1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 // struct iterator_traits
16 #include <type_traits>
18 #include "test_macros.h"
21 using always_void
= void;
23 #define HAS_XXX(member) \
24 template <class T, class = void> \
25 struct has_##member : std::false_type {}; \
27 struct has_##member<T, always_void<typename T::member> > : std::true_type {}
29 HAS_XXX(difference_type
);
33 HAS_XXX(iterator_category
);
36 struct NotAnIteratorEmpty
{};
38 struct NotAnIteratorNoDifference
{
39 // typedef int difference_type;
43 typedef std::forward_iterator_tag iterator_category
;
46 struct NotAnIteratorNoValue
{
47 typedef int difference_type
;
48 // typedef A value_type;
51 typedef std::forward_iterator_tag iterator_category
;
54 struct NotAnIteratorNoPointer
{
55 typedef int difference_type
;
57 // typedef A* pointer;
59 typedef std::forward_iterator_tag iterator_category
;
62 struct NotAnIteratorNoReference
{
63 typedef int difference_type
;
66 // typedef A& reference;
67 typedef std::forward_iterator_tag iterator_category
;
70 struct NotAnIteratorNoCategory
{
71 typedef int difference_type
;
75 // typedef std::forward_iterator_tag iterator_category;
80 typedef std::iterator_traits
<NotAnIteratorEmpty
> T
;
81 static_assert(!has_difference_type
<T
>::value
, "");
82 static_assert(!has_value_type
<T
>::value
, "");
83 static_assert(!has_pointer
<T
>::value
, "");
84 static_assert(!has_reference
<T
>::value
, "");
85 static_assert(!has_iterator_category
<T
>::value
, "");
89 typedef std::iterator_traits
<NotAnIteratorNoDifference
> T
;
90 static_assert(!has_difference_type
<T
>::value
, "");
91 static_assert(!has_value_type
<T
>::value
, "");
92 static_assert(!has_pointer
<T
>::value
, "");
93 static_assert(!has_reference
<T
>::value
, "");
94 static_assert(!has_iterator_category
<T
>::value
, "");
98 typedef std::iterator_traits
<NotAnIteratorNoValue
> T
;
99 static_assert(!has_difference_type
<T
>::value
, "");
100 static_assert(!has_value_type
<T
>::value
, "");
101 static_assert(!has_pointer
<T
>::value
, "");
102 static_assert(!has_reference
<T
>::value
, "");
103 static_assert(!has_iterator_category
<T
>::value
, "");
105 #if TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
107 typedef std::iterator_traits
<NotAnIteratorNoPointer
> T
;
108 static_assert(!has_difference_type
<T
>::value
, "");
109 static_assert(!has_value_type
<T
>::value
, "");
110 static_assert(!has_pointer
<T
>::value
, "");
111 static_assert(!has_reference
<T
>::value
, "");
112 static_assert(!has_iterator_category
<T
>::value
, "");
114 #endif // TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
116 typedef std::iterator_traits
<NotAnIteratorNoReference
> T
;
117 static_assert(!has_difference_type
<T
>::value
, "");
118 static_assert(!has_value_type
<T
>::value
, "");
119 static_assert(!has_pointer
<T
>::value
, "");
120 static_assert(!has_reference
<T
>::value
, "");
121 static_assert(!has_iterator_category
<T
>::value
, "");
125 typedef std::iterator_traits
<NotAnIteratorNoCategory
> T
;
126 static_assert(!has_difference_type
<T
>::value
, "");
127 static_assert(!has_value_type
<T
>::value
, "");
128 static_assert(!has_pointer
<T
>::value
, "");
129 static_assert(!has_reference
<T
>::value
, "");
130 static_assert(!has_iterator_category
<T
>::value
, "");