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 #ifndef TEST_SUPPORT_TYPE_ALGORITHMS_H 10 #define TEST_SUPPORT_TYPE_ALGORITHMS_H 11 12 #include <type_traits> 13 14 #include "test_macros.h" 15 16 namespace types { 17 template <class... Types> 18 struct type_list {}; 19 20 // concatenates N type_lists to one (for N >= 1) 21 template <class...> 22 struct concatenate; 23 24 template <class... Types> 25 using concatenate_t = typename concatenate<Types...>::type; 26 27 // for_each takes a type_list calls f with each element as the first template argument 28 template <class... Types, class Functor> 29 TEST_CONSTEXPR_CXX14 void for_each(type_list<Types...>, Functor f); 30 31 // impl 32 template <class... Types> 33 struct concatenate<type_list<Types...> > { 34 using type = type_list<Types...>; 35 }; 36 37 template <class... Types1, class... Types2> 38 struct concatenate<type_list<Types1...>, type_list<Types2...> > { 39 using type = type_list<Types1..., Types2...>; 40 }; 41 42 template <class... Types1, class... Types2, class... Rest> 43 struct concatenate<type_list<Types1...>, type_list<Types2...>, Rest...> { 44 using type = concatenate_t<type_list<Types1..., Types2...>, Rest...>; 45 }; 46 47 template <class... Types> 48 TEST_CONSTEXPR_CXX14 void swallow(Types...) {} 49 50 template <class... Types, class Functor> 51 TEST_CONSTEXPR_CXX14 void for_each(type_list<Types...>, Functor f) { 52 swallow((f.template operator()<Types>(), 0)...); 53 } 54 55 template <class T> 56 struct type_identity { 57 using type = T; 58 }; 59 60 #if TEST_STD_VER >= 17 61 template <class Func> 62 struct apply_type_identity { 63 Func func_; 64 65 apply_type_identity(Func func) : func_(func) {} 66 67 template <class... Args> 68 decltype(auto) operator()() const { 69 return func_(type_identity<Args>{}...); 70 } 71 }; 72 73 template <class T> 74 apply_type_identity(T) -> apply_type_identity<T>; 75 76 #endif 77 template <template <class...> class T, class... Args> 78 struct partial_instantiation { 79 template <class Other> 80 using apply = T<Args..., Other>; 81 }; 82 83 // type categories defined in [basic.fundamental] plus extensions (without CV-qualifiers) 84 85 using character_types = 86 type_list<char 87 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 88 , 89 wchar_t 90 #endif 91 #ifndef TEST_HAS_NO_CHAR8_T 92 , 93 char8_t 94 #endif 95 #if TEST_STD_VER >= 11 96 , 97 char16_t, 98 char32_t 99 #endif 100 >; 101 102 using signed_integer_types = 103 type_list<signed char, 104 short, 105 int, 106 long, 107 long long 108 #ifndef TEST_HAS_NO_INT128 109 , 110 __int128_t 111 #endif 112 >; 113 114 using unsigned_integer_types = 115 type_list<unsigned char, 116 unsigned short, 117 unsigned int, 118 unsigned long, 119 unsigned long long 120 #ifndef TEST_HAS_NO_INT128 121 , 122 __uint128_t 123 #endif 124 >; 125 126 using integer_types = concatenate_t<character_types, signed_integer_types, unsigned_integer_types>; 127 128 using integral_types = concatenate_t<integer_types, type_list<bool> >; 129 130 using floating_point_types = type_list<float, double, long double>; 131 132 using arithmetic_types = concatenate_t<integral_types, floating_point_types>; 133 134 template <class T> 135 using cv_qualified_versions = type_list<T, const T, volatile T, const volatile T>; 136 137 template <class T> 138 struct type_list_as_pointers; 139 140 template <class... Types> 141 struct type_list_as_pointers<type_list<Types...> > { 142 using type = type_list<Types*...>; 143 }; 144 145 template <class T> 146 using as_pointers = typename type_list_as_pointers<T>::type; 147 } // namespace types 148 149 #endif // TEST_SUPPORT_TYPE_ALGORITHMS_H 150