C++ Utilities: misc/traits.h Source File

C++ Utilities 5.34.0 Useful C++ classes and routines such as argument parser, IO and conversion utilities

Loading...
Searching...
No Matches
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
11 namespace Traits {
12
14namespace Detail {
15enum class Enabler {};
16}
18
20 template <typename If, typename Then, typename Else> using Conditional = typename std::conditional<If::value, Then, Else>::type;
21
23 template <bool B, typename...> struct Bool : std::integral_constant<bool, B> {};
24
26 template <typename T> using Not = Bool<!T::value>;
27
29 template <typename... T> struct Any : Bool<false> {};
31 template <typename Head, typename... Tail> struct Any<Head, Tail...> : Conditional<Head, Bool<true>, Any<Tail...>> {};
32
34 template <typename... T> struct All : Bool<true> {};
36 template <typename Head, typename... Tail> struct All<Head, Tail...> : Conditional<Head, All<Tail...>, Bool<false>> {};
37
39 template <typename... T> struct None : Bool<true> {};
41 template <typename Head, typename... Tail> struct None<Head, Tail...> : Conditional<Head, Bool<false>, None<Tail...>> {};
42
44 template <typename... Condition> using EnableIf = typename std::enable_if<All<Condition...>::value, Detail::Enabler>::type;
46 template <typename... Condition> using DisableIf = typename std::enable_if<!All<Condition...>::value, Detail::Enabler>::type;
47
49 template <typename... Condition> using EnableIfAny = typename std::enable_if<Any<Condition...>::value, Detail::Enabler>::type;
51 template <typename... Condition> using DisableIfAny = typename std::enable_if<!Any<Condition...>::value, Detail::Enabler>::type;
52
54namespace Detail {
55template <typename T, template <typename...> class Template> struct IsSpecializationOfHelper : Bool<false> {};
56template <template <typename...> class Template, typename... Args> struct IsSpecializationOfHelper<Template<Args...>, Template> : Bool<true> {};
57} // namespace Detail
60template <typename Type, template <typename...> class... TemplateTypes>
61 struct IsSpecializationOf
62 : Detail::IsSpecializationOfHelper<typename std::remove_cv<typename std::remove_reference<Type>::type>::type, TemplateTypes...> {};
63
64 template <typename Type, template <typename...> class... TemplateTypes> struct IsSpecializingAnyOf : Bool<false> {};
66template <typename Type, template <typename...> class TemplateType, template <typename...> class... RemainingTemplateTypes>
67 struct IsSpecializingAnyOf<Type, TemplateType, RemainingTemplateTypes...>
68 : Conditional<IsSpecializationOf<Type, TemplateType>, Bool<true>, IsSpecializingAnyOf<Type, RemainingTemplateTypes...>> {};
69
71 template <typename... T> struct IsAnyOf : Bool<false> {};
73template <typename Type, typename OtherType, typename... RemainingTypes>
74 struct IsAnyOf<Type, OtherType, RemainingTypes...> : Conditional<std::is_same<Type, OtherType>, Bool<true>, IsAnyOf<Type, RemainingTypes...>> {};
76 template <typename... T> struct IsNoneOf : Bool<true> {};
78template <typename Type, typename OtherType, typename... RemainingTypes>
79 struct IsNoneOf<Type, OtherType, RemainingTypes...> : Conditional<std::is_same<Type, OtherType>, Bool<false>, IsNoneOf<Type, RemainingTypes...>> {};
80
82template <typename T>
83 struct IsCString
84 : Bool<std::is_same<char const *, typename std::decay<T>::type>::value || std::is_same<char *, typename std::decay<T>::type>::value> {};
85
87template <typename T>
88 struct IsString
89 : Bool<IsCString<T>::value || IsSpecializationOf<T, std::basic_string>::value || IsSpecializationOf<T, std::basic_string_view>::value> {};
90
92 template <typename T, typename = void> struct IsComplete : Bool<false> {};
94 template <typename T> struct IsComplete<T, decltype(void(sizeof(T)))> : Bool<true> {};
95
100#define CPP_UTILITIES_PP_COMMA ,
101
108#define CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(CheckName, CheckCode) \
109 namespace Detail { \
110 template <typename T> auto CheckName(int) -> decltype(CheckCode, ::CppUtilities::Traits::Bool<true>{}); \
111 template <typename T>::CppUtilities::Traits::Bool<false> CheckName(...); \
112 } \
113 template <typename T> using CheckName = decltype(Detail::CheckName<T>(0))
114
116 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsDereferencable, *(std::declval<T &>()));
117
119 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasSize, std::is_integral<decltype(std::declval<T &>().size())>::value);
120
122 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsReservable, std::declval<T &>().reserve(0u));
123
125 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsResizable, std::declval<T &>().resize(0u));
126
128 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(HasOperatorBool, std::declval<T &>() ? true : false);
129
131 CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(IsIteratable,
132 // begin/end and operator !=
133 std::begin(std::declval<T &>())
134 != std::end(std::declval<T &>()) CPP_UTILITIES_PP_COMMA
135 // operator ,
136 void() CPP_UTILITIES_PP_COMMA
137 // operator ++
138 ++ std::declval<decltype(begin(std::declval<T &>())) &>() CPP_UTILITIES_PP_COMMA
139 // operator*
140 void(*begin(std::declval<T &>())));
141
143 template <typename T, EnableIf<IsDereferencable<T>> * = nullptr> constexpr auto &dereferenceMaybe(T &&value)
144{
145 return *value;
146}
147
149 template <typename T, DisableIf<IsDereferencable<T>> * = nullptr> constexpr auto &dereferenceMaybe(T &&value)
150{
151 return value;
152}
153
154} // namespace Traits
155
156} // namespace CppUtilities
157
158#endif // CPP_UTILITIES_TRAITS_H
CppUtilities::Detail
Definition verification.h:19
CppUtilities::Traits
Contains traits for conveniently exploiting SFINAE.
Definition traits.h:11
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:46
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:49
CppUtilities::Traits::dereferenceMaybe
constexpr auto & dereferenceMaybe(T &&value)
Dereferences the specified value if possible; otherwise just returns value itself.
Definition traits.h:143
CppUtilities::Traits::Conditional
typename std::conditional< If::value, Then, Else >::type Conditional
Shortcut for std::conditional to omit value and type.
Definition traits.h:20
CppUtilities::Traits::Not
Bool<!T::value > Not
Negates the specified value.
Definition traits.h:26
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:44
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:51
CppUtilities
Contains all utilities provided by the c++utilities library.
Definition argumentparser.h:18
CppUtilities::Traits::All
Evaluates to Bool<true> if all specified conditions are true; otherwise evaluates to Bool<false>.
Definition traits.h:34
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::Bool
Wraps a static boolean constant.
Definition traits.h:23
CppUtilities::Traits::IsAnyOf
Evaluates to Bool<true> if the specified type is any of the specified types; otherwise evaluates to B...
Definition traits.h:71
CppUtilities::Traits::IsCString
Evaluates to Bool<true> if the specified type is a C-string (char * or const char *); otherwise evalu...
Definition traits.h:84
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:92
CppUtilities::Traits::IsNoneOf
Evaluates to Bool<true> if the specified type is none of the specified types; otherwise evaluates to ...
Definition traits.h:76
CppUtilities::Traits::IsSpecializationOf
Evaluates to Bool<true> if the specified type is based on the specified template; otherwise evaluates...
Definition traits.h:62
CppUtilities::Traits::IsSpecializingAnyOf
Evaluates to Bool<true> if the specified type is based on one of the specified templates; otherwise e...
Definition traits.h:64
CppUtilities::Traits::IsString
Evaluates to Bool<true> if the specified type is a standard string, standard string view or C-string ...
Definition traits.h:89
CppUtilities::Traits::None
Evaluates to Bool<true> if none of the specified conditions are true; otherwise evaluates to Bool<fal...
Definition traits.h:39
CPP_UTILITIES_PP_COMMA
#define CPP_UTILITIES_PP_COMMA
The CPP_UTILITIES_PP_COMMA macro helps passing "," as a macro argument.
Definition traits.h:100
CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK
#define CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(CheckName, CheckCode)
The CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK macro defines a type trait for checking whether some opera...
Definition traits.h:108