C++ Utilities 5.11.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 <string>
6#include <type_traits>
7
8namespace CppUtilities {
9
11namespace Traits {
12
14namespace Detail {
15enum class Enabler {};
16}
18
20template <typename If, typename Then, typename Else> using Conditional = typename std::conditional<If::value, Then, Else>::type;
21
23template <bool B, typename...> struct Bool : std::integral_constant<bool, B> {
24};
25
27template <typename T> using Not = Bool<!T::value>;
28
30template <typename... T> struct Any : Bool<false> {
31};
33template <typename Head, typename... Tail> struct Any<Head, Tail...> : Conditional<Head, Bool<true>, Any<Tail...>> {
34};
35
37template <typename... T> struct All : Bool<true> {
38};
40template <typename Head, typename... Tail> struct All<Head, Tail...> : Conditional<Head, All<Tail...>, Bool<false>> {
41};
42
44template <typename... T> struct None : Bool<true> {
45};
47template <typename Head, typename... Tail> struct None<Head, Tail...> : Conditional<Head, Bool<false>, None<Tail...>> {
48};
49
51template <typename... Condition> using EnableIf = typename std::enable_if<All<Condition...>::value, Detail::Enabler>::type;
53template <typename... Condition> using DisableIf = typename std::enable_if<!All<Condition...>::value, Detail::Enabler>::type;
54
56template <typename... Condition> using EnableIfAny = typename std::enable_if<Any<Condition...>::value, Detail::Enabler>::type;
58template <typename... Condition> using DisableIfAny = typename std::enable_if<!Any<Condition...>::value, Detail::Enabler>::type;
59
61namespace Detail {
62template <typename T, template <typename...> class Template> struct IsSpecializationOfHelper : Bool<false> {
63};
64template <template <typename...> class Template, typename... Args> struct IsSpecializationOfHelper<Template<Args...>, Template> : Bool<true> {
65};
66} // namespace Detail
69template <typename Type, template <typename...> class... TemplateTypes>
71 : Detail::IsSpecializationOfHelper<typename std::remove_cv<typename std::remove_reference<Type>::type>::type, TemplateTypes...> {
72};
74template <typename Type, template <typename...> class... TemplateTypes> struct IsSpecializingAnyOf : Bool<false> {
75};
77template <typename Type, template <typename...> class TemplateType, template <typename...> class... RemainingTemplateTypes>
78struct IsSpecializingAnyOf<Type, TemplateType, RemainingTemplateTypes...>
79 : Conditional<IsSpecializationOf<Type, TemplateType>, Bool<true>, IsSpecializingAnyOf<Type, RemainingTemplateTypes...>> {
80};
81
83template <typename... T> struct IsAnyOf : Bool<false> {
84};
86template <typename Type, typename OtherType, typename... RemainingTypes>
87struct IsAnyOf<Type, OtherType, RemainingTypes...> : Conditional<std::is_same<Type, OtherType>, Bool<true>, IsAnyOf<Type, RemainingTypes...>> {
88};
90template <typename... T> struct IsNoneOf : Bool<true> {
91};
93template <typename Type, typename OtherType, typename... RemainingTypes>
94struct IsNoneOf<Type, OtherType, RemainingTypes...> : Conditional<std::is_same<Type, OtherType>, Bool<false>, IsNoneOf<Type, RemainingTypes...>> {
95};
96
98template <typename T>
100 : Bool<std::is_same<char const *, typename std::decay<T>::type>::value || std::is_same<char *, typename std::decay<T>::type>::value> {
101};
104template <typename T>
106 : Bool<IsCString<T>::value || IsSpecializationOf<T, std::basic_string>::value || IsSpecializationOf<T, std::basic_string_view>::value> {
107};
108
110template <typename T, typename = void> struct IsComplete : Bool<false> {
111};
113template <typename T> struct IsComplete<T, decltype(void(sizeof(T)))> : Bool<true> {
114};
115
120#define CPP_UTILITIES_PP_COMMA ,
121
128#define CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(CheckName, CheckCode) \
129 namespace Detail { \
130 template <typename T> auto CheckName(int) -> decltype(CheckCode, ::CppUtilities::Traits::Bool<true>{}); \
131 template <typename T>::CppUtilities::Traits::Bool<false> CheckName(...); \
132 } \
133 template <typename T> using CheckName = decltype(Detail::CheckName<T>(0))
134
136CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsDereferencable, *(std::declval<T &>()));
137
139CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasSize, std::is_integral<decltype(std::declval<T &>().size())>::value);
140
142CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsReservable, std::declval<T &>().reserve(0u));
143
145CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsResizable, std::declval<T &>().resize(0u));
146
148CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasOperatorBool, std::declval<T &>() ? true : false);
149
152 // begin/end and operator !=
153 std::begin(std::declval<T &>())
154 != std::end(std::declval<T &>()) CPP_UTILITIES_PP_COMMA
155 // operator ,
157 // operator ++
158 ++ std::declval<decltype(begin(std::declval<T &>())) &>() CPP_UTILITIES_PP_COMMA
159 // operator*
160 void(*begin(std::declval<T &>())));
161
163template <typename T, EnableIf<IsDereferencable<T>> * = nullptr> constexpr auto &dereferenceMaybe(T &&value)
164{
165 return *value;
166}
167
169template <typename T, DisableIf<IsDereferencable<T>> * = nullptr> constexpr auto &dereferenceMaybe(T &&value)
170{
171 return value;
172}
173
174} // namespace Traits
175
176} // namespace CppUtilities
177
178#endif // CPP_UTILITIES_TRAITS_H
constexpr auto & dereferenceMaybe(T &&value)
Dereferences the specified value if possible; otherwise just returns value itself.
Definition: traits.h:163
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...
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
Shortcut for std::enable_if to omit ::value and ::type.
Definition: traits.h:51
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:56
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:53
typename std::conditional< If::value, Then, Else >::type Conditional
Shortcut for std::conditional to omit ::value and ::type.
Definition: traits.h:20
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:58
Contains all utilities provides by the c++utilities library.
Evaluates to Bool<true> if all specified conditions are true; otherwise evaluates to Bool<false>.
Definition: traits.h:37
Evaluates to Bool<true> if at least one of the specified conditions is true; otherwise evaluates to B...
Definition: traits.h:30
Wraps a static boolean constant.
Definition: traits.h:23
Evaluates to Bool<true> if the specified type is any of the specified types; otherwise evaluates to B...
Definition: traits.h:83
Evaluates to Bool<true> if the specified type is a C-string (char * or const char *); otherwise evalu...
Definition: traits.h:100
Evaluates to Bool<true> if the specified type is complete; if the type is only forward-declared it ev...
Definition: traits.h:110
Evaluates to Bool<true> if the specified type is none of the specified types; otherwise evaluates to ...
Definition: traits.h:90
Evaluates to Bool<true> if the specified type is based on the specified template; otherwise evaluates...
Definition: traits.h:71
Evaluates to Bool<true> if the specified type is based on one of the specified templates; otherwise e...
Definition: traits.h:74
Evaluates to Bool<true> if the specified type is a standard string, standard string view or C-string ...
Definition: traits.h:106
Evaluates to Bool<true> if none of the specified conditions are true; otherwise evaluates to Bool<fal...
Definition: traits.h:44
#define CPP_UTILITIES_PP_COMMA
The CPP_UTILITIES_PP_COMMA macro helps passing "," as a macro argument.
Definition: traits.h:120