Commit a6b02828 authored by Théo DELRIEU's avatar Théo DELRIEU

move conjunction/disjunction to the top of detail

parent d566bb81
This diff is collapsed.
...@@ -168,6 +168,25 @@ using is_unscoped_enum = ...@@ -168,6 +168,25 @@ using is_unscoped_enum =
namespace detail namespace detail
{ {
// Implementation of 2 C++17 constructs: conjunction, negation.
// This is needed to avoid evaluating all the traits in a condition
//
// For example: not std::is_same<void, T>::value and has_value_type<T>::value
// will not compile when T = void (on MSVC at least)
// Whereas conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value
// will stop evaluating if negation<...>::value == false
//
// Please note that those constructs must be used with caution, since symbols can
// become very long quickly (which can slow down compilation and cause MSVC internal compiler errors)
// Only use it when you have too (see example ahead)
template <class...> struct conjunction : std::true_type {};
template <class B1> struct conjunction<B1> : B1 {};
template <class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template <class B> struct negation : std::integral_constant < bool, !B::value > {};
template <typename Json> std::string type_name(const Json& j) template <typename Json> std::string type_name(const Json& j)
{ {
switch (j.m_type) switch (j.m_type)
...@@ -317,25 +336,6 @@ struct external_constructor<value_t::object> ...@@ -317,25 +336,6 @@ struct external_constructor<value_t::object>
} }
}; };
// Implementation of 2 C++17 constructs: conjunction, negation.
// This is needed to avoid evaluating all the traits in a condition
//
// For example: not std::is_same<void, T>::value and has_value_type<T>::value
// will not compile when T = void (on MSVC at least)
// Whereas conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value
// will stop evaluating if negation<...>::value == false
//
// Please note that those constructs must be used with caution, since symbols can
// become very long quickly (which can slow down compilation and cause MSVC internal compiler errors)
// Only use it when you have too (see example ahead)
template <class...> struct conjunction : std::true_type {};
template <class B1> struct conjunction<B1> : B1 {};
template <class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template <class B> struct negation : std::integral_constant < bool, !B::value > {};
/*! /*!
@brief Helper to determine whether there's a key_type for T. @brief Helper to determine whether there's a key_type for T.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment