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,27 @@ : 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 +233,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/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;