@@ -1352,35 +1352,73 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
13521352template <class _Tp , class _Allocator >
13531353template <class _InputIterator , class _Sentinel >
13541354_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
1355- vector<_Tp, _Allocator>::__insert_with_sentinel (const_iterator __position, _InputIterator __first, _Sentinel __last) {
1355+ vector<_Tp, _Allocator>::__insert_with_sentinel (const_iterator __position,
1356+ _InputIterator __first, _Sentinel __last) {
13561357 difference_type __off = __position - begin ();
13571358 pointer __p = this ->__begin_ + __off;
13581359 allocator_type& __a = this ->__alloc ();
13591360 pointer __old_last = this ->__end_ ;
1360- for (; this ->__end_ != this ->__end_cap () && __first != __last; ++__first) {
1361- __construct_one_at_end (*__first);
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_
13621363 }
1363- if (__first == __last)
1364- std::rotate (__p, __old_last, this ->__end_ );
1365- else {
1366- auto __guard =
1367- std::__make_exception_guard (_AllocatorDestroyRangeReverse<allocator_type, pointer>(__a, __old_last, __end_));
1368- __split_buffer<value_type, allocator_type&> __v (__a);
1369- __v.__construct_at_end_with_sentinel (std::move (__first), std::move (__last));
1370- __split_buffer<value_type, allocator_type&> __merged (__recommend (size () + __v.size ()), __off, __a);
1371- std::__uninitialized_allocator_relocate (
1372- __a, std::__to_address (__old_last), std::__to_address (__end_), std::__to_address (__merged.__end_ ));
1373- __merged.__end_ += __end_ - __old_last;
1374- __end_ = __old_last;
1375- __guard.__complete ();
1376- std::__uninitialized_allocator_relocate (
1377- __a, std::__to_address (__v.__begin_ ), std::__to_address (__v.__end_ ), std::__to_address (__merged.__end_ ));
1378- __merged.__end_ += __v.size ();
1379- __p = __swap_out_circular_buffer (__merged, __p);
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
13801382 }
1381- return __make_iter (__p);
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;
13821387}
13831388
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+
13841422template <class _Tp , class _Allocator >
13851423template <class _ForwardIterator ,
13861424 __enable_if_t <__has_forward_iterator_category<_ForwardIterator>::value &&
0 commit comments