diff --git a/stl/inc/iterator b/stl/inc/iterator index dbcb87b5d97..139ebe72124 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -25,12 +25,19 @@ 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 +63,7 @@ public: } protected: - _Container* container; // pointer to container + _Container* container = nullptr; }; // FUNCTION TEMPLATE back_inserter @@ -72,12 +79,19 @@ 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 +117,7 @@ public: } protected: - _Container* container; // pointer to container + _Container* container = nullptr; }; // FUNCTION TEMPLATE front_inserter @@ -119,12 +133,19 @@ 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; +#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) {} @@ -155,8 +176,8 @@ public: } protected: - _Container* container; // pointer to container - typename _Container::iterator iter; // iterator into container + _Container* container = nullptr; + typename _Container::iterator iter{}; }; // FUNCTION TEMPLATE inserter diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 0e692b9aa18..83a7739937c 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. diff --git a/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp index 2d4fb010d34..2ea0b9e2d9a 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,29 @@ 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::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>); + 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();