Skip to content

Commit 1d68abc

Browse files
authored
[libc++] Move _ITER_TRAITS and _ITER_CONCEPT into <__iterator/concepts.h> (#140528)
`_ITER_TRAITS` and `_ITER_CONCEPT` are really implenentation details of `<__iterator/concetps.h>`, so it makes more sense to put them there than into `<__iterator/iterator_traits.h>`.
1 parent 678cdd6 commit 1d68abc

File tree

4 files changed

+80
-96
lines changed

4 files changed

+80
-96
lines changed

libcxx/include/__iterator/concepts.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,19 @@
2929
#include <__iterator/incrementable_traits.h>
3030
#include <__iterator/iter_move.h>
3131
#include <__iterator/iterator_traits.h>
32-
#include <__iterator/readable_traits.h>
3332
#include <__memory/pointer_traits.h>
3433
#include <__type_traits/add_pointer.h>
3534
#include <__type_traits/common_reference.h>
35+
#include <__type_traits/conditional.h>
36+
#include <__type_traits/disjunction.h>
37+
#include <__type_traits/enable_if.h>
3638
#include <__type_traits/integral_constant.h>
3739
#include <__type_traits/invoke.h>
3840
#include <__type_traits/is_pointer.h>
3941
#include <__type_traits/is_primary_template.h>
4042
#include <__type_traits/is_reference.h>
4143
#include <__type_traits/is_referenceable.h>
44+
#include <__type_traits/is_valid_expansion.h>
4245
#include <__type_traits/remove_cv.h>
4346
#include <__type_traits/remove_cvref.h>
4447
#include <__utility/forward.h>
@@ -151,6 +154,42 @@ concept sized_sentinel_for =
151154
{ __i - __s } -> same_as<iter_difference_t<_Ip>>;
152155
};
153156

157+
template <class _Iter>
158+
struct __iter_traits_cache {
159+
using type _LIBCPP_NODEBUG =
160+
_If<__is_primary_template<iterator_traits<_Iter> >::value, _Iter, iterator_traits<_Iter> >;
161+
};
162+
template <class _Iter>
163+
using _ITER_TRAITS _LIBCPP_NODEBUG = typename __iter_traits_cache<_Iter>::type;
164+
165+
struct __iter_concept_concept_test {
166+
template <class _Iter>
167+
using _Apply _LIBCPP_NODEBUG = typename _ITER_TRAITS<_Iter>::iterator_concept;
168+
};
169+
struct __iter_concept_category_test {
170+
template <class _Iter>
171+
using _Apply _LIBCPP_NODEBUG = typename _ITER_TRAITS<_Iter>::iterator_category;
172+
};
173+
struct __iter_concept_random_fallback {
174+
template <class _Iter>
175+
using _Apply _LIBCPP_NODEBUG =
176+
__enable_if_t<__is_primary_template<iterator_traits<_Iter> >::value, random_access_iterator_tag>;
177+
};
178+
179+
template <class _Iter, class _Tester>
180+
struct __test_iter_concept : _IsValidExpansion<_Tester::template _Apply, _Iter>, _Tester {};
181+
182+
template <class _Iter>
183+
struct __iter_concept_cache {
184+
using type _LIBCPP_NODEBUG =
185+
_Or<__test_iter_concept<_Iter, __iter_concept_concept_test>,
186+
__test_iter_concept<_Iter, __iter_concept_category_test>,
187+
__test_iter_concept<_Iter, __iter_concept_random_fallback> >;
188+
};
189+
190+
template <class _Iter>
191+
using _ITER_CONCEPT _LIBCPP_NODEBUG = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
192+
154193
// [iterator.concept.input]
155194
template <class _Ip>
156195
concept input_iterator = input_or_output_iterator<_Ip> && indirectly_readable<_Ip> && requires {

libcxx/include/__iterator/iterator_traits.h

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,12 @@
2727
#include <__type_traits/conditional.h>
2828
#include <__type_traits/detected_or.h>
2929
#include <__type_traits/disjunction.h>
30-
#include <__type_traits/enable_if.h>
3130
#include <__type_traits/integral_constant.h>
3231
#include <__type_traits/is_convertible.h>
3332
#include <__type_traits/is_object.h>
3433
#include <__type_traits/is_primary_template.h>
3534
#include <__type_traits/is_reference.h>
3635
#include <__type_traits/is_referenceable.h>
37-
#include <__type_traits/is_valid_expansion.h>
3836
#include <__type_traits/nat.h>
3937
#include <__type_traits/remove_const.h>
4038
#include <__type_traits/remove_cv.h>
@@ -73,42 +71,6 @@ struct random_access_iterator_tag : public bidirectional_iterator_tag {};
7371
struct contiguous_iterator_tag : public random_access_iterator_tag {};
7472
#endif
7573

76-
template <class _Iter>
77-
struct __iter_traits_cache {
78-
using type _LIBCPP_NODEBUG =
79-
_If<__is_primary_template<iterator_traits<_Iter> >::value, _Iter, iterator_traits<_Iter> >;
80-
};
81-
template <class _Iter>
82-
using _ITER_TRAITS _LIBCPP_NODEBUG = typename __iter_traits_cache<_Iter>::type;
83-
84-
struct __iter_concept_concept_test {
85-
template <class _Iter>
86-
using _Apply _LIBCPP_NODEBUG = typename _ITER_TRAITS<_Iter>::iterator_concept;
87-
};
88-
struct __iter_concept_category_test {
89-
template <class _Iter>
90-
using _Apply _LIBCPP_NODEBUG = typename _ITER_TRAITS<_Iter>::iterator_category;
91-
};
92-
struct __iter_concept_random_fallback {
93-
template <class _Iter>
94-
using _Apply _LIBCPP_NODEBUG =
95-
__enable_if_t<__is_primary_template<iterator_traits<_Iter> >::value, random_access_iterator_tag>;
96-
};
97-
98-
template <class _Iter, class _Tester>
99-
struct __test_iter_concept : _IsValidExpansion<_Tester::template _Apply, _Iter>, _Tester {};
100-
101-
template <class _Iter>
102-
struct __iter_concept_cache {
103-
using type _LIBCPP_NODEBUG =
104-
_Or<__test_iter_concept<_Iter, __iter_concept_concept_test>,
105-
__test_iter_concept<_Iter, __iter_concept_category_test>,
106-
__test_iter_concept<_Iter, __iter_concept_random_fallback> >;
107-
};
108-
109-
template <class _Iter>
110-
using _ITER_CONCEPT _LIBCPP_NODEBUG = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
111-
11274
template <class _Tp>
11375
struct __has_iterator_typedefs {
11476
private:
@@ -195,16 +157,6 @@ concept __specifies_members = requires {
195157
requires __has_member_iterator_category<_Ip>;
196158
};
197159

198-
template <class>
199-
struct __iterator_traits_member_pointer_or_void {
200-
using type _LIBCPP_NODEBUG = void;
201-
};
202-
203-
template <__has_member_pointer _Tp>
204-
struct __iterator_traits_member_pointer_or_void<_Tp> {
205-
using type _LIBCPP_NODEBUG = typename _Tp::pointer;
206-
};
207-
208160
template <class _Tp>
209161
concept __cpp17_iterator_missing_members = !__specifies_members<_Tp> && __iterator_traits_detail::__cpp17_iterator<_Tp>;
210162

@@ -304,6 +256,9 @@ struct __iterator_traits_difference_type<_Ip> {
304256
template <class>
305257
struct __iterator_traits {};
306258

259+
template <class _Tp>
260+
using __pointer_member _LIBCPP_NODEBUG = typename _Tp::pointer;
261+
307262
// [iterator.traits]/3.1
308263
// If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and
309264
// `iterator-category`, then `iterator-traits<I>` has the following publicly accessible members:
@@ -312,7 +267,7 @@ struct __iterator_traits<_Ip> {
312267
using iterator_category = typename _Ip::iterator_category;
313268
using value_type = typename _Ip::value_type;
314269
using difference_type = typename _Ip::difference_type;
315-
using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type;
270+
using pointer = __detected_or_t<void, __pointer_member, _Ip>;
316271
using reference = typename _Ip::reference;
317272
};
318273

libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.pass.cpp renamed to libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.compile.pass.cpp

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// UNSUPPORTED: c++03
9+
// REQUIRES: std-at-least-c++20
1010

1111
// ITER_TRAITS(I)
1212

@@ -19,6 +19,7 @@
1919
// random_access_iterator_tag.
2020
// (1.4) -- Otherwise, ITER_CONCEPT(I) does not denote a type.
2121

22+
#include <__iterator/concepts.h>
2223
#include <__type_traits/is_valid_expansion.h>
2324
#include <cstddef>
2425
#include <iterator>
@@ -30,19 +31,19 @@ struct OtherTagTwo : std::output_iterator_tag {};
3031

3132
struct MyIter {
3233
using iterator_category = std::random_access_iterator_tag;
33-
using iterator_concept = int;
34-
using value_type = char;
35-
using difference_type = std::ptrdiff_t;
36-
using pointer = char*;
37-
using reference = char&;
34+
using iterator_concept = int;
35+
using value_type = char;
36+
using difference_type = std::ptrdiff_t;
37+
using pointer = char*;
38+
using reference = char&;
3839
};
3940

4041
struct MyIter2 {
4142
using iterator_category = OtherTag;
42-
using value_type = char;
43-
using difference_type = std::ptrdiff_t;
44-
using pointer = char*;
45-
using reference = char&;
43+
using value_type = char;
44+
using difference_type = std::ptrdiff_t;
45+
using pointer = char*;
46+
using reference = char&;
4647
};
4748

4849
struct MyIter3 {};
@@ -52,40 +53,29 @@ struct EmptyWithSpecial {};
5253
template <>
5354
struct std::iterator_traits<MyIter3> {
5455
using iterator_category = OtherTagTwo;
55-
using value_type = char;
56-
using difference_type = std::ptrdiff_t;
57-
using pointer = char*;
58-
using reference = char&;
56+
using value_type = char;
57+
using difference_type = std::ptrdiff_t;
58+
using pointer = char*;
59+
using reference = char&;
5960
};
6061

6162
template <>
6263
struct std::iterator_traits<EmptyWithSpecial> {
6364
// empty non-default.
6465
};
6566

66-
int main(int, char**) {
67-
// If the qualified-id ITER_TRAITS(I)::iterator_concept is valid and names a type,
68-
// then ITER_CONCEPT(I) denotes that type.
69-
{
70-
#if TEST_STD_VER > 17
71-
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<char*>, std::contiguous_iterator_tag);
72-
#endif
73-
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter>, int);
74-
}
75-
// Otherwise, if the qualified-id ITER_TRAITS(I)::iterator_category is valid
76-
// and names a type, then ITER_CONCEPT(I) denotes that type.
77-
{
78-
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter2>, OtherTag);
79-
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter3>, OtherTagTwo);
80-
}
81-
// FIXME - This requirement makes no sense to me. Why does an empty type with
82-
// an empty default iterator_traits get a category of random?
83-
{
84-
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<Empty>, std::random_access_iterator_tag);
85-
}
86-
{
87-
static_assert(!std::_IsValidExpansion<std::_ITER_CONCEPT, EmptyWithSpecial>::value, "");
88-
}
67+
// If the qualified-id ITER_TRAITS(I)::iterator_concept is valid and names a type,
68+
// then ITER_CONCEPT(I) denotes that type.
69+
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<char*>, std::contiguous_iterator_tag);
70+
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter>, int);
8971

90-
return 0;
91-
}
72+
// Otherwise, if the qualified-id ITER_TRAITS(I)::iterator_category is valid
73+
// and names a type, then ITER_CONCEPT(I) denotes that type.
74+
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter2>, OtherTag);
75+
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter3>, OtherTagTwo);
76+
77+
// FIXME - This requirement makes no sense to me. Why does an empty type with
78+
// an empty default iterator_traits get a category of random?
79+
ASSERT_SAME_TYPE(std::_ITER_CONCEPT<Empty>, std::random_access_iterator_tag);
80+
81+
static_assert(!std::_IsValidExpansion<std::_ITER_CONCEPT, EmptyWithSpecial>::value);

libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// UNSUPPORTED: c++03
9+
// REQUIRES: std-at-least-c++20
1010

1111
// ITER_TRAITS(I)
1212

1313
// For a type I, let ITER_TRAITS(I) denote the type I if iterator_traits<I> names
1414
// a specialization generated from the primary template. Otherwise,
1515
// ITER_TRAITS(I) denotes iterator_traits<I>.
1616

17-
#include <iterator>
17+
#include <__iterator/concepts.h>
1818
#include <type_traits>
1919

2020
#include "test_iterators.h"
@@ -27,8 +27,8 @@ template<> struct std::iterator_traits<B> {};
2727
template<> struct std::iterator_traits<C> : std::iterator_traits<A> {};
2828
template<> struct std::iterator_traits<D> : std::iterator_traits<int*> {};
2929

30-
static_assert(std::is_same<std::_ITER_TRAITS<int*>, std::iterator_traits<int*>>::value, "");
31-
static_assert(std::is_same<std::_ITER_TRAITS<A>, A>::value, "");
32-
static_assert(std::is_same<std::_ITER_TRAITS<B>, std::iterator_traits<B>>::value, "");
33-
static_assert(std::is_same<std::_ITER_TRAITS<C>, std::iterator_traits<C>>::value, "");
34-
static_assert(std::is_same<std::_ITER_TRAITS<D>, std::iterator_traits<D>>::value, "");
30+
static_assert(std::is_same<std::_ITER_TRAITS<int*>, std::iterator_traits<int*>>::value);
31+
static_assert(std::is_same<std::_ITER_TRAITS<A>, A>::value);
32+
static_assert(std::is_same<std::_ITER_TRAITS<B>, std::iterator_traits<B>>::value);
33+
static_assert(std::is_same<std::_ITER_TRAITS<C>, std::iterator_traits<C>>::value);
34+
static_assert(std::is_same<std::_ITER_TRAITS<D>, std::iterator_traits<D>>::value);

0 commit comments

Comments
 (0)