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,24 @@ : public __move_iter_category_base<_Iter> #endif { + private: +#if _LIBCPP_STD_VER > 20 + 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 > 20 public: -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER > 20 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>; @@ -70,6 +84,7 @@ using reference = iter_rvalue_reference_t<_Iter>; #else typedef _Iter iterator_type; + typedef input_iterator_tag iterator_concept; typedef _If< __is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, @@ -85,8 +100,7 @@ __libcpp_remove_reference_t<__reference>&&, __reference >::type reference; -#endif // _LIBCPP_STD_VER > 17 - +#endif // _LIBCPP_STD_VER > 20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} @@ -216,11 +230,10 @@ return ranges::iter_swap(__x.__current_, __y.__current_); } #endif // _LIBCPP_STD_VER > 17 - private: - template friend class move_iterator; +template friend class move_iterator; - _Iter __current_; + _Iter __current_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); diff --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_specializations.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_specializations.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_specializations.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// move_iterator + +#include + +#include "test_macros.h" +#include "test_iterators.h" + + +// Tests for move_iterator specializations +#if TEST_STD_VER > 20 +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 +int main() {} // COMPILE-ONLY