Changeset 56521a2 in mainline


Ignore:
Timestamp:
2018-07-05T21:41:17Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b9f897c
Parents:
f041811
git-author:
Jaroslav Jindrak <dzejrou@…> (2017-10-25 15:09:51)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:17)
Message:

cpp: fixed vector::insert to work when no reallocation is needed and made the code much more elegant/readable in insert and emplace

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/impl/vector.hpp

    rf041811 r56521a2  
    392392            iterator emplace(const_iterator position, Args&&... args)
    393393            {
    394                 auto idx = shift_right_(position, 1);
    395                 allocator_.construct(data_ + idx, std::forward<Args>(args)...);
    396 
    397                 return begin() + idx;
     394                auto pos = const_cast<iterator>(position);
     395
     396                shift_(pos, 1);
     397                allocator_.construct(pos, std::forward<Args>(args)...);
     398
     399                return pos;
    398400            }
    399401
    400402            iterator insert(const_iterator position, const value_type& x)
    401403            {
    402                 /**
    403                  * Note: The reason that all insert functions are done in this weird
    404                  *       way with an auxiliary vector instead of just shifting
    405                  *       the elements is that we need to provide strong exception
    406                  *       guarantee - in the case of exception our vector needs to
    407                  *       stay in its pre-instert state and this swap method guarantees
    408                  *       that.
    409                  * TODO: Avoid reallocation if it still fits!
    410                  */
    411                 size_type idx = static_cast<size_type>(position - cbegin());
    412 
    413                 vector tmp{};
    414                 tmp.resize_without_copy_(max(size_ + 1, capacity_));
    415 
    416                 // Copy before insertion index.
    417                 tmp.copy_(0, begin(), begin() + idx);
    418 
    419                 // Insertion.
    420                 tmp.data_[idx] = x;
    421 
    422                 // Copy after insertion index.
    423                 tmp.copy_(idx + 1, begin() + idx + 1, end());
    424                 tmp.size_ = size_ + 1;
    425                 swap(tmp);
    426 
    427                 return begin() + idx;
     404                auto pos = const_cast<iterator>(position);
     405
     406                shift_(pos, 1);
     407                *pos = x;
     408
     409                ++size_;
     410                return pos;
    428411            }
    429412
    430413            iterator insert(const_iterator position, value_type&& x)
    431414            {
    432                 size_type idx = static_cast<size_type>(position - cbegin());
    433 
    434                 vector tmp{};
    435                 tmp.resize_without_copy_(max(size_ + 1, capacity_));
    436 
    437                 // Copy before insertion index.
    438                 tmp.copy_(0, begin(), begin() + idx);
    439 
    440                 // Insertion.
    441                 tmp.data_[idx] = std::forward<value_type>(x);
    442 
    443                 // Copy after insertion index.
    444                 tmp.copy_(idx + 1, begin() + idx + 1, end());
    445                 tmp.size_ = size_ + 1;
    446                 swap(tmp);
    447 
    448                 return begin() + idx;
     415                auto pos = const_cast<iterator>(position);
     416
     417                shift_(pos, 1);
     418                *pos = forward<value_type>(x);
     419
     420                ++size_;
     421                return pos;
    449422            }
    450423
    451424            iterator insert(const_iterator position, size_type count, const value_type& x)
    452425            {
    453                 size_type idx = static_cast<size_type>(position - cbegin());
    454 
    455                 vector tmp{};
    456                 tmp.resize_without_copy_(max(size_ + 1, capacity_));
    457 
    458                 // Copy before insertion index.
    459                 tmp.copy_(0, begin(), begin() + idx);
    460 
    461                 // Insertion.
    462                 auto tmp_idx = idx;
    463                 for (size_type i = 0; i < count; ++i, ++tmp_idx)
    464                     tmp.data_[tmp_idx] = x;
    465 
    466                 // Copy after insertion index.
    467                 tmp.copy_(tmp_idx, begin() + idx, end());
    468                 tmp.size_ = size_ + count;
    469                 swap(tmp);
    470 
    471                 return begin() + idx;
     426                auto pos = const_cast<iterator>(position);
     427
     428                shift_(pos, count);
     429                auto copy_target = pos;
     430                for (size_type i = 0; i < count; ++i)
     431                    *copy_target++ = x;
     432
     433                size_ += count;
     434                return pos;
    472435            }
    473436
     
    476439                            InputIterator last)
    477440            {
    478                 size_type idx = static_cast<size_type>(position - cbegin());
    479                 size_type count = static_cast<size_type>(last - first);
    480 
    481                 return insert_(idx, count, first, last);
     441                auto pos = const_cast<iterator>(position);
     442                auto count = static_cast<size_type>(last - first);
     443
     444                shift_(pos, count);
     445                std::copy(first, last, pos);
     446
     447                size_ += count;
     448                return pos;
    482449            }
    483450
    484451            iterator insert(const_iterator position, initializer_list<T> init)
    485452            {
    486                 size_type idx = static_cast<size_type>(position - cbegin());
    487                 size_type count = init.size();
    488 
    489                 return insert_(idx, count, init.begin(), init.end());
     453                auto pos = const_cast<iterator>(position);
     454
     455                shift_(pos, init.size());
     456                std::copy(init.begin(), init.end(), pos);
     457
     458                size_ += init.size();
     459                return pos;
    490460            }
    491461
     
    580550            }
    581551
    582             template<class Iterator>
    583             void copy_(size_type idx, Iterator first, Iterator last)
    584             {
    585                 for (size_type i = idx; first != last; ++i, ++first)
    586                     data_[i] = *first;
    587             }
    588 
    589             template<class Iterator>
    590             iterator insert_(size_type idx, size_type count, Iterator first, Iterator last)
    591             {
    592                 vector tmp{};
    593                 tmp.resize_without_copy_(max(size_ + count, capacity_));
    594 
    595                 // Copy before insertion index.
    596                 tmp.copy_(0, begin(), begin() + idx);
    597 
    598                 // Insertion.
    599                 tmp.copy_(idx, first, last);
    600 
    601                 // Copy after insertion index.
    602                 tmp.copy_(idx + count, begin() + idx, end());
    603                 tmp.size_ = size_ + count;
    604                 swap(tmp);
    605 
    606                 return begin() + idx;
     552            void shift_(iterator position, size_type count)
     553            {
     554                if (size_ + count < capacity_)
     555                    std::copy_backwards(pos, end(), end() + count);
     556                else
     557                {
     558                    auto start_idx = static_cast<size_type>(position - begin());
     559                    auto end_idx = start_idx + count;
     560                    auto new_size = size_ + count;
     561
     562                    // Auxiliary vector for easier swap.
     563                    vector tmp{};
     564                    tmp.resize_without_copy_(max(new_size, capacity_));
     565                    tmp.size_ = new_size;
     566
     567                    // Copy before insertion index.
     568                    std::copy(tmp.begin(), tmp.begin() + start_idx, begin());
     569
     570                    // Copy after insertion index.
     571                    std::copy(tmp.begin() + end_idx, tmp.end(), begin() + start_idx);
     572
     573                    swap(tmp);
     574                }
    607575            }
    608576    };
Note: See TracChangeset for help on using the changeset viewer.