Use macros when comparing optional

This commit is contained in:
Alexander Karzhenkov 2023-01-08 17:35:08 +05:00
parent 7745f5987a
commit d3f72b1b9c
2 changed files with 66 additions and 274 deletions

View File

@ -170,160 +170,56 @@ template <typename T> const std::optional<T>& cmp_val(const optional<T>& v)
{ {
return v.base(); return v.base();
} }
template <typename T> void cmp_val(const std::optional<T>& v) = delete;
} // namespace detail::opt } // namespace detail::opt
#ifdef JSON_HAS_CPP_20 #define JSON_OPTIONAL_COMPARISON_EXPR(OP) \
detail::opt::cmp_val(lhs) OP detail::opt::cmp_val(rhs)
template <typename T, typename U> #define JSON_OPTIONAL_COMPARISON(OP, LHS, RHS) \
auto operator == (const optional<T>& lhs, const U& rhs) -> template <typename A, typename B> \
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) auto operator OP (const LHS& lhs, const RHS& rhs) \
{ noexcept(noexcept(JSON_OPTIONAL_COMPARISON_EXPR(OP))) \
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); -> decltype(JSON_OPTIONAL_COMPARISON_EXPR(OP)) \
} { \
return JSON_OPTIONAL_COMPARISON_EXPR(OP); \
}
#ifdef JSON_HAS_CPP_20
// *INDENT-OFF* // *INDENT-OFF*
template <typename T, typename U> JSON_OPTIONAL_COMPARISON( <=>, optional<A>, B)
auto operator <=> (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) <=> detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <=> detail::opt::cmp_val(rhs);
}
// *INDENT-ON* // *INDENT-ON*
JSON_OPTIONAL_COMPARISON( ==, optional<A>, B)
JSON_OPTIONAL_COMPARISON( ==, optional<A>, std::optional<B>)
JSON_OPTIONAL_COMPARISON( ==, std::optional<A>, optional<B>)
#else // JSON_HAS_CPP_20 #else // JSON_HAS_CPP_20
template<class T, class U> #define JSON_OPTIONAL_COMPARISON_OP(OP) \
constexpr auto operator == (const optional<T>& lhs, const optional<U>& rhs) -> JSON_OPTIONAL_COMPARISON(OP, optional<A>, optional<B>) \
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) JSON_OPTIONAL_COMPARISON(OP, optional<A>, std::optional<B>) \
{ JSON_OPTIONAL_COMPARISON(OP, std::optional<A>, optional<B>) \
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); JSON_OPTIONAL_COMPARISON(OP, optional<A>, B) \
} JSON_OPTIONAL_COMPARISON(OP, A, optional<B>)
template <class T, class U> JSON_OPTIONAL_COMPARISON_OP( == )
constexpr auto operator == (const optional<T>& lhs, const U& rhs) -> JSON_OPTIONAL_COMPARISON_OP( != )
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) JSON_OPTIONAL_COMPARISON_OP( < )
{ JSON_OPTIONAL_COMPARISON_OP( <= )
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); JSON_OPTIONAL_COMPARISON_OP( > )
} JSON_OPTIONAL_COMPARISON_OP( >= )
template <class T, class U> #undef JSON_OPTIONAL_COMPARISON_OP
constexpr auto operator == (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator != (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator != (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator != (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator < (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator < (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator < (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator <= (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator <= (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator <= (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator > (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator > (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator > (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator >= (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator >= (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator >= (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs);
}
#endif // JSON_HAS_CPP_20 #endif // JSON_HAS_CPP_20
#undef JSON_OPTIONAL_COMPARISON
#undef JSON_OPTIONAL_COMPARISON_EXPR
NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_END
#endif // JSON_HAS_CPP_17 #endif // JSON_HAS_CPP_17

View File

@ -4762,160 +4762,56 @@ template <typename T> const std::optional<T>& cmp_val(const optional<T>& v)
{ {
return v.base(); return v.base();
} }
template <typename T> void cmp_val(const std::optional<T>& v) = delete;
} // namespace detail::opt } // namespace detail::opt
#ifdef JSON_HAS_CPP_20 #define JSON_OPTIONAL_COMPARISON_EXPR(OP) \
detail::opt::cmp_val(lhs) OP detail::opt::cmp_val(rhs)
template <typename T, typename U> #define JSON_OPTIONAL_COMPARISON(OP, LHS, RHS) \
auto operator == (const optional<T>& lhs, const U& rhs) -> template <typename A, typename B> \
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) auto operator OP (const LHS& lhs, const RHS& rhs) \
{ noexcept(noexcept(JSON_OPTIONAL_COMPARISON_EXPR(OP))) \
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); -> decltype(JSON_OPTIONAL_COMPARISON_EXPR(OP)) \
} { \
return JSON_OPTIONAL_COMPARISON_EXPR(OP); \
}
#ifdef JSON_HAS_CPP_20
// *INDENT-OFF* // *INDENT-OFF*
template <typename T, typename U> JSON_OPTIONAL_COMPARISON( <=>, optional<A>, B)
auto operator <=> (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) <=> detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <=> detail::opt::cmp_val(rhs);
}
// *INDENT-ON* // *INDENT-ON*
JSON_OPTIONAL_COMPARISON( ==, optional<A>, B)
JSON_OPTIONAL_COMPARISON( ==, optional<A>, std::optional<B>)
JSON_OPTIONAL_COMPARISON( ==, std::optional<A>, optional<B>)
#else // JSON_HAS_CPP_20 #else // JSON_HAS_CPP_20
template<class T, class U> #define JSON_OPTIONAL_COMPARISON_OP(OP) \
constexpr auto operator == (const optional<T>& lhs, const optional<U>& rhs) -> JSON_OPTIONAL_COMPARISON(OP, optional<A>, optional<B>) \
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) JSON_OPTIONAL_COMPARISON(OP, optional<A>, std::optional<B>) \
{ JSON_OPTIONAL_COMPARISON(OP, std::optional<A>, optional<B>) \
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); JSON_OPTIONAL_COMPARISON(OP, optional<A>, B) \
} JSON_OPTIONAL_COMPARISON(OP, A, optional<B>)
template <class T, class U> JSON_OPTIONAL_COMPARISON_OP( == )
constexpr auto operator == (const optional<T>& lhs, const U& rhs) -> JSON_OPTIONAL_COMPARISON_OP( != )
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) JSON_OPTIONAL_COMPARISON_OP( < )
{ JSON_OPTIONAL_COMPARISON_OP( <= )
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); JSON_OPTIONAL_COMPARISON_OP( > )
} JSON_OPTIONAL_COMPARISON_OP( >= )
template <class T, class U> #undef JSON_OPTIONAL_COMPARISON_OP
constexpr auto operator == (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator != (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator != (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator != (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator < (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator < (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator < (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator <= (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator <= (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator <= (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator > (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator > (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator > (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs);
}
template<class T, class U>
constexpr auto operator >= (const optional<T>& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator >= (const optional<T>& lhs, const U& rhs) ->
decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs);
}
template <class T, class U>
constexpr auto operator >= (const T& lhs, const optional<U>& rhs) ->
decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs))
{
return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs);
}
#endif // JSON_HAS_CPP_20 #endif // JSON_HAS_CPP_20
#undef JSON_OPTIONAL_COMPARISON
#undef JSON_OPTIONAL_COMPARISON_EXPR
NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_END
#endif // JSON_HAS_CPP_17 #endif // JSON_HAS_CPP_17