xref: /llvm-project/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.compile.pass.cpp (revision 37086ea21cd966465694cc6998a6e937846ec28d)
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <iterator>
10 
11 // struct iterator_traits
12 // {
13 // };
14 
15 #include <iterator>
16 #include <type_traits>
17 
18 #include "test_macros.h"
19 
20 template <class...>
21 using always_void = void;
22 
23 #define HAS_XXX(member)                                                                                                \
24   template <class T, class = void>                                                                                     \
25   struct has_##member : std::false_type {};                                                                            \
26   template <class T>                                                                                                   \
27   struct has_##member<T, always_void<typename T::member> > : std::true_type {}
28 
29 HAS_XXX(difference_type);
30 HAS_XXX(value_type);
31 HAS_XXX(pointer);
32 HAS_XXX(reference);
33 HAS_XXX(iterator_category);
34 
35 struct A {};
36 struct NotAnIteratorEmpty {};
37 
38 struct NotAnIteratorNoDifference {
39   //     typedef int                       difference_type;
40   typedef A value_type;
41   typedef A* pointer;
42   typedef A& reference;
43   typedef std::forward_iterator_tag iterator_category;
44 };
45 
46 struct NotAnIteratorNoValue {
47   typedef int difference_type;
48   //     typedef A                         value_type;
49   typedef A* pointer;
50   typedef A& reference;
51   typedef std::forward_iterator_tag iterator_category;
52 };
53 
54 struct NotAnIteratorNoPointer {
55   typedef int difference_type;
56   typedef A value_type;
57   //     typedef A*                        pointer;
58   typedef A& reference;
59   typedef std::forward_iterator_tag iterator_category;
60 };
61 
62 struct NotAnIteratorNoReference {
63   typedef int difference_type;
64   typedef A value_type;
65   typedef A* pointer;
66   //    typedef A&                        reference;
67   typedef std::forward_iterator_tag iterator_category;
68 };
69 
70 struct NotAnIteratorNoCategory {
71   typedef int difference_type;
72   typedef A value_type;
73   typedef A* pointer;
74   typedef A& reference;
75   //     typedef std::forward_iterator_tag iterator_category;
76 };
77 
78 void test() {
79   {
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, "");
86   }
87 
88   {
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, "");
95   }
96 
97   {
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, "");
104   }
105 #if TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
106   {
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, "");
113   }
114 #endif // TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
115   {
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, "");
122   }
123 
124   {
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, "");
131   }
132 }
133