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