From d3f72b1b9ca6db536419b2972b65349e666c4c09 Mon Sep 17 00:00:00 2001 From: Alexander Karzhenkov Date: Sun, 8 Jan 2023 17:35:08 +0500 Subject: [PATCH] Use macros when comparing optional --- include/nlohmann/optional.hpp | 170 ++++++------------------------- single_include/nlohmann/json.hpp | 170 ++++++------------------------- 2 files changed, 66 insertions(+), 274 deletions(-) diff --git a/include/nlohmann/optional.hpp b/include/nlohmann/optional.hpp index dee4d4b5b4..d7cd210cea 100644 --- a/include/nlohmann/optional.hpp +++ b/include/nlohmann/optional.hpp @@ -170,160 +170,56 @@ template const std::optional& cmp_val(const optional& v) { return v.base(); } -template void cmp_val(const std::optional& v) = delete; } // 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 -auto operator == (const optional& 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); -} +#define JSON_OPTIONAL_COMPARISON(OP, LHS, RHS) \ + template \ + auto operator OP (const LHS& lhs, const RHS& rhs) \ + noexcept(noexcept(JSON_OPTIONAL_COMPARISON_EXPR(OP))) \ + -> decltype(JSON_OPTIONAL_COMPARISON_EXPR(OP)) \ + { \ + return JSON_OPTIONAL_COMPARISON_EXPR(OP); \ + } + +#ifdef JSON_HAS_CPP_20 // *INDENT-OFF* -template -auto operator <=> (const optional& 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); -} +JSON_OPTIONAL_COMPARISON( <=>, optional, B) // *INDENT-ON* -#else // JSON_HAS_CPP_20 - -template -constexpr auto operator == (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); -} +JSON_OPTIONAL_COMPARISON( ==, optional, B) +JSON_OPTIONAL_COMPARISON( ==, optional, std::optional) +JSON_OPTIONAL_COMPARISON( ==, std::optional, optional) -template -constexpr auto operator == (const optional& 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 -constexpr auto operator == (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator != (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator != (const optional& 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 -constexpr auto operator != (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator < (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator < (const optional& 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 -constexpr auto operator < (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator <= (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator <= (const optional& 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 -constexpr auto operator <= (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator > (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs); -} +#else // JSON_HAS_CPP_20 -template -constexpr auto operator > (const optional& 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); -} +#define JSON_OPTIONAL_COMPARISON_OP(OP) \ + JSON_OPTIONAL_COMPARISON(OP, optional, optional) \ + JSON_OPTIONAL_COMPARISON(OP, optional, std::optional) \ + JSON_OPTIONAL_COMPARISON(OP, std::optional, optional) \ + JSON_OPTIONAL_COMPARISON(OP, optional, B) \ + JSON_OPTIONAL_COMPARISON(OP, A, optional) -template -constexpr auto operator > (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs); -} +JSON_OPTIONAL_COMPARISON_OP( == ) +JSON_OPTIONAL_COMPARISON_OP( != ) +JSON_OPTIONAL_COMPARISON_OP( < ) +JSON_OPTIONAL_COMPARISON_OP( <= ) +JSON_OPTIONAL_COMPARISON_OP( > ) +JSON_OPTIONAL_COMPARISON_OP( >= ) -template -constexpr auto operator >= (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator >= (const optional& 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 -constexpr auto operator >= (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs); -} +#undef JSON_OPTIONAL_COMPARISON_OP #endif // JSON_HAS_CPP_20 +#undef JSON_OPTIONAL_COMPARISON +#undef JSON_OPTIONAL_COMPARISON_EXPR + NLOHMANN_JSON_NAMESPACE_END #endif // JSON_HAS_CPP_17 diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index b2d4f1e483..67bc932aaa 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -4762,160 +4762,56 @@ template const std::optional& cmp_val(const optional& v) { return v.base(); } -template void cmp_val(const std::optional& v) = delete; } // 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 -auto operator == (const optional& 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); -} +#define JSON_OPTIONAL_COMPARISON(OP, LHS, RHS) \ + template \ + auto operator OP (const LHS& lhs, const RHS& rhs) \ + noexcept(noexcept(JSON_OPTIONAL_COMPARISON_EXPR(OP))) \ + -> decltype(JSON_OPTIONAL_COMPARISON_EXPR(OP)) \ + { \ + return JSON_OPTIONAL_COMPARISON_EXPR(OP); \ + } + +#ifdef JSON_HAS_CPP_20 // *INDENT-OFF* -template -auto operator <=> (const optional& 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); -} +JSON_OPTIONAL_COMPARISON( <=>, optional, B) // *INDENT-ON* -#else // JSON_HAS_CPP_20 - -template -constexpr auto operator == (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); -} +JSON_OPTIONAL_COMPARISON( ==, optional, B) +JSON_OPTIONAL_COMPARISON( ==, optional, std::optional) +JSON_OPTIONAL_COMPARISON( ==, std::optional, optional) -template -constexpr auto operator == (const optional& 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 -constexpr auto operator == (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) == detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator != (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator != (const optional& 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 -constexpr auto operator != (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) != detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator < (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator < (const optional& 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 -constexpr auto operator < (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) < detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator <= (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator <= (const optional& 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 -constexpr auto operator <= (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) <= detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator > (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs); -} +#else // JSON_HAS_CPP_20 -template -constexpr auto operator > (const optional& 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); -} +#define JSON_OPTIONAL_COMPARISON_OP(OP) \ + JSON_OPTIONAL_COMPARISON(OP, optional, optional) \ + JSON_OPTIONAL_COMPARISON(OP, optional, std::optional) \ + JSON_OPTIONAL_COMPARISON(OP, std::optional, optional) \ + JSON_OPTIONAL_COMPARISON(OP, optional, B) \ + JSON_OPTIONAL_COMPARISON(OP, A, optional) -template -constexpr auto operator > (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) > detail::opt::cmp_val(rhs); -} +JSON_OPTIONAL_COMPARISON_OP( == ) +JSON_OPTIONAL_COMPARISON_OP( != ) +JSON_OPTIONAL_COMPARISON_OP( < ) +JSON_OPTIONAL_COMPARISON_OP( <= ) +JSON_OPTIONAL_COMPARISON_OP( > ) +JSON_OPTIONAL_COMPARISON_OP( >= ) -template -constexpr auto operator >= (const optional& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs); -} - -template -constexpr auto operator >= (const optional& 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 -constexpr auto operator >= (const T& lhs, const optional& rhs) -> -decltype(detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs)) -{ - return detail::opt::cmp_val(lhs) >= detail::opt::cmp_val(rhs); -} +#undef JSON_OPTIONAL_COMPARISON_OP #endif // JSON_HAS_CPP_20 +#undef JSON_OPTIONAL_COMPARISON +#undef JSON_OPTIONAL_COMPARISON_EXPR + NLOHMANN_JSON_NAMESPACE_END #endif // JSON_HAS_CPP_17