C++ Utilities  4.12.1
Useful C++ classes and routines such as argument parser, IO and conversion utilities
traits.h
Go to the documentation of this file.
1 #ifndef CPP_UTILITIES_TRAITS_H
2 #define CPP_UTILITIES_TRAITS_H
3 
4 #include <iterator>
5 #include <type_traits>
6 
8 namespace Traits {
9 
11 namespace Detail {
12 enum class Enabler {};
13 }
15 
16 template <typename If, typename Then, typename Else> using Conditional = typename std::conditional<If::value, Then, Else>::type;
17 
18 template <bool B, typename...> struct Bool : std::integral_constant<bool, B> {
19 };
20 
21 template <typename T> using Not = Bool<!T::value>;
22 
23 template <typename... T> struct Any : Bool<false> {
24 };
25 template <typename Head, typename... Tail> struct Any<Head, Tail...> : Conditional<Head, Bool<true>, Any<Tail...>> {
26 };
27 
28 template <typename... T> struct All : Bool<true> {
29 };
30 template <typename Head, typename... Tail> struct All<Head, Tail...> : Conditional<Head, All<Tail...>, Bool<false>> {
31 };
32 
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;
35 
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;
38 
39 template <typename T, template <typename...> class Template> struct IsSpecializationOf : Bool<false> {
40 };
41 template <template <typename...> class Template, typename... Args> struct IsSpecializationOf<Template<Args...>, Template> : Bool<true> {
42 };
43 
44 template <typename T>
45 struct IsCString
46  : Bool<std::is_same<char const *, typename std::decay<T>::type>::value || std::is_same<char *, typename std::decay<T>::type>::value> {
47 };
48 template <typename T> struct IsString : Bool<IsCString<T>::value || IsSpecializationOf<T, std::basic_string>::value> {
49 };
50 
51 template <typename T, typename = void> struct IsComplete : Bool<false> {
52 };
53 template <typename T> struct IsComplete<T, decltype(void(sizeof(T)))> : Bool<true> {
54 };
55 
60 #define CPP_UTILITIES_PP_COMMA ,
61 
68 #define CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(CheckName, CheckCode) \
69  namespace Detail { \
70  template <typename T> auto CheckName(int) -> decltype(CheckCode, ::Traits::Bool<true>{}); \
71  template <typename T>::Traits::Bool<false> CheckName(...); \
72  } \
73  template <typename T> using CheckName = decltype(Detail::CheckName<T>(0))
74 
75 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasSize, std::is_integral<decltype(std::declval<T &>().size())>::value);
76 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsReservable, std::declval<T &>().reserve(0u));
78  // begin/end and operator !=
79  std::begin(std::declval<T &>())
80  != std::end(std::declval<T &>()) CPP_UTILITIES_PP_COMMA
81  // operator ,
83  // operator ++
84  ++ std::declval<decltype(begin(std::declval<T &>())) &>() CPP_UTILITIES_PP_COMMA
85  // operator*
86  void(*begin(std::declval<T &>())));
87 
88 } // namespace Traits
89 
90 #endif // CPP_UTILITIES_TRAITS_H
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
Definition: traits.h:33
#define CPP_UTILITIES_PP_COMMA
The CPP_UTILITIES_PP_COMMA macro helps passing "," as a macro argument.
Definition: traits.h:60
typename std::conditional< If::value, Then, Else >::type Conditional
Definition: traits.h:16
typename std::enable_if<!Any< Condition... >::value, Detail::Enabler >::type DisableIfAny
Definition: traits.h:37
typename std::enable_if<!All< Condition... >::value, Detail::Enabler >::type DisableIf
Definition: traits.h:34
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
Definition: traits.h:36
Contains traits for conveniently exploiting SFINAE.
Definition: traits.h:8