133 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// <iterator>10 11// struct iterator_traits12// {13// };14 15#include <iterator>16#include <type_traits>17 18#include "test_macros.h"19 20template <class...>21using 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 29HAS_XXX(difference_type);30HAS_XXX(value_type);31HAS_XXX(pointer);32HAS_XXX(reference);33HAS_XXX(iterator_category);34 35struct A {};36struct NotAnIteratorEmpty {};37 38struct 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 46struct 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 54struct 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 62struct 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 70struct 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 78void 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