C++ Utilities  5.0.0
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 
7 namespace CppUtilities {
8 
10 namespace Traits {
11 
13 namespace Detail {
14 enum class Enabler {};
15 }
17 
19 template <typename If, typename Then, typename Else> using Conditional = typename std::conditional<If::value, Then, Else>::type;
20 
22 template <bool B, typename...> struct Bool : std::integral_constant<bool, B> {
23 };
24 
26 template <typename T> using Not = Bool<!T::value>;
27 
29 template <typename... T> struct Any : Bool<false> {
30 };
32 template <typename Head, typename... Tail> struct Any<Head, Tail...> : Conditional<Head, Bool<true>, Any<Tail...>> {
33 };
34 
36 template <typename... T> struct All : Bool<true> {
37 };
39 template <typename Head, typename... Tail> struct All<Head, Tail...> : Conditional<Head, All<Tail...>, Bool<false>> {
40 };
41 
43 template <typename... T> struct None : Bool<true> {
44 };
46 template <typename Head, typename... Tail> struct None<Head, Tail...> : Conditional<Head, Bool<false>, None<Tail...>> {
47 };
48 
50 template <typename... Condition> using EnableIf = typename std::enable_if<All<Condition...>::value, Detail::Enabler>::type;
52 template <typename... Condition> using DisableIf = typename std::enable_if<!All<Condition...>::value, Detail::Enabler>::type;
53 
55 template <typename... Condition> using EnableIfAny = typename std::enable_if<Any<Condition...>::value, Detail::Enabler>::type;
57 template <typename... Condition> using DisableIfAny = typename std::enable_if<!Any<Condition...>::value, Detail::Enabler>::type;
58 
60 namespace Detail {
61 template <typename T, template <typename...> class Template> struct IsSpecializationOfHelper : Bool<false> {
62 };
63 template <template <typename...> class Template, typename... Args> struct IsSpecializationOfHelper<Template<Args...>, Template> : Bool<true> {
64 };
65 } // namespace Detail
68 template <typename Type, template <typename...> class... TemplateTypes>
69 struct IsSpecializationOf : Detail::IsSpecializationOfHelper<typename std::remove_cv<Type>::type, TemplateTypes...> {
70 };
72 template <typename Type, template <typename...> class... TemplateTypes> struct IsSpecializingAnyOf : Bool<false> {
73 };
75 template <typename Type, template <typename...> class TemplateType, template <typename...> class... RemainingTemplateTypes>
76 struct IsSpecializingAnyOf<Type, TemplateType, RemainingTemplateTypes...>
77  : Conditional<IsSpecializationOf<Type, TemplateType>, Bool<true>, IsSpecializingAnyOf<Type, RemainingTemplateTypes...>> {
78 };
79 
81 template <typename... T> struct IsAnyOf : Bool<false> {
82 };
84 template <typename Type, typename OtherType, typename... RemainingTypes>
85 struct IsAnyOf<Type, OtherType, RemainingTypes...> : Conditional<std::is_same<Type, OtherType>, Bool<true>, IsAnyOf<Type, RemainingTypes...>> {
86 };
88 template <typename... T> struct IsNoneOf : Bool<true> {
89 };
91 template <typename Type, typename OtherType, typename... RemainingTypes>
92 struct IsNoneOf<Type, OtherType, RemainingTypes...> : Conditional<std::is_same<Type, OtherType>, Bool<false>, IsNoneOf<Type, RemainingTypes...>> {
93 };
94 
96 template <typename T>
97 struct IsCString
98  : Bool<std::is_same<char const *, typename std::decay<T>::type>::value || std::is_same<char *, typename std::decay<T>::type>::value> {
99 };
101 template <typename T> struct IsString : Bool<IsCString<T>::value || IsSpecializationOf<T, std::basic_string>::value> {
102 };
103 
105 template <typename T, typename = void> struct IsComplete : Bool<false> {
106 };
108 template <typename T> struct IsComplete<T, decltype(void(sizeof(T)))> : Bool<true> {
109 };
110 
115 #define CPP_UTILITIES_PP_COMMA ,
116 
123 #define CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(CheckName, CheckCode) \
124  namespace Detail { \
125  template <typename T> auto CheckName(int) -> decltype(CheckCode, ::CppUtilities::Traits::Bool<true>{}); \
126  template <typename T>::CppUtilities::Traits::Bool<false> CheckName(...); \
127  } \
128  template <typename T> using CheckName = decltype(Detail::CheckName<T>(0))
129 
131 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsDereferencable, *(std::declval<T &>()));
132 
134 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasSize, std::is_integral<decltype(std::declval<T &>().size())>::value);
135 
137 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsReservable, std::declval<T &>().reserve(0u));
138 
140 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsResizable, std::declval<T &>().resize(0u));
141 
143 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasOperatorBool, std::declval<T &>() ? true : false);
144 
147  // begin/end and operator !=
148  std::begin(std::declval<T &>())
149  != std::end(std::declval<T &>()) CPP_UTILITIES_PP_COMMA
150  // operator ,
152  // operator ++
153  ++ std::declval<decltype(begin(std::declval<T &>())) &>() CPP_UTILITIES_PP_COMMA
154  // operator*
155  void(*begin(std::declval<T &>())));
156 
158 template <typename T, EnableIf<IsDereferencable<T>> * = nullptr> constexpr auto &dereferenceMaybe(T &value)
159 {
160  return *value;
161 }
162 
164 template <typename T, DisableIf<IsDereferencable<T>> * = nullptr> constexpr auto &dereferenceMaybe(T &value)
165 {
166  return value;
167 }
168 
170 template <typename T, EnableIf<IsDereferencable<T>> * = nullptr> constexpr const auto &dereferenceMaybe(const T &value)
171 {
172  return *value;
173 }
174 
176 template <typename T, DisableIf<IsDereferencable<T>> * = nullptr> constexpr const auto &dereferenceMaybe(const T &value)
177 {
178  return value;
179 }
180 
181 } // namespace Traits
182 
183 } // namespace CppUtilities
184 
185 #endif // CPP_UTILITIES_TRAITS_H
CppUtilities::Traits::EnableIf
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
Shortcut for std::enable_if to omit ::value and ::type.
Definition: traits.h:50
CppUtilities::Traits::IsAnyOf
Evaluates to Bool<true> if the specified type is any of the specified types; otherwise evaluates to B...
Definition: traits.h:81
CppUtilities::Traits::DisableIf
typename std::enable_if<!All< Condition... >::value, Detail::Enabler >::type DisableIf
Shortcut for std::enable_if to negate the condition and omit ::value and ::type.
Definition: traits.h:52
CppUtilities::Traits::IsCString
Evaluates to Bool<true> if the specified type is a C-string (char * or const char *); otherwise evalu...
Definition: traits.h:97
CppUtilities::Traits::EnableIfAny
typename std::enable_if< Any< Condition... >::value, Detail::Enabler >::type EnableIfAny
Shortcut for std::enable_if to apply Traits::Any and omit ::value and ::type.
Definition: traits.h:55
CppUtilities::Traits::Conditional
typename std::conditional< If::value, Then, Else >::type Conditional
Shortcut for std::conditional to omit ::value and ::type.
Definition: traits.h:19
CppUtilities::Traits::IsSpecializationOf
Evaluates to Bool<true> if the specified type is based on the specified.
Definition: traits.h:69
CppUtilities::Traits::IsString
Evaluates to Bool<true> if the specified type is a C-string (char * or const char *); otherwise evalu...
Definition: traits.h:101
CppUtilities::Traits::dereferenceMaybe
constexpr auto & dereferenceMaybe(T &value)
Dereferences the specified value if possible; otherwise just returns value itself.
Definition: traits.h:158
CppUtilities::Traits::DisableIfAny
typename std::enable_if<!Any< Condition... >::value, Detail::Enabler >::type DisableIfAny
Shortcut for std::enable_if to apply Traits::Any, negate the condition and omit ::value and ::type.
Definition: traits.h:57
CppUtilities
Contains all utilities provides by the c++utilities library.
Definition: argumentparser.h:17
CppUtilities::Traits::CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK
CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsDereferencable, *(std::declval< T & >()))
Evaluates to Bool<true> if the specified type can be dereferenced using the *-operator; otherwise eva...
CppUtilities::Traits::Any
Evaluates to Bool<true> if at least one of the specified conditions is true; otherwise evaluates to B...
Definition: traits.h:29
CppUtilities::Traits::IsComplete
Evaluates to Bool<true> if the specified type is complete; if the type is only forward-declared it ev...
Definition: traits.h:105
CppUtilities::Traits::IsSpecializingAnyOf
Evaluates to Bool<true> if the specified type is based on one of the specified templates; otherwise e...
Definition: traits.h:72
CppUtilities::Traits::Bool
Wraps a static boolean constant.
Definition: traits.h:22
CppUtilities::Traits::All
Evaluates to Bool<true> if all specified conditions are true; otherwise evaluates to Bool<false>.
Definition: traits.h:36
CppUtilities::Traits::None
Evaluates to Bool<true> if none of the specified conditions are true; otherwise evaluates to Bool<fal...
Definition: traits.h:43
CPP_UTILITIES_PP_COMMA
#define CPP_UTILITIES_PP_COMMA
The CPP_UTILITIES_PP_COMMA macro helps passing "," as a macro argument.
Definition: traits.h:115
CppUtilities::Traits::IsNoneOf
Evaluates to Bool<true> if the specified type is none of the specified types; otherwise evaluates to ...
Definition: traits.h:88