32 #ifndef VSMC_INTERNAL_TRAITS_HPP 33 #define VSMC_INTERNAL_TRAITS_HPP 38 #include <type_traits> 40 #define VSMC_DEFINE_TYPE_DISPATCH_TRAIT(Outer, Inner, Default) \ 41 template <typename T> \ 47 template <typename T> \ 48 class Has##Outer##Impl \ 56 template <typename U> \ 57 static char test(typename U::Inner *); \ 59 template <typename U> \ 60 static char2 test(...); \ 63 static constexpr bool value = \ 64 sizeof(test<T>(nullptr)) == sizeof(char); \ 67 template <typename T> \ 69 : public std::integral_constant<bool, Has##Outer##Impl<T>::value> \ 73 template <typename T, bool> \ 74 class Outer##Dispatch; \ 76 template <typename T> \ 77 class Outer##Dispatch<T, false> \ 80 using type = Default; \ 83 template <typename T> \ 84 class Outer##Dispatch<T, true> \ 87 using type = typename T::Inner; \ 92 template <typename T> \ 96 static constexpr bool value = internal::Has##Outer<T>::value; \ 97 using type = typename internal::Outer##Dispatch<T, value>::type; \ 100 template <typename T> \ 101 using Outer = typename Outer##Trait<T>::type; 103 #define VSMC_DEFINE_TYPE_TEMPLATE_DISPATCH_TRAIT(Outer, Inner, Default) \ 104 template <typename T> \ 105 class Outer##Trait; \ 110 template <typename T> \ 111 class Has##Outer##Impl \ 119 template <typename U> \ 120 static char test(typename U::template Inner<T> *); \ 122 template <typename U> \ 123 static char2 test(...); \ 126 static constexpr bool value = \ 127 sizeof(test<T>(nullptr)) == sizeof(char); \ 130 template <typename T> \ 132 : public std::integral_constant<bool, Has##Outer##Impl<T>::value> \ 136 template <typename T, bool> \ 137 class Outer##Dispatch; \ 139 template <typename T> \ 140 class Outer##Dispatch<T, false> \ 143 using type = Default<T>; \ 146 template <typename T> \ 147 class Outer##Dispatch<T, true> \ 150 using type = typename T::template Inner<T>; \ 154 template <typename T> \ 158 static constexpr bool value = internal::Has##Outer<T>::value; \ 159 using type = typename internal::Outer##Dispatch<T, value>::type; \ 162 template <typename T> \ 163 using Outer = typename Outer##Trait<T>::type; 165 #define VSMC_DEFINE_METHOD_CHECKER(name, RT, Args) \ 166 template <typename U> \ 167 class has_##name##_impl_ \ 175 template <typename V, RT(V::*) Args> \ 178 template <typename V, RT(V::*) Args const> \ 179 class sfinae_const_; \ 181 template <typename V, RT(*) Args> \ 182 class sfinae_static_; \ 184 template <typename V> \ 185 static char test(sfinae_<V, &V::name> *); \ 187 template <typename V> \ 188 static char test(sfinae_const_<V, &V::name> *); \ 190 template <typename V> \ 191 static char test(sfinae_static_<V, &V::name> *); \ 193 template <typename V> \ 194 static char2 test(...); \ 197 static constexpr bool value = \ 198 sizeof(test<U>(nullptr)) == sizeof(char); \ 201 template <typename U> \ 202 class has_##name##_ \ 203 : public std::integral_constant<bool, has_##name##_impl_<U>::value> \ 205 }; // class has_##name##_ 216 #endif // VSMC_INTERNAL_TRAITS_HPP #define VSMC_DEFINE_TYPE_DISPATCH_TRAIT(Outer, Inner, Default)
typename SizeTypeTrait< T >::type SizeType