@@ -1358,67 +1358,32 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position,
13581358 pointer __p = this ->__begin_ + __off;
13591359 allocator_type& __a = this ->__alloc ();
13601360 pointer __old_last = this ->__end_ ;
1361- for (; this ->__end_ != this ->__end_cap () && __first != __last; ++__first) {
1362- __construct_one_at_end (*__first); // 先插入一部分数据到现有 vector 的尾部,直至尾部剩余内存耗尽为止。__construct_one_at_end() 只会改变 this->__end_ 指针,但不会改变 this->__begin_
1361+ for (; this ->__end_ != this ->__end_cap () && __first != __last; ++__first) {
1362+ __construct_one_at_end (*__first);
13631363 }
1364- __split_buffer<value_type, allocator_type&> __v (__a);
1365- if (__first != __last) {
1366- #if _LIBCPP_HAS_EXCEPTIONS
1367- try {
1368- #endif // _LIBCPP_HAS_EXCEPTIONS
1369- __v.__construct_at_end_with_sentinel (std::move (__first),
1370- std::move (__last));
1371- difference_type __old_size = __old_last - this ->__begin_ ;
1372- difference_type __old_p = __p - this ->__begin_ ; // 截止到此处,this->__begin_, __p 均未改变,因此,old_p 正是前面的 __off,故这一步重新计算 __old_p 完全是多余的!下面在计算 __p 时直接用 __off 代替 __old_p 即可。
1373- reserve (__recommend (size () + __v.size ())); // 此处 reserve() 会导致一次扩容,故会改变 this->__begin_, this->__end_, __p,因此,需要下面重新计算它们
1374- __p = this ->__begin_ + __old_p; // 此处需要重新计算 __p 和 __old_last 是因为 reserve() 会改变 this->__begin_, this->__end_
1375- __old_last = this ->__begin_ + __old_size;
1376- #if _LIBCPP_HAS_EXCEPTIONS
1377- } catch (...) {
1378- erase (__make_iter (__old_last), end ());
1379- throw ;
1380- }
1381- #endif // _LIBCPP_HAS_EXCEPTIONS
1364+
1365+ if (__first == __last)
1366+ (void )std::rotate (__p, __old_last, this ->__end_ );
1367+ else {
1368+ __split_buffer<value_type, allocator_type&> __v (__a);
1369+ auto __guard =
1370+ std::__make_exception_guard (_AllocatorDestroyRangeReverse<allocator_type, pointer>(__a, __old_last, __end_));
1371+ __v.__construct_at_end_with_sentinel (std::move (__first), std::move (__last));
1372+ __split_buffer<value_type, allocator_type&> __merged (__recommend (size () + __v.size ()), __off, __a);
1373+ std::__uninitialized_allocator_relocate (
1374+ __a, std::__to_address (__old_last), std::__to_address (__end_), std::__to_address (__merged.__end_ ));
1375+ __merged.__end_ += __end_ - __old_last;
1376+ __end_ = __old_last;
1377+ __guard.__complete ();
1378+ std::__uninitialized_allocator_relocate (
1379+ __a, std::__to_address (__v.__begin_ ), std::__to_address (__v.__end_ ), std::__to_address (__merged.__end_ ));
1380+ __merged.__end_ += __v.size ();
1381+ __v.__begin_ = __v.__end_ ;
1382+ __p = __swap_out_circular_buffer (__merged, __p);
13821383 }
1383- __p = std::rotate (__p, __old_last, this ->__end_ ); // 此实现有改进空间!既然都要扩容了,就应该在扩容的同时一次性将 [__old_p, __old_last] 和 [__old_last, this->__end_)放到正确的位置,从而避免了此处不必要的 rotate! 也就是说只有前面那种无需扩容的情形才需要最终的 rotate()
1384- insert (__make_iter (__p), std::make_move_iterator (__v.begin ()),
1385- std::make_move_iterator (__v.end ()));
1386- return begin () + __off;
1384+ return __make_iter (__p);
13871385}
13881386
1389-
1390- // template <class _Tp, class _Allocator>
1391- // template <class _InputIterator, class _Sentinel>
1392- // _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
1393- // vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) {
1394- // difference_type __off = __position - begin();
1395- // pointer __p = this->__begin_ + __off;
1396- // allocator_type& __a = this->__alloc();
1397- // pointer __old_last = this->__end_;
1398- // for (; this->__end_ != this->__end_cap() && __first != __last; ++__first) {
1399- // __construct_one_at_end(*__first);
1400- // }
1401- // if (__first == __last)
1402- // std::rotate(__p, __old_last, this->__end_);
1403- // else {
1404- // auto __guard =
1405- // std::__make_exception_guard(_AllocatorDestroyRangeReverse<allocator_type, pointer>(__a, __old_last, __end_));
1406- // __split_buffer<value_type, allocator_type&> __v(__a);
1407- // __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
1408- // __split_buffer<value_type, allocator_type&> __merged(__recommend(size() + __v.size()), __off, __a);
1409- // std::__uninitialized_allocator_relocate(
1410- // __a, std::__to_address(__old_last), std::__to_address(__end_), std::__to_address(__merged.__end_));
1411- // __merged.__end_ += __end_ - __old_last;
1412- // __end_ = __old_last;
1413- // __guard.__complete();
1414- // std::__uninitialized_allocator_relocate(
1415- // __a, std::__to_address(__v.__begin_), std::__to_address(__v.__end_), std::__to_address(__merged.__end_));
1416- // __merged.__end_ += __v.size();
1417- // __p = __swap_out_circular_buffer(__merged, __p);
1418- // }
1419- // return __make_iter(__p);
1420- // }
1421-
14221387template <class _Tp , class _Allocator >
14231388template <class _ForwardIterator ,
14241389 __enable_if_t <__has_forward_iterator_category<_ForwardIterator>::value &&
0 commit comments