From 4eca4d16a512dd7fe814456598307dbd319420c6 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Thu, 5 Mar 2020 20:14:05 -0800 Subject: [PATCH 1/6] P0896R4 changes to insert iterators When `defined(__cpp_lib_concepts)`, `(back_|front_|)insert_iterator` are default constructible, and have `ptrdiff_t` as difference type. --- stl/inc/iterator | 38 +++++++++++++------ .../test.cpp | 22 +++++++++++ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index dbcb87b5d9..c7a4bd6778 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -25,12 +25,18 @@ class back_insert_iterator { // wrap pushes to back of container as output itera public: using iterator_category = output_iterator_tag; using value_type = void; - using difference_type = void; using pointer = void; using reference = void; using container_type = _Container; +#ifdef __cpp_lib_concepts + using difference_type = ptrdiff_t; + constexpr back_insert_iterator() noexcept = default; +#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv + using difference_type = void; +#endif // __cpp_lib_concepts + explicit back_insert_iterator(_Container& _Cont) noexcept /* strengthened */ : container(_STD addressof(_Cont)) {} back_insert_iterator& operator=(const typename _Container::value_type& _Val) { @@ -56,7 +62,7 @@ public: } protected: - _Container* container; // pointer to container + _Container* container = nullptr; }; // FUNCTION TEMPLATE back_inserter @@ -72,12 +78,18 @@ class front_insert_iterator { // wrap pushes to front of container as output ite public: using iterator_category = output_iterator_tag; using value_type = void; - using difference_type = void; using pointer = void; using reference = void; using container_type = _Container; +#ifdef __cpp_lib_concepts + using difference_type = ptrdiff_t; + constexpr front_insert_iterator() noexcept = default; +#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv + using difference_type = void; +#endif // __cpp_lib_concepts + explicit front_insert_iterator(_Container& _Cont) : container(_STD addressof(_Cont)) {} front_insert_iterator& operator=(const typename _Container::value_type& _Val) { // push value into container @@ -103,7 +115,7 @@ public: } protected: - _Container* container; // pointer to container + _Container* container = nullptr; }; // FUNCTION TEMPLATE front_inserter @@ -119,24 +131,28 @@ class insert_iterator { // wrap inserts into container as output iterator public: using iterator_category = output_iterator_tag; using value_type = void; - using difference_type = void; using pointer = void; using reference = void; + using container_type = _Container; - using container_type = _Container; +#ifdef __cpp_lib_concepts + using difference_type = ptrdiff_t; + insert_iterator() = default; +#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv + using difference_type = void; +#endif // __cpp_lib_concepts insert_iterator(_Container& _Cont, typename _Container::iterator _Where) : container(_STD addressof(_Cont)), iter(_Where) {} - insert_iterator& operator=( - const typename _Container::value_type& _Val) { // insert into container and increment stored iterator + insert_iterator& operator=(const typename _Container::value_type& _Val) { + // insert into container and increment stored iterator iter = container->insert(iter, _Val); ++iter; return *this; } insert_iterator& operator=(typename _Container::value_type&& _Val) { // push value into container - iter = container->insert(iter, _STD move(_Val)); ++iter; return *this; @@ -155,8 +171,8 @@ public: } protected: - _Container* container; // pointer to container - typename _Container::iterator iter; // iterator into container + _Container* container = nullptr; + typename _Container::iterator iter = typename _Container::iterator(); }; // FUNCTION TEMPLATE inserter diff --git a/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp index 2d4fb010d3..a2613165b0 100644 --- a/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp +++ b/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp @@ -5,8 +5,10 @@ #include #include #include +#include #include #include +#include #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) @@ -2770,6 +2772,26 @@ namespace iter_ops { } } // namespace iter_ops +namespace insert_iterators { + template + constexpr bool test() { + using std::back_insert_iterator, std::front_insert_iterator, std::insert_iterator; + using std::default_initializable, std::iter_difference_t, std::ptrdiff_t, std::same_as; + + STATIC_ASSERT(default_initializable>); + STATIC_ASSERT(default_initializable>); + STATIC_ASSERT(default_initializable>); + STATIC_ASSERT(same_as>, ptrdiff_t>); + STATIC_ASSERT(same_as>, ptrdiff_t>); + STATIC_ASSERT(same_as>, ptrdiff_t>); + + return true; + } + + STATIC_ASSERT(test>()); + STATIC_ASSERT(test>()); +} // namespace insert_iterators + int main() { iterator_cust_swap_test::test(); iter_ops::test(); From 1db61ea4d4cfcb58e75b45f4623e7541d8d16559 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 6 Mar 2020 15:39:51 -0800 Subject: [PATCH 2/6] Review comments --- stl/inc/iterator | 14 +++++++++----- .../P0896R4_ranges_iterator_machinery/test.cpp | 5 ++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index c7a4bd6778..b736b802ba 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -31,7 +31,8 @@ public: using container_type = _Container; #ifdef __cpp_lib_concepts - using difference_type = ptrdiff_t; + using difference_type = ptrdiff_t; + constexpr back_insert_iterator() noexcept = default; #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv using difference_type = void; @@ -84,7 +85,8 @@ public: using container_type = _Container; #ifdef __cpp_lib_concepts - using difference_type = ptrdiff_t; + using difference_type = ptrdiff_t; + constexpr front_insert_iterator() noexcept = default; #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv using difference_type = void; @@ -133,11 +135,13 @@ public: using value_type = void; using pointer = void; using reference = void; - using container_type = _Container; + + using container_type = _Container; #ifdef __cpp_lib_concepts using difference_type = ptrdiff_t; - insert_iterator() = default; + + insert_iterator() = default; #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv using difference_type = void; #endif // __cpp_lib_concepts @@ -172,7 +176,7 @@ public: protected: _Container* container = nullptr; - typename _Container::iterator iter = typename _Container::iterator(); + typename _Container::iterator iter = {}; }; // FUNCTION TEMPLATE inserter diff --git a/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp index a2613165b0..2ea0b9e2d9 100644 --- a/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp +++ b/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp @@ -2776,10 +2776,13 @@ namespace insert_iterators { template constexpr bool test() { using std::back_insert_iterator, std::front_insert_iterator, std::insert_iterator; - using std::default_initializable, std::iter_difference_t, std::ptrdiff_t, std::same_as; + using std::default_initializable, std::is_nothrow_default_constructible_v, std::iter_difference_t, + std::ptrdiff_t, std::same_as; STATIC_ASSERT(default_initializable>); + STATIC_ASSERT(is_nothrow_default_constructible_v>); STATIC_ASSERT(default_initializable>); + STATIC_ASSERT(is_nothrow_default_constructible_v>); STATIC_ASSERT(default_initializable>); STATIC_ASSERT(same_as>, ptrdiff_t>); STATIC_ASSERT(same_as>, ptrdiff_t>); From 223cf23c16038a7a02dcc1440553a2e2fac6259a Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 6 Mar 2020 15:50:57 -0800 Subject: [PATCH 3/6] Revert NFC changes to reduce conflict potential --- stl/inc/iterator | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index b736b802ba..40df6bea8a 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -149,14 +149,15 @@ public: insert_iterator(_Container& _Cont, typename _Container::iterator _Where) : container(_STD addressof(_Cont)), iter(_Where) {} - insert_iterator& operator=(const typename _Container::value_type& _Val) { - // insert into container and increment stored iterator + insert_iterator& operator=( + const typename _Container::value_type& _Val) { // insert into container and increment stored iterator iter = container->insert(iter, _Val); ++iter; return *this; } insert_iterator& operator=(typename _Container::value_type&& _Val) { // push value into container + iter = container->insert(iter, _STD move(_Val)); ++iter; return *this; From 62e0cc6a2abfdad47718f6746721e9a0245c6e37 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 6 Mar 2020 17:00:36 -0800 Subject: [PATCH 4/6] Skip libc++ tests broken by this change --- tests/libcxx/skipped_tests.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 0e692b9aa1..83a7739937 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -779,6 +779,11 @@ language.support\cmp\cmp.weakord\weakord.pass.cpp # error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax containers\sequences\array\array.creation\to_array.pass.cpp +# Tests that need to learn that insert iterators have non-void difference type in C++20 +iterators\predef.iterators\insert.iterators\back.insert.iterator\types.pass.cpp +iterators\predef.iterators\insert.iterators\front.insert.iterator\types.pass.cpp +iterators\predef.iterators\insert.iterators\insert.iterator\types.pass.cpp + # *** LIKELY STL BUGS *** # Not yet analyzed, likely STL bugs. Assertions and other runtime failures. From 79c979a8b64dae2c6abc9255812a54363d97c73b Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 6 Mar 2020 17:37:35 -0800 Subject: [PATCH 5/6] Update stl/inc/iterator Use direct-list-init instead of copy-list-init for `insert_iterator::iter`. Co-Authored-By: Stephan T. Lavavej --- stl/inc/iterator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index 40df6bea8a..bbe75a175a 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -177,7 +177,7 @@ public: protected: _Container* container = nullptr; - typename _Container::iterator iter = {}; + typename _Container::iterator iter{}; }; // FUNCTION TEMPLATE inserter From 48ea79b8b7231e9be871064336275d8fa9c87130 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sat, 7 Mar 2020 17:38:41 -0800 Subject: [PATCH 6/6] clang-format --- stl/inc/iterator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/iterator b/stl/inc/iterator index bbe75a175a..139ebe7212 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -176,7 +176,7 @@ public: } protected: - _Container* container = nullptr; + _Container* container = nullptr; typename _Container::iterator iter{}; };