2016-11-13 22:51:09 +01:00
|
|
|
#ifndef CPP_UTILITIES_TRAITS_H
|
|
|
|
#define CPP_UTILITIES_TRAITS_H
|
|
|
|
|
|
|
|
#include <type_traits>
|
|
|
|
|
2017-02-03 00:54:44 +01:00
|
|
|
/// \brief Contains traits for conveniently exploiting SFINAE.
|
2016-11-13 22:51:09 +01:00
|
|
|
namespace Traits {
|
|
|
|
|
2017-02-03 00:54:44 +01:00
|
|
|
/// \cond
|
2016-11-13 22:51:09 +01:00
|
|
|
namespace Detail {
|
2017-05-01 03:13:11 +02:00
|
|
|
enum class Enabler {};
|
2016-11-13 22:51:09 +01:00
|
|
|
}
|
2017-02-03 00:54:44 +01:00
|
|
|
/// \endcond
|
2016-11-13 22:51:09 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <typename If, typename Then, typename Else> using Conditional = typename std::conditional<If::value, Then, Else>::type;
|
2016-11-13 22:51:09 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <bool B, typename...> struct Bool : std::integral_constant<bool, B> {
|
|
|
|
};
|
2016-11-13 22:51:09 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <typename T> using Not = Bool<!T::value>;
|
2016-11-13 22:51:09 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <typename... T> struct Any : Bool<false> {
|
|
|
|
};
|
2017-05-04 22:44:00 +02:00
|
|
|
template <typename Head, typename... Tail> struct Any<Head, Tail...> : Conditional<Head, Bool<true>, Any<Tail...>> {
|
2017-05-01 03:13:11 +02:00
|
|
|
};
|
2017-01-27 18:49:53 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <typename... T> struct All : Bool<true> {
|
|
|
|
};
|
2017-05-04 22:44:00 +02:00
|
|
|
template <typename Head, typename... Tail> struct All<Head, Tail...> : Conditional<Head, All<Tail...>, Bool<false>> {
|
2017-05-01 03:13:11 +02:00
|
|
|
};
|
2016-11-13 22:51:09 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <typename... Condition> using EnableIf = typename std::enable_if<All<Condition...>::value, Detail::Enabler>::type;
|
|
|
|
template <typename... Condition> using DisableIf = typename std::enable_if<!All<Condition...>::value, Detail::Enabler>::type;
|
2016-11-13 22:51:09 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <typename... Condition> using EnableIfAny = typename std::enable_if<Any<Condition...>::value, Detail::Enabler>::type;
|
|
|
|
template <typename... Condition> using DisableIfAny = typename std::enable_if<!Any<Condition...>::value, Detail::Enabler>::type;
|
2017-01-30 00:08:35 +01:00
|
|
|
|
2017-05-01 03:13:11 +02:00
|
|
|
template <typename T, template <typename...> class Template> struct IsSpecializationOf : Bool<false> {
|
|
|
|
};
|
|
|
|
template <template <typename...> class Template, typename... Args> struct IsSpecializationOf<Template<Args...>, Template> : Bool<true> {
|
|
|
|
};
|
2016-11-13 22:51:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // CPP_UTILITIES_TRAITS_H
|