From 146f5802cc189510a4b735d133dac7c0f5f6ac0c Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 31 Mar 2021 19:50:07 +0200 Subject: [PATCH 1/9] Use iterator concept in vector's range constructor --- stl/inc/vector | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stl/inc/vector b/stl/inc/vector index 9a943420d4..bf602adf37 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -522,7 +522,11 @@ private: template _CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag) { +#if __cpp_lib_concepts + const auto _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); +#else const auto _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); +#endif if (_Count != 0) { _Buy_nonzero(_Count); _Tidy_guard _Guard{this}; @@ -539,7 +543,11 @@ public: auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); _Adl_verify_range(_First, _Last); +#if __cpp_lib_concepts + _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_concept<_Iter>{}); +#else _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); +#endif _Proxy._Release(); } From 3e3930576a27a23516b137850a79b54fff5910de Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:19:54 +0200 Subject: [PATCH 2/9] Should be ifdef + comments --- stl/inc/vector | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index bf602adf37..9ed2be8a32 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -522,11 +522,11 @@ private: template _CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag) { -#if __cpp_lib_concepts +#ifdef __cpp_lib_concepts const auto _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); -#else +#else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv const auto _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); -#endif +#endif // ^^^ !__cpp_lib_concepts ^^^ if (_Count != 0) { _Buy_nonzero(_Count); _Tidy_guard _Guard{this}; @@ -543,11 +543,11 @@ public: auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); _Adl_verify_range(_First, _Last); -#if __cpp_lib_concepts +#ifdef __cpp_lib_concepts _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_concept<_Iter>{}); -#else +#else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); -#endif +#endif // ^^^ !__cpp_lib_concepts ^^^ _Proxy._Release(); } From f8b273d339e4303254f31c3abf4f9b207ece9659 Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:49:45 +0200 Subject: [PATCH 3/9] Use the stronger of iterator_concept and iterator_category --- stl/inc/vector | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/stl/inc/vector b/stl/inc/vector index 9ed2be8a32..2f5f8731dd 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -544,7 +544,11 @@ public: _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); _Adl_verify_range(_First, _Last); #ifdef __cpp_lib_concepts - _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_concept<_Iter>{}); + if constexpr (derived_from<_Iter_concept<_Iter>, _Iter_cat_t<_Iter>>) { + _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_concept<_Iter>{}); + } else { + _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); + } #else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); #endif // ^^^ !__cpp_lib_concepts ^^^ @@ -1145,7 +1149,11 @@ private: template _CONSTEXPR20_CONTAINER void _Assign_range(_Iter _First, _Iter _Last, forward_iterator_tag) { // assign forward range [_First, _Last) +#ifdef __cpp_lib_concepts + const auto _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); +#else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv const auto _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); +#endif // ^^^ !__cpp_lib_concepts ^^^ auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1195,6 +1203,15 @@ public: _CONSTEXPR20_CONTAINER void assign(_Iter _First, _Iter _Last) { _Adl_verify_range(_First, _Last); _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); +#ifdef __cpp_lib_concepts + if constexpr (derived_from<_Iter_concept<_Iter>, _Iter_cat_t<_Iter>>) { + _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_concept<_Iter>{}); + } else { + _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); + } +#else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv + _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); +#endif // ^^^ !__cpp_lib_concepts ^^^ } _CONSTEXPR20_CONTAINER void assign(initializer_list<_Ty> _Ilist) { From 53a0a35d0b4789a96af0ed393f9a7b46e69856fa Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:51:58 +0200 Subject: [PATCH 4/9] clang-format --- stl/inc/vector | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 2f5f8731dd..f3455e7d8b 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -1154,10 +1154,10 @@ private: #else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv const auto _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); #endif // ^^^ !__cpp_lib_concepts ^^^ - auto& _My_data = _Mypair._Myval2; - pointer& _Myfirst = _My_data._Myfirst; - pointer& _Mylast = _My_data._Mylast; - pointer& _Myend = _My_data._Myend; + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + pointer& _Myend = _My_data._Myend; _My_data._Orphan_all(); From 41213bd1ac41fad77ec0f2a54bb75ababbaffdae Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 31 Mar 2021 21:09:39 +0200 Subject: [PATCH 5/9] Fix tests --- stl/inc/vector | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index f3455e7d8b..3f328a62f4 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -523,7 +523,12 @@ private: template _CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag) { #ifdef __cpp_lib_concepts - const auto _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + size_type _Count; + if constexpr (forward_iterator<_Iter>) { + _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + } else { + _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); + } #else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv const auto _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); #endif // ^^^ !__cpp_lib_concepts ^^^ @@ -1150,7 +1155,12 @@ private: _CONSTEXPR20_CONTAINER void _Assign_range(_Iter _First, _Iter _Last, forward_iterator_tag) { // assign forward range [_First, _Last) #ifdef __cpp_lib_concepts - const auto _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + size_type _Newsize; + if constexpr (forward_iterator<_Iter>) { + _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + } else { + _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); + } #else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv const auto _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); #endif // ^^^ !__cpp_lib_concepts ^^^ From 041055ceb55420469dd01a309420e6da6a7f0a47 Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 31 Mar 2021 21:50:48 +0200 Subject: [PATCH 6/9] Actually the test was wrong --- stl/inc/vector | 14 ++------------ .../test.compile.pass.cpp | 12 ++++++++++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 3f328a62f4..f3455e7d8b 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -523,12 +523,7 @@ private: template _CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag) { #ifdef __cpp_lib_concepts - size_type _Count; - if constexpr (forward_iterator<_Iter>) { - _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); - } else { - _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); - } + const auto _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); #else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv const auto _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); #endif // ^^^ !__cpp_lib_concepts ^^^ @@ -1155,12 +1150,7 @@ private: _CONSTEXPR20_CONTAINER void _Assign_range(_Iter _First, _Iter _Last, forward_iterator_tag) { // assign forward range [_First, _Last) #ifdef __cpp_lib_concepts - size_type _Newsize; - if constexpr (forward_iterator<_Iter>) { - _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); - } else { - _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); - } + const auto _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); #else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv const auto _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); #endif // ^^^ !__cpp_lib_concepts ^^^ diff --git a/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp b/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp index 2a6a9b4b90..3835d8b028 100644 --- a/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp @@ -82,14 +82,22 @@ class fancy_pointer { return *this; } - void operator++(int) = delete; // avoid postincrement + fancy_pointer operator++(int) { + fancy_pointer result = *this; + ++rep; + return result; + } fancy_pointer& operator--() { --rep; return *this; } - void operator--(int) = delete; // avoid postdecrement + fancy_pointer operator--(int) { + fancy_pointer result = *this; + --rep; + return result; + } #ifdef _WIN64 fancy_pointer& operator+=(int rhs) { From bd146124e31a8f121d1eb6610ac07c24922c56fb Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 31 Mar 2021 21:57:53 +0200 Subject: [PATCH 7/9] Remove double call to _Assign_range --- stl/inc/vector | 1 - 1 file changed, 1 deletion(-) diff --git a/stl/inc/vector b/stl/inc/vector index f3455e7d8b..c3b5322795 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -1202,7 +1202,6 @@ public: template , int> = 0> _CONSTEXPR20_CONTAINER void assign(_Iter _First, _Iter _Last) { _Adl_verify_range(_First, _Last); - _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); #ifdef __cpp_lib_concepts if constexpr (derived_from<_Iter_concept<_Iter>, _Iter_cat_t<_Iter>>) { _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_concept<_Iter>{}); From 43f8d987a28d7277ff1495117a86d54c4f07786a Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Thu, 1 Jul 2021 19:31:19 +0200 Subject: [PATCH 8/9] refactoring and insert --- stl/inc/vector | 58 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 61fb11261d..3de2ada0c0 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -813,7 +813,7 @@ public: private: template - _CONSTEXPR20_CONTAINER void _Insert_range(const_iterator _Where, _Iter _First, _Iter _Last, input_iterator_tag) { + _CONSTEXPR20_CONTAINER void _Insert_input_range(const_iterator _Where, _Iter _First, _Iter _Last) { // insert input range [_First, _Last) at _Where if (_First == _Last) { return; // nothing to do, avoid invalidating iterators @@ -839,10 +839,18 @@ private: } template - _CONSTEXPR20_CONTAINER void _Insert_range(const_iterator _Where, _Iter _First, _Iter _Last, forward_iterator_tag) { + _CONSTEXPR20_CONTAINER void _Insert_forward_range(const_iterator _Where, _Iter _First, _Iter _Last) { // insert forward range [_First, _Last) at _Where const pointer _Whereptr = _Where._Ptr; - const auto _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); + size_type _Count; +#ifdef __cpp_lib_concepts + if constexpr (forward_iterator<_Iter>) { + _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + } else +#endif // __cpp_lib_concepts + { + _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); + } auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; @@ -965,7 +973,16 @@ public: _Adl_verify_range(_First, _Last); const auto _Whereoff = static_cast(_Whereptr - _Oldfirst); - _Insert_range(_Where, _Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); +#ifdef __cpp_lib_concepts + constexpr bool _Is_fwd = _Is_fwd_iter_v<_Iter> || forward_iterator<_Iter>; +#else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv + constexpr bool _Is_fwd = _Is_fwd_iter_v<_Iter>; +#endif // ^^^ !__cpp_lib_concepts ^^^ + if constexpr (_Is_fwd) { + _Insert_forward_range(_Where, _Get_unwrapped(_First), _Get_unwrapped(_Last)); + } else { + _Insert_input_range(_Where, _Get_unwrapped(_First), _Get_unwrapped(_Last)); + } return _Make_iterator_offset(_Whereoff); } @@ -1003,7 +1020,7 @@ public: private: template - _CONSTEXPR20_CONTAINER void _Assign_range(_Iter _First, _Iter _Last, input_iterator_tag) { + _CONSTEXPR20_CONTAINER void _Assign_input_range(_Iter _First, _Iter _Last) { // assign input range [_First, _Last) auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; @@ -1033,13 +1050,17 @@ private: } template - _CONSTEXPR20_CONTAINER void _Assign_range(_Iter _First, _Iter _Last, forward_iterator_tag) { + _CONSTEXPR20_CONTAINER void _Assign_forward_range(_Iter _First, _Iter _Last) { // assign forward range [_First, _Last) + size_type _Newsize; #ifdef __cpp_lib_concepts - const auto _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); -#else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv - const auto _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); -#endif // ^^^ !__cpp_lib_concepts ^^^ + if constexpr (forward_iterator<_Iter>) { + _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + } else +#endif // __cpp_lib_concepts + { + _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); + } auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; @@ -1090,18 +1111,19 @@ public: _CONSTEXPR20_CONTAINER void assign(_Iter _First, _Iter _Last) { _Adl_verify_range(_First, _Last); #ifdef __cpp_lib_concepts - if constexpr (derived_from<_Iter_concept<_Iter>, _Iter_cat_t<_Iter>>) { - _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_concept<_Iter>{}); - } else { - _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); - } + constexpr bool _Is_fwd = _Is_fwd_iter_v<_Iter> || forward_iterator<_Iter>; #else // ^^^ __cpp_lib_concepts ^^^ / vvv !__cpp_lib_concepts vvv - _Assign_range(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); + constexpr bool _Is_fwd = _Is_fwd_iter_v<_Iter>; #endif // ^^^ !__cpp_lib_concepts ^^^ + if constexpr (_Is_fwd) { + _Assign_forward_range(_Get_unwrapped(_First), _Get_unwrapped(_Last)); + } else { + _Assign_input_range(_Get_unwrapped(_First), _Get_unwrapped(_Last)); + } } _CONSTEXPR20_CONTAINER void assign(initializer_list<_Ty> _Ilist) { - _Assign_range(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{}); + _Assign_forward_range(_Ilist.begin(), _Ilist.end()); } private: @@ -1131,7 +1153,7 @@ public: } _CONSTEXPR20_CONTAINER vector& operator=(initializer_list<_Ty> _Ilist) { - _Assign_range(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{}); + _Assign_forward_range(_Ilist.begin(), _Ilist.end()); return *this; } From 798f9ce1bb91fa37c24410df397870c419d519d5 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 9 Jun 2022 18:02:11 -0700 Subject: [PATCH 9/9] Code review feedback. --- stl/inc/vector | 6 ++--- stl/inc/xmemory | 14 ++++++---- .../tests/P0896R4_views_transform/test.cpp | 27 +++++++++++++++++++ .../test.compile.pass.cpp | 8 +++--- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 5a76d721c3..421794447c 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -701,7 +701,7 @@ public: _Construct_n(_Count, _STD move(_UFirst), _STD move(_ULast)); #ifdef __cpp_lib_concepts } else if constexpr (forward_iterator<_Iter>) { - const auto _Count = _Convert_size(static_cast(_RANGES distance(_UFirst, _ULast))); + const auto _Count = _Convert_size(_To_unsigned_like(_RANGES distance(_UFirst, _ULast))); _Construct_n(_Count, _STD move(_UFirst), _STD move(_ULast)); #endif // __cpp_lib_concepts } else { @@ -1078,7 +1078,7 @@ private: size_type _Count; #ifdef __cpp_lib_concepts if constexpr (forward_iterator<_Iter>) { - _Count = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + _Count = _Convert_size(_To_unsigned_like(_RANGES distance(_First, _Last))); } else #endif // __cpp_lib_concepts { @@ -1308,7 +1308,7 @@ private: size_type _Newsize; #ifdef __cpp_lib_concepts if constexpr (forward_iterator<_Iter>) { - _Newsize = _Convert_size(static_cast(_RANGES distance(_First, _Last))); + _Newsize = _Convert_size(_To_unsigned_like(_RANGES distance(_First, _Last))); } else #endif // __cpp_lib_concepts { diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 013fb5b297..9efff079ad 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -961,12 +961,16 @@ _CONSTEXPR20 void _Destroy_range(_NoThrowFwdIt _First, const _NoThrowSentinel _L } } -template -_NODISCARD constexpr _Size_type _Convert_size(const size_t _Len) noexcept(is_same_v<_Size_type, size_t>) { - // convert size_t to _Size_type, avoiding truncation - if constexpr (!is_same_v<_Size_type, size_t>) { +template +_NODISCARD constexpr _Size_type _Convert_size(const _Unsigned_type _Len) noexcept( + sizeof(_Unsigned_type) <= sizeof(_Size_type)) { + // convert _Unsigned_type to _Size_type, avoiding truncation + _STL_INTERNAL_STATIC_ASSERT(_Unsigned_type(-1) > 0); + _STL_INTERNAL_STATIC_ASSERT(_Size_type(-1) > 0); + + if constexpr (sizeof(_Unsigned_type) > sizeof(_Size_type)) { if (_Len > (numeric_limits<_Size_type>::max)()) { - _Xlength_error("size_t too long for _Size_type"); + _Xlength_error("size is too long for _Size_type"); } } diff --git a/tests/std/tests/P0896R4_views_transform/test.cpp b/tests/std/tests/P0896R4_views_transform/test.cpp index ed8ac17cf9..6f31355a25 100644 --- a/tests/std/tests/P0896R4_views_transform/test.cpp +++ b/tests/std/tests/P0896R4_views_transform/test.cpp @@ -708,6 +708,31 @@ constexpr void iterator_instantiation_test() { iterator_instantiator::call>(); } +// GH-1709 "Performance issue in handling range iterators in vector constructor" +void test_gh_1709() { + const vector vec{1, 2, 3, 4, 5}; + const auto transformed{vec | views::transform([](int i) { return i * 10; })}; + const auto b{ranges::begin(transformed)}; + const auto e{ranges::end(transformed)}; + + { + const vector test_construct(b, e); + assert((test_construct == vector{10, 20, 30, 40, 50})); + } + + { + vector test_insert{-6, -7}; + test_insert.insert(test_insert.end(), b, e); + assert((test_insert == vector{-6, -7, 10, 20, 30, 40, 50})); + } + + { + vector test_assign{-8, -9}; + test_assign.assign(b, e); + assert((test_assign == vector{10, 20, 30, 40, 50})); + } +} + int main() { { // Validate copyable views constexpr span s{some_ints}; @@ -776,4 +801,6 @@ int main() { assert(*i1 == 'e'); assert(*i2 == 'h'); } + + test_gh_1709(); } diff --git a/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp b/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp index f69d3241ae..85931ac0ff 100644 --- a/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0000000_fancy_pointers/test.compile.pass.cpp @@ -24,6 +24,9 @@ #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +template +struct always_false : std::false_type {}; + int main() {} // COMPILE-ONLY template @@ -83,6 +86,7 @@ class fancy_pointer { } fancy_pointer operator++(int) { + static_assert(always_false::value, "avoid postincrement"); fancy_pointer result = *this; ++rep; return result; @@ -94,6 +98,7 @@ class fancy_pointer { } fancy_pointer operator--(int) { + static_assert(always_false::value, "avoid postdecrement"); fancy_pointer result = *this; --rep; return result; @@ -286,9 +291,6 @@ namespace std { }; } // namespace std -template -struct always_false : std::false_type {}; - template struct fancy_allocator { fancy_allocator() = default;