Skip to content

Commit

Permalink
Cleanup construction of vector with known size
Browse files Browse the repository at this point in the history
  • Loading branch information
miscco committed Mar 23, 2021
1 parent f387efe commit 7bb4110
Showing 1 changed file with 51 additions and 84 deletions.
135 changes: 51 additions & 84 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -481,114 +481,56 @@ public:
_Mypair._Myval2._Alloc_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Getal()));
}

private:
template <class _Ty2>
_CONSTEXPR20_CONTAINER void _Construct_n_copies_of_ty(_CRT_GUARDOVERFLOW const size_type _Count, const _Ty2& _Val) {
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
auto& _Al = _Getal();
auto& _My_data = _Mypair._Myval2;
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data);
if (_Count != 0) {
_Buy_nonzero(_Count);
_Tidy_guard<vector> _Guard{this};
if constexpr (is_same_v<_Ty2, _Ty>) {
_My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val, _Al);
} else {
_My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Al);
}
_Guard._Target = nullptr;
}

_Proxy._Release();
}

public:
_CONSTEXPR20_CONTAINER explicit vector(_CRT_GUARDOVERFLOW const size_type _Count, const _Alloc& _Al = _Alloc())
: _Mypair(_One_then_variadic_args_t{}, _Al) {
_Construct_n_copies_of_ty(_Count, _Value_init_tag{});
_Construct_n(_Count);
}

_CONSTEXPR20_CONTAINER vector(
_CRT_GUARDOVERFLOW const size_type _Count, const _Ty& _Val, const _Alloc& _Al = _Alloc())
: _Mypair(_One_then_variadic_args_t{}, _Al) {
_Construct_n_copies_of_ty(_Count, _Val);
}

private:
template <class _Iter>
_CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, input_iterator_tag) {
_Tidy_guard<vector> _Guard{this};
for (; _First != _Last; ++_First) {
emplace_back(*_First); // performance note: emplace_back()'s strong guarantee is unnecessary here
}

_Guard._Target = nullptr;
_Construct_n(_Count, _Val);
}

template <class _Iter>
_CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag) {
const auto _Count = _Convert_size<size_type>(static_cast<size_t>(_STD distance(_First, _Last)));
if (_Count != 0) {
_Buy_nonzero(_Count);
_Tidy_guard<vector> _Guard{this};
auto& _My_data = _Mypair._Myval2;
_My_data._Mylast = _Uninitialized_copy(_First, _Last, _My_data._Myfirst, _Getal());
_Guard._Target = nullptr;
}
}

public:
template <class _Iter, enable_if_t<_Is_iterator_v<_Iter>, int> = 0>
_CONSTEXPR20_CONTAINER vector(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc())
: _Mypair(_One_then_variadic_args_t{}, _Al) {
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2);
_Adl_verify_range(_First, _Last);
_Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{});
_Proxy._Release();
auto _UFirst = _Get_unwrapped(_First);
auto _ULast = _Get_unwrapped(_Last);
if constexpr (is_same_v<_Iter_cat_t<_Iter>, input_iterator_tag>) {
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2);
_Tidy_guard<vector> _Guard{this};

for (; _UFirst != _ULast; ++_UFirst) {
emplace_back(*_UFirst); // performance note: emplace_back()'s strong guarantee is unnecessary here
}

_Guard._Target = nullptr;
_Proxy._Release();
} else {
const auto _Count = _Convert_size<size_type>(static_cast<size_t>(_STD distance(_UFirst, _ULast)));
_Construct_n(_Count, _STD move(_UFirst), _STD move(_ULast));
}
}

_CONSTEXPR20_CONTAINER vector(initializer_list<_Ty> _Ilist, const _Alloc& _Al = _Alloc())
: _Mypair(_One_then_variadic_args_t{}, _Al) {
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2);
_Range_construct_or_tidy(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{});
_Proxy._Release();
_Construct_n(_Ilist.size(), _Ilist.begin(), _Ilist.end());
}

_CONSTEXPR20_CONTAINER vector(const vector& _Right)
: _Mypair(_One_then_variadic_args_t{}, _Alty_traits::select_on_container_copy_construction(_Right._Getal())) {
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
auto& _My_data = _Mypair._Myval2;
const auto& _Right_data = _Right._Mypair._Myval2;
const pointer _Rightfirst = _Right_data._Myfirst;
const pointer _Rightlast = _Right_data._Mylast;
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data);
if (_Rightfirst != _Rightlast) {
_Buy_raw(static_cast<size_type>(_Rightlast - _Rightfirst));
_Tidy_guard<vector> _Guard{this};
_My_data._Mylast = _Uninitialized_copy(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal());
_Guard._Target = nullptr;
}

_Proxy._Release();
const auto& _Right_data = _Right._Mypair._Myval2;
const auto _Count = static_cast<size_type>(_Right_data._Mylast - _Right_data._Myfirst);
_Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast);
}

_CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
auto& _My_data = _Mypair._Myval2;
const auto& _Right_data = _Right._Mypair._Myval2;
const pointer _Rightfirst = _Right_data._Myfirst;
const pointer _Rightlast = _Right_data._Mylast;
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data);
if (_Rightfirst != _Rightlast) {
_Buy_raw(static_cast<size_type>(_Rightlast - _Rightfirst));
_Tidy_guard<vector> _Guard{this};
_My_data._Mylast = _Uninitialized_copy(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal());
_Guard._Target = nullptr;
}

_Proxy._Release();
const auto& _Right_data = _Right._Mypair._Myval2;
const auto _Count = static_cast<size_type>(_Right_data._Mylast - _Right_data._Myfirst);
_Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast);
}

private:
Expand Down Expand Up @@ -1771,6 +1713,31 @@ private:
}
}

template <class... _Valty>
_CONSTEXPR20_CONTAINER void _Construct_n(_CRT_GUARDOVERFLOW const size_type _Count, _Valty&&... _Val) {
auto& _Al = _Getal();
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al);
auto& _My_data = _Mypair._Myval2;
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data);
if (_Count != 0) {
_Buy_nonzero(_Count);
_Tidy_guard<vector> _Guard{this};
if constexpr (sizeof...(_Val) == 0) {
_My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Al);
} else if constexpr (sizeof...(_Val) == 1) {
static_assert(is_same_v<_Valty..., const _Ty&>, "Wrong type passed to _Construct_n");
_My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val..., _Al);
} else if constexpr (sizeof...(_Val) == 2) {
_My_data._Mylast = _Uninitialized_copy(_STD forward<_Valty>(_Val)..., _My_data._Myfirst, _Al);
} else {
static_assert(_Always_false<_Ty>, "Should be unreachable");
}
_Guard._Target = nullptr;
}

_Proxy._Release();
}

[[noreturn]] static void _Xlength() {
_Xlength_error("vector too long");
}
Expand Down

0 comments on commit 7bb4110

Please sign in to comment.