diff --git a/libcxx/include/__iterator/move_iterator.h b/libcxx/include/__iterator/move_iterator.h --- a/libcxx/include/__iterator/move_iterator.h +++ b/libcxx/include/__iterator/move_iterator.h @@ -59,10 +59,28 @@ : public __move_iter_category_base<_Iter> #endif { + private: + #if _LIBCPP_STD_VER > 17 + static consteval auto _get_iterator_concept() { + if constexpr (random_access_iterator<_Iter>) { + return random_access_iterator_tag{}; + } else if constexpr (bidirectional_iterator<_Iter>) { + return bidirectional_iterator_tag{}; + } else if constexpr (forward_iterator<_Iter>) { + return forward_iterator_tag{}; + } else { + return input_iterator_tag{}; + } + } + #endif //_LIBCPP_STD_VER > 17 + template friend class move_iterator; + + _Iter __current_; + public: #if _LIBCPP_STD_VER > 17 using iterator_type = _Iter; - using iterator_concept = input_iterator_tag; + using iterator_concept = decltype(_get_iterator_concept()); // iterator_category is inherited and not always present using value_type = iter_value_t<_Iter>; using difference_type = iter_difference_t<_Iter>; @@ -216,11 +234,6 @@ return ranges::iter_swap(__x.__current_, __y.__current_); } #endif // _LIBCPP_STD_VER > 17 - -private: - template friend class move_iterator; - - _Iter __current_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -116,6 +116,7 @@ __cpp_lib_logical_traits 201510L __cpp_lib_make_from_tuple 201606L __cpp_lib_make_reverse_iterator 201402L +__cpp_lib_move_iterator_concept 202207L __cpp_lib_make_unique 201304L __cpp_lib_map_try_emplace 201411L __cpp_lib_math_constants 201907L @@ -295,6 +296,7 @@ # undef __cpp_lib_array_constexpr # define __cpp_lib_array_constexpr 201811L # define __cpp_lib_assume_aligned 201811L +# define __cpp_lib_move_iterator_concept 202207L # define __cpp_lib_atomic_flag_test 201907L // # define __cpp_lib_atomic_float 201711L # define __cpp_lib_atomic_lock_free_type_aliases 201907L diff --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp --- a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp @@ -142,11 +142,11 @@ #if TEST_STD_VER > 17 test>(); - static_assert(std::is_same_v>::iterator_concept, std::input_iterator_tag>); - static_assert(std::is_same_v>::iterator_concept, std::input_iterator_tag>); - static_assert(std::is_same_v>::iterator_concept, std::input_iterator_tag>); - static_assert(std::is_same_v>::iterator_concept, std::input_iterator_tag>); - static_assert(std::is_same_v::iterator_concept, std::input_iterator_tag>); + static_assert(std::is_same_v>::iterator_concept, std::forward_iterator_tag>); + static_assert(std::is_same_v>::iterator_concept, std::bidirectional_iterator_tag>); + static_assert(std::is_same_v>::iterator_concept, std::random_access_iterator_tag>); + static_assert(std::is_same_v>::iterator_concept, std::random_access_iterator_tag>); + static_assert(std::is_same_v::iterator_concept, std::random_access_iterator_tag>); #endif return 0;