@@ -461,6 +461,17 @@ class _LIBCPP_TEMPLATE_VIS vector {
461461 emplace_back (_Args&&... __args);
462462#endif
463463
464+ template <class ... _Args>
465+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __emplace_back_assume_capacity (_Args&&... __args) {
466+ _LIBCPP_ASSERT_INTERNAL (
467+ size () < capacity (), " We assume that we have enough space to insert an element at the end of the vector" );
468+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (this ->__end_ ), std::forward<_Args>(__args)...);
469+ ++this ->__end_ ;
470+ #if _LIBCPP_HAS_ASAN
471+ __annotate_increase (1 );
472+ #endif
473+ }
474+
464475#if _LIBCPP_STD_VER >= 23
465476 template <_ContainerCompatibleRange<_Tp> _Range>
466477 _LIBCPP_HIDE_FROM_ABI constexpr void append_range (_Range&& __range) {
@@ -758,13 +769,6 @@ class _LIBCPP_TEMPLATE_VIS vector {
758769 _ConstructTransaction& operator =(_ConstructTransaction const &) = delete ;
759770 };
760771
761- template <class ... _Args>
762- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_one_at_end (_Args&&... __args) {
763- _ConstructTransaction __tx (*this , 1 );
764- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__tx.__pos_ ), std::forward<_Args>(__args)...);
765- ++__tx.__pos_ ;
766- }
767-
768772 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end (pointer __new_last) _NOEXCEPT {
769773 pointer __soon_to_be_end = this ->__end_ ;
770774 while (__new_last != __soon_to_be_end)
@@ -1152,7 +1156,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline
11521156 vector<_Tp, _Allocator>::emplace_back (_Args&&... __args) {
11531157 pointer __end = this ->__end_ ;
11541158 if (__end < this ->__cap_ ) {
1155- __construct_one_at_end (std::forward<_Args>(__args)...);
1159+ __emplace_back_assume_capacity (std::forward<_Args>(__args)...);
11561160 ++__end;
11571161 } else {
11581162 __end = __emplace_back_slow_path (std::forward<_Args>(__args)...);
@@ -1206,7 +1210,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
12061210 pointer __p = this ->__begin_ + (__position - begin ());
12071211 if (this ->__end_ < this ->__cap_ ) {
12081212 if (__p == this ->__end_ ) {
1209- __construct_one_at_end (__x);
1213+ __emplace_back_assume_capacity (__x);
12101214 } else {
12111215 __move_range (__p, this ->__end_ , __p + 1 );
12121216 const_pointer __xr = pointer_traits<const_pointer>::pointer_to (__x);
@@ -1228,7 +1232,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
12281232 pointer __p = this ->__begin_ + (__position - begin ());
12291233 if (this ->__end_ < this ->__cap_ ) {
12301234 if (__p == this ->__end_ ) {
1231- __construct_one_at_end (std::move (__x));
1235+ __emplace_back_assume_capacity (std::move (__x));
12321236 } else {
12331237 __move_range (__p, this ->__end_ , __p + 1 );
12341238 *__p = std::move (__x);
@@ -1248,7 +1252,7 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
12481252 pointer __p = this ->__begin_ + (__position - begin ());
12491253 if (this ->__end_ < this ->__cap_ ) {
12501254 if (__p == this ->__end_ ) {
1251- __construct_one_at_end (std::forward<_Args>(__args)...);
1255+ __emplace_back_assume_capacity (std::forward<_Args>(__args)...);
12521256 } else {
12531257 __temp_value<value_type, _Allocator> __tmp (this ->__alloc_ , std::forward<_Args>(__args)...);
12541258 __move_range (__p, this ->__end_ , __p + 1 );
@@ -1300,7 +1304,7 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu
13001304 pointer __p = this ->__begin_ + __off;
13011305 pointer __old_last = this ->__end_ ;
13021306 for (; this ->__end_ != this ->__cap_ && __first != __last; ++__first)
1303- __construct_one_at_end (*__first);
1307+ __emplace_back_assume_capacity (*__first);
13041308
13051309 if (__first == __last)
13061310 (void )std::rotate (__p, __old_last, this ->__end_ );
0 commit comments