Skip to content

Commit

Permalink
Implement P2520R0: move_iterator<T*> should be a random access iter…
Browse files Browse the repository at this point in the history
…ator
  • Loading branch information
strega-nil committed Jul 27, 2022
1 parent 04ee878 commit 363bf89
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 21 deletions.
20 changes: 17 additions & 3 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -3186,11 +3186,26 @@ class move_sentinel;

template <class>
struct _Move_iterator_category {};
template <class _Iter>
struct _Move_iterator_concept {
using iterator_concept = decltype(_Get_concept());
static auto _Get_concept() {
if constexpr (_RANGES random_access_iterator<_Iter>) {
return random_access_iterator_tag{};
} else if constexpr (_RANGES bidirectional_iterator<_Iter>) {
return bidirectional_iterator_tag{};
} else if constexpr (_RANGES forward_iterator_tag<_Iter>) {
return forward_iterator_tag{};
} else {
return input_iterator_tag{};
}
}
};

// clang-format off
template <class _Iter>
requires requires { typename _Iter_cat_t<_Iter>; }
struct _Move_iterator_category<_Iter> {
struct _Move_iterator_category<_Iter> : _Move_iterator_concept<_Iter> {
using iterator_category = conditional_t<derived_from<_Iter_cat_t<_Iter>, random_access_iterator_tag>,
random_access_iterator_tag, _Iter_cat_t<_Iter>>;
};
Expand All @@ -3211,8 +3226,7 @@ public:
using pointer = _Iter;

#ifdef __cpp_lib_concepts
using iterator_concept = input_iterator_tag;
using reference = iter_rvalue_reference_t<_Iter>;
using reference = iter_rvalue_reference_t<_Iter>;
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
using reference =
conditional_t<is_reference_v<_Iter_ref_t<_Iter>>, remove_reference_t<_Iter_ref_t<_Iter>>&&, _Iter_ref_t<_Iter>>;
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@
// P2415R2 What Is A view?
// P2418R2 Add Support For std::generator-like Types To std::format
// P2432R1 Fix istream_view
// P2520R0 move_iterator<T*> Should Be A Random-Access Iterator

// _HAS_CXX20 indirectly controls:
// P0619R4 Removing C++17-Deprecated Features
Expand Down Expand Up @@ -1409,6 +1410,7 @@
#define __cpp_lib_latch 201907L
#define __cpp_lib_list_remove_return_type 201806L
#define __cpp_lib_math_constants 201907L
#define __cpp_lib_move_iterator_concept 202207L
#define __cpp_lib_polymorphic_allocator 201902L

#if defined(__cpp_lib_concepts) // TRANSITION, GH-395
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ static_assert(contiguous_iterator<int Test::*volatile*>);
static_assert(contiguous_iterator<int Test::*const volatile*>);

// Tests for move_iterator specializations
static_assert(input_iterator<move_iterator<volatile int*>>);
static_assert(input_iterator<move_iterator<const volatile int*>>);
static_assert(input_iterator<move_iterator<volatile double*>>);
static_assert(input_iterator<move_iterator<const volatile double*>>);
static_assert(input_iterator<move_iterator<volatile nullptr_t*>>);
static_assert(input_iterator<move_iterator<const volatile nullptr_t*>>);
static_assert(input_iterator<move_iterator<volatile Unscoped*>>);
static_assert(input_iterator<move_iterator<const volatile Unscoped*>>);
static_assert(input_iterator<move_iterator<volatile Scoped*>>);
static_assert(input_iterator<move_iterator<const volatile Scoped*>>);
static_assert(input_iterator<move_iterator<Test* volatile*>>);
static_assert(input_iterator<move_iterator<Test* const volatile*>>);
static_assert(input_iterator<move_iterator<int Test::*volatile*>>);
static_assert(input_iterator<move_iterator<int Test::*const volatile*>>);
static_assert(random_access_iterator<move_iterator<volatile int*>>);
static_assert(random_access_iterator<move_iterator<const volatile int*>>);
static_assert(random_access_iterator<move_iterator<volatile double*>>);
static_assert(random_access_iterator<move_iterator<const volatile double*>>);
static_assert(random_access_iterator<move_iterator<volatile nullptr_t*>>);
static_assert(random_access_iterator<move_iterator<const volatile nullptr_t*>>);
static_assert(random_access_iterator<move_iterator<volatile Unscoped*>>);
static_assert(random_access_iterator<move_iterator<const volatile Unscoped*>>);
static_assert(random_access_iterator<move_iterator<volatile Scoped*>>);
static_assert(random_access_iterator<move_iterator<const volatile Scoped*>>);
static_assert(random_access_iterator<move_iterator<Test* volatile*>>);
static_assert(random_access_iterator<move_iterator<Test* const volatile*>>);
static_assert(random_access_iterator<move_iterator<int Test::*volatile*>>);
static_assert(random_access_iterator<move_iterator<int Test::*const volatile*>>);

int main() {} // COMPILE-ONLY
10 changes: 6 additions & 4 deletions tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3271,17 +3271,19 @@ struct std::common_type<move_iterator_test::input_iter<true>::rvalue_reference,

namespace move_iterator_test {
// Validate the iterator_concept/iterator_category metaprogramming
STATIC_ASSERT(same_as<move_iterator<simple_contiguous_iter<>>::iterator_concept, input_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_contiguous_iter<>>::iterator_concept, random_access_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_contiguous_iter<>>::iterator_category, random_access_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_random_iter<>>::iterator_concept, input_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_random_iter<>>::iterator_concept, random_access_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_random_iter<>>::iterator_category, random_access_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_bidi_iter<>>::iterator_concept, input_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_bidi_iter<>>::iterator_concept, bidirectional_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_bidi_iter<>>::iterator_category, bidirectional_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_forward_iter<>>::iterator_concept, input_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_forward_iter<>>::iterator_concept, forward_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_forward_iter<>>::iterator_category, forward_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_input_iter>::iterator_concept, input_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<simple_input_iter>::iterator_category, input_iterator_tag>);
STATIC_ASSERT(same_as<move_iterator<input_iter<true>>::iterator_concept, input_iterator_tag>);
STATIC_ASSERT(!has_member_iter_category<move_iterator<input_iter<true>>>);
STATIC_ASSERT(same_as<move_iterator<input_iter<true>>::iterator_concept, input_iterator_tag>);
STATIC_ASSERT(!has_member_iter_category<move_iterator<input_iter<false>>>);

// Validate that move_iterator<some_proxy_iterator>::reference is iter_rvalue_reference_t<some_proxy_iterator>
Expand Down

0 comments on commit 363bf89

Please sign in to comment.