1 #ifndef CPP_UTILITIES_TRAITS_H 2 #define CPP_UTILITIES_TRAITS_H 12 enum class Enabler {};
17 template <
typename If,
typename Then,
typename Else>
using Conditional =
typename std::conditional<If::value, Then, Else>::type;
20 template <
bool B,
typename...>
struct Bool : std::integral_constant<bool, B> {
27 template <
typename... T>
struct Any :
Bool<false> {
30 template <
typename Head,
typename... Tail>
struct Any<Head, Tail...> :
Conditional<Head, Bool<true>, Any<Tail...>> {
34 template <
typename... T>
struct All :
Bool<true> {
37 template <
typename Head,
typename... Tail>
struct All<Head, Tail...> :
Conditional<Head, All<Tail...>, Bool<false>> {
41 template <
typename... T>
struct None :
Bool<true> {
44 template <
typename Head,
typename... Tail>
struct None<Head, Tail...> :
Conditional<Head, Bool<false>, None<Tail...>> {
48 template <
typename... Condition>
using EnableIf =
typename std::enable_if<
All<Condition...>::value, Detail::Enabler>::type;
50 template <
typename... Condition>
using DisableIf =
typename std::enable_if<!
All<Condition...>::value, Detail::Enabler>::type;
53 template <
typename... Condition>
using EnableIfAny =
typename std::enable_if<
Any<Condition...>::value, Detail::Enabler>::type;
55 template <
typename... Condition>
using DisableIfAny =
typename std::enable_if<!
Any<Condition...>::value, Detail::Enabler>::type;
59 template <
typename T,
template <
typename...>
class Template>
struct IsSpecializationOfHelper :
Bool<false> {
61 template <
template <
typename...>
class Template,
typename... Args>
struct IsSpecializationOfHelper<Template<Args...>, Template> :
Bool<true> {
66 template <
typename Type,
template <
typename...>
class... TemplateTypes>
67 struct IsSpecializationOf : Detail::IsSpecializationOfHelper<typename std::remove_cv<Type>::type, TemplateTypes...> {
73 template <
typename Type,
template <
typename...>
class TemplateType,
template <
typename...>
class... RemainingTemplateTypes>
75 :
Conditional<IsSpecializationOf<Type, TemplateType>, Bool<true>, IsSpecializingAnyOf<Type, RemainingTemplateTypes...>> {
82 template <
typename Type,
typename OtherType,
typename... RemainingTypes>
83 struct IsAnyOf<Type, OtherType, RemainingTypes...> :
Conditional<std::is_same<Type, OtherType>, Bool<true>, IsAnyOf<Type, RemainingTypes...>> {
89 template <
typename Type,
typename OtherType,
typename... RemainingTypes>
90 struct IsNoneOf<Type, OtherType, RemainingTypes...> :
Conditional<std::is_same<Type, OtherType>, Bool<false>, IsNoneOf<Type, RemainingTypes...>> {
96 :
Bool<std::is_same<char const *, typename std::decay<T>::type>::value || std::is_same<char *, typename std::decay<T>::type>::value> {
99 template <
typename T>
struct IsString :
Bool<IsCString<T>::value || IsSpecializationOf<T, std::basic_string>::value> {
106 template <
typename T>
struct IsComplete<T, decltype(void(sizeof(T)))> :
Bool<true> {
113 #define CPP_UTILITIES_PP_COMMA , 121 #define CPP_UTILITIES_TRAITS_DEFINE_TYPE_CHECK(CheckName, CheckCode) \ 123 template <typename T> auto CheckName(int) -> decltype(CheckCode, ::Traits::Bool<true>{}); \ 124 template <typename T>::Traits::Bool<false> CheckName(...); \ 126 template <typename T> using CheckName = decltype(Detail::CheckName<T>(0)) 146 std::begin(std::declval<T &>())
153 void(*begin(std::declval<T &>())));
156 template <
typename T, EnableIf<IsDereferencable<T>> * =
nullptr> constexpr
auto &
dereferenceMaybe(T &value)
162 template <
typename T, DisableIf<IsDereferencable<T>> * =
nullptr> constexpr
auto &
dereferenceMaybe(T &value)
168 template <
typename T, EnableIf<IsDereferencable<T>> * =
nullptr> constexpr
const auto &
dereferenceMaybe(
const T &value)
174 template <
typename T, DisableIf<IsDereferencable<T>> * =
nullptr> constexpr
const auto &
dereferenceMaybe(
const T &value)
181 #endif // CPP_UTILITIES_TRAITS_H constexpr auto & dereferenceMaybe(T &value)
Dereferences the specified value if possible; otherwise just returns value itself.
Evaluates to Bool<true> if the specified type is any of the specified types; otherwise evaluates to B...
Evaluates to Bool<true> if the specified type is based on the specified.
Evaluates to Bool<true> if the specified type is complete; if the type is only forward-declared it ev...
Evaluates to Bool<true> if all specified conditions are true; otherwise evaluates to Bool<false>.
Evaluates to Bool<true> if the specified type is based on one of the specified templates; otherwise e...
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
Shortcut for std::enable_if to omit ::value and ::type.
Evaluates to Bool<true> if the specified type is a C-string (char * or const char *); otherwise evalu...
#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
Shortcut for std::conditional to omit ::value and ::type.
Evaluates to Bool<true> if the specified type is none of the specified types; otherwise evaluates to ...
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.
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.
Evaluates to Bool<true> if at least one of the specified conditions is true; otherwise evaluates to B...
Evaluates to Bool<true> if the specified type is a C-string (char * or const char *); otherwise evalu...
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.
Evaluates to Bool<true> if none of the specified conditions are true; otherwise evaluates to Bool<fal...
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...
Contains traits for conveniently exploiting SFINAE.
Wraps a static boolean constant.