1 #ifndef CPP_UTILITIES_TRAITS_H 2 #define CPP_UTILITIES_TRAITS_H 12 enum class Enabler {};
16 template <
typename If,
typename Then,
typename Else>
using Conditional =
typename std::conditional<If::value, Then, Else>::type;
18 template <
bool B,
typename...>
struct Bool : std::integral_constant<bool, B> {
23 template <
typename... T>
struct Any :
Bool<false> {
25 template <
typename Head,
typename... Tail>
struct Any<Head, Tail...> :
Conditional<Head, Bool<true>, Any<Tail...>> {
28 template <
typename... T>
struct All :
Bool<true> {
30 template <
typename Head,
typename... Tail>
struct All<Head, Tail...> :
Conditional<Head, All<Tail...>, Bool<false>> {
33 template <
typename... Condition>
using EnableIf =
typename std::enable_if<
All<Condition...>::value, Detail::Enabler>::type;
34 template <
typename... Condition>
using DisableIf =
typename std::enable_if<!
All<Condition...>::value, Detail::Enabler>::type;
36 template <
typename... Condition>
using EnableIfAny =
typename std::enable_if<
Any<Condition...>::value, Detail::Enabler>::type;
37 template <
typename... Condition>
using DisableIfAny =
typename std::enable_if<!
Any<Condition...>::value, Detail::Enabler>::type;
41 template <
template <
typename...>
class Template,
typename... Args>
struct IsSpecializationOf<Template<Args...>, Template> :
Bool<true> {
46 :
Bool<std::is_same<char const *, typename std::decay<T>::type>::value || std::is_same<char *, typename std::decay<T>::type>::value> {
48 template <
typename T>
struct IsString :
Bool<IsCString<T>::value || IsSpecializationOf<T, std::basic_string>::value> {
53 template <
typename T>
struct IsComplete<T, decltype(void(sizeof(T)))> :
Bool<true> {
60 #define CPP_UTILITIES_PP_COMMA , 68 #define CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(CheckName, CheckCode) \ 70 template <typename T> auto CheckName(int) -> decltype(CheckCode, ::Traits::Bool<true>{}); \ 71 template <typename T>::Traits::Bool<false> CheckName(...); \ 73 template <typename T> using CheckName = decltype(Detail::CheckName<T>(0)) 79 std::begin(std::declval<T &>())
86 void(*begin(std::declval<T &>())));
90 #endif // CPP_UTILITIES_TRAITS_H
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
#define CPP_UTILITIES_PP_COMMA
The CPP_UTILITIES_PP_COMMA macro helps passing "," as a macro argument.
typename std::conditional< If::value, Then, Else >::type Conditional
typename std::enable_if<!Any< Condition... >::value, Detail::Enabler >::type DisableIfAny
typename std::enable_if<!All< Condition... >::value, Detail::Enabler >::type DisableIf
CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasSize, std::is_integral< decltype(std::declval< T &>().size())>::value)
typename std::enable_if< Any< Condition... >::value, Detail::Enabler >::type EnableIfAny
Contains traits for conveniently exploiting SFINAE.