Skip to content

Commit bcb9179

Browse files
committed
Revert back
1 parent 52de203 commit bcb9179

File tree

1 file changed

+59
-21
lines changed

1 file changed

+59
-21
lines changed

libcxx/include/__vector/vector.h

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,35 +1352,73 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
13521352
template <class _Tp, class _Allocator>
13531353
template <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+
13841422
template <class _Tp, class _Allocator>
13851423
template <class _ForwardIterator,
13861424
__enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value &&

0 commit comments

Comments
 (0)