#ifndef CPP_UTILITIES_TRAITS_H #define CPP_UTILITIES_TRAITS_H #include #include #include namespace CppUtilities { /// \brief Contains traits for conveniently exploiting SFINAE. namespace Traits { /// \cond namespace Detail { enum class Enabler {}; } /// \endcond /// \brief Shortcut for std::conditional to omit ::value and ::type. template using Conditional = typename std::conditional::type; /// \brief Wraps a static boolean constant. template struct Bool : std::integral_constant {}; /// \brief Negates the specified value. template using Not = Bool; /// \brief Evaluates to Bool if at least one of the specified conditions is true; otherwise evaluates to Bool. template struct Any : Bool {}; /// \brief Evaluates to Bool if at least one of the specified conditions is true; otherwise evaluates to Bool. template struct Any : Conditional, Any> {}; /// \brief Evaluates to Bool if all specified conditions are true; otherwise evaluates to Bool. template struct All : Bool {}; /// \brief Evaluates to Bool if all specified conditions are true; otherwise evaluates to Bool. template struct All : Conditional, Bool> {}; /// \brief Evaluates to Bool if none of the specified conditions are true; otherwise evaluates to Bool. template struct None : Bool {}; /// \brief Evaluates to Bool if none of the specified conditions are true; otherwise evaluates to Bool. template struct None : Conditional, None> {}; /// \brief Shortcut for std::enable_if to omit ::value and ::type. template using EnableIf = typename std::enable_if::value, Detail::Enabler>::type; /// \brief Shortcut for std::enable_if to negate the condition and omit ::value and ::type. template using DisableIf = typename std::enable_if::value, Detail::Enabler>::type; /// \brief Shortcut for std::enable_if to apply Traits::Any and omit ::value and ::type. template using EnableIfAny = typename std::enable_if::value, Detail::Enabler>::type; /// \brief Shortcut for std::enable_if to apply Traits::Any, negate the condition and omit ::value and ::type. template using DisableIfAny = typename std::enable_if::value, Detail::Enabler>::type; /// \cond namespace Detail { template class Template> struct IsSpecializationOfHelper : Bool {}; template