#pragma once #include #ifdef JSON_HAS_CPP_17 #include #include NLOHMANN_JSON_NAMESPACE_BEGIN template class optional { // *INDENT-OFF* using base_type = std::optional; using value_type = T; template struct has_conversion_operator : std::false_type { }; template struct has_conversion_operator().operator optional())> : std::true_type { }; template using is_base_constructible_from = std::is_constructible; template using is_convertible_to_base = std::is_convertible; template using enable_int_if = std::enable_if_t; template using use_conversion_operator = enable_int_if< has_conversion_operator >; template using use_implicit_forwarding = enable_int_if< std::conjunction< std::negation>, is_base_constructible_from, is_convertible_to_base > >; template using use_explicit_forwarding = enable_int_if< std::conjunction< std::negation>, is_base_constructible_from, std::negation> > >; template using can_construct_in_place_from = enable_int_if< is_base_constructible_from >; struct noexcept_fix_t {}; // trick for GCC8.1 (see default constructor) base_type base_value; public: base_type& base() & noexcept { return base_value; } const base_type& base() const & noexcept { return base_value; } base_type&& base() && noexcept { return std::move(base_value); } constexpr optional() noexcept(noexcept(std::optional())) : base_value() // explicitly initialized to mitigate -Werror=effc++ { } constexpr optional(std::nullopt_t /* unused */) noexcept : base_value(std::nullopt) { } template = 0> constexpr optional(U&& value) noexcept(noexcept( base_type(std::forward(value).operator optional()) )) : base_value(std::forward(value).operator optional()) { } template = 0> constexpr optional(U&& value) noexcept(noexcept( base_type(std::forward(value)) )) : base_value(std::forward(value)) { } template = 0> explicit constexpr optional(U&& value) noexcept(noexcept( base_type(std::forward(value)) )) : base_value(std::forward(value)) { } template = 0> explicit constexpr optional(std::in_place_t /* unused */, U&& u, Args&&... args) noexcept(noexcept( base_type(std::in_place, std::forward(u), std::forward(args)...) )) : base_value(std::in_place, std::forward(u), std::forward(args)...) { } template &, Args...> = 0> explicit constexpr optional(std::in_place_t /* unused */, std::initializer_list u, Args&&... args) noexcept(noexcept( base_type(std::in_place, u, std::forward(args)...) )) : base_value(std::in_place, u, std::forward(args)...) { } constexpr T& operator *() & noexcept { return *base_value; } constexpr const T& operator *() const& noexcept { return *base_value; } constexpr T&& operator *() && noexcept { return static_cast(*base_value); } constexpr const T&& operator *() const&& noexcept { return static_cast(*base_value); } constexpr T* operator ->() noexcept { return base_value.operator ->(); } constexpr const T* operator ->() const noexcept { return base_value.operator ->(); } operator base_type& () & noexcept { return base_value; } operator base_type&& () && noexcept { return std::move(base_value); } // *INDENT-ON* }; namespace detail::opt { template const T& cmp_val(const T& v) { return v; } template const std::optional& cmp_val(const optional& v) { return v.base(); } } // namespace detail::opt #define JSON_OPTIONAL_COMPARISON_EXPR(OP) \ detail::opt::cmp_val(lhs) OP detail::opt::cmp_val(rhs) #define JSON_OPTIONAL_COMPARISON(OP, LHS, RHS) \ template \ auto operator OP (const LHS& lhs, const RHS& rhs) \ -> decltype(JSON_OPTIONAL_COMPARISON_EXPR(OP)) \ { \ return JSON_OPTIONAL_COMPARISON_EXPR(OP); \ } #ifdef JSON_HAS_CPP_20 // *INDENT-OFF* JSON_OPTIONAL_COMPARISON( <=>, optional, B) // *INDENT-ON* JSON_OPTIONAL_COMPARISON( ==, optional, B) JSON_OPTIONAL_COMPARISON( ==, optional, std::optional) JSON_OPTIONAL_COMPARISON( ==, std::optional, optional) #else // JSON_HAS_CPP_20 #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) JSON_OPTIONAL_COMPARISON_OP( == ) JSON_OPTIONAL_COMPARISON_OP( != ) JSON_OPTIONAL_COMPARISON_OP( < ) JSON_OPTIONAL_COMPARISON_OP( <= ) JSON_OPTIONAL_COMPARISON_OP( > ) JSON_OPTIONAL_COMPARISON_OP( >= ) #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