123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- //
- // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/json
- //
- #ifndef BOOST_JSON_DETAIL_VALUE_HPP
- #define BOOST_JSON_DETAIL_VALUE_HPP
- #include <boost/json/kind.hpp>
- #include <boost/json/storage_ptr.hpp>
- #include <cstdint>
- #include <limits>
- #include <new>
- #include <utility>
- BOOST_JSON_NS_BEGIN
- namespace detail {
- struct key_t
- {
- };
- #if 0
- template<class T>
- struct to_number_limit
- : std::numeric_limits<T>
- {
- };
- template<class T>
- struct to_number_limit<T const>
- : to_number_limit<T>
- {
- };
- template<>
- struct to_number_limit<long long>
- {
- static constexpr long long (min)() noexcept
- {
- return -9223372036854774784;
- }
- static constexpr long long (max)() noexcept
- {
- return 9223372036854774784;
- }
- };
- template<>
- struct to_number_limit<unsigned long long>
- {
- static constexpr
- unsigned long long (min)() noexcept
- {
- return 0;
- }
- static constexpr
- unsigned long long (max)() noexcept
- {
- return 18446744073709549568ULL;
- }
- };
- #else
- template<class T>
- class to_number_limit
- {
- // unsigned
- static constexpr
- double min1(std::false_type)
- {
- return 0.0;
- }
- static constexpr
- double max1(std::false_type)
- {
- return max2u(std::integral_constant<
- bool, (std::numeric_limits<T>::max)() ==
- UINT64_MAX>{});
- }
- static constexpr
- double max2u(std::false_type)
- {
- return static_cast<double>(
- (std::numeric_limits<T>::max)());
- }
- static constexpr
- double max2u(std::true_type)
- {
- return 18446744073709549568.0;
- }
- // signed
- static constexpr
- double min1(std::true_type)
- {
- return min2s(std::integral_constant<
- bool, (std::numeric_limits<T>::max)() ==
- INT64_MAX>{});
- }
- static constexpr
- double min2s(std::false_type)
- {
- return static_cast<double>(
- (std::numeric_limits<T>::min)());
- }
- static constexpr
- double min2s(std::true_type)
- {
- return -9223372036854774784.0;
- }
- static constexpr
- double max1(std::true_type)
- {
- return max2s(std::integral_constant<
- bool, (std::numeric_limits<T>::max)() ==
- INT64_MAX>{});
- }
- static constexpr
- double max2s(std::false_type)
- {
- return static_cast<double>(
- (std::numeric_limits<T>::max)());
- }
- static constexpr
- double max2s(std::true_type)
- {
- return 9223372036854774784.0;
- }
- public:
- static constexpr
- double (min)() noexcept
- {
- return min1(std::is_signed<T>{});
- }
- static constexpr
- double (max)() noexcept
- {
- return max1(std::is_signed<T>{});
- }
- };
- #endif
- struct scalar
- {
- storage_ptr sp; // must come first
- kind k; // must come second
- union
- {
- bool b;
- std::int64_t i;
- std::uint64_t u;
- double d;
- };
- explicit
- scalar(storage_ptr sp_ = {}) noexcept
- : sp(std::move(sp_))
- , k(json::kind::null)
- {
- }
- explicit
- scalar(bool b_,
- storage_ptr sp_ = {}) noexcept
- : sp(std::move(sp_))
- , k(json::kind::bool_)
- , b(b_)
- {
- }
- explicit
- scalar(std::int64_t i_,
- storage_ptr sp_ = {}) noexcept
- : sp(std::move(sp_))
- , k(json::kind::int64)
- , i(i_)
- {
- }
- explicit
- scalar(std::uint64_t u_,
- storage_ptr sp_ = {}) noexcept
- : sp(std::move(sp_))
- , k(json::kind::uint64)
- , u(u_)
- {
- }
- explicit
- scalar(double d_,
- storage_ptr sp_ = {}) noexcept
- : sp(std::move(sp_))
- , k(json::kind::double_)
- , d(d_)
- {
- }
- };
- struct access
- {
- template<class Value, class... Args>
- static
- Value&
- construct_value(Value* p, Args&&... args)
- {
- return *reinterpret_cast<
- Value*>(::new(p) Value(
- std::forward<Args>(args)...));
- }
- template<class KeyValuePair, class... Args>
- static
- KeyValuePair&
- construct_key_value_pair(
- KeyValuePair* p, Args&&... args)
- {
- return *reinterpret_cast<
- KeyValuePair*>(::new(p)
- KeyValuePair(
- std::forward<Args>(args)...));
- }
- template<class Value>
- static
- char const*
- release_key(
- Value& jv,
- std::size_t& len) noexcept
- {
- BOOST_ASSERT(jv.is_string());
- jv.str_.sp_.~storage_ptr();
- return jv.str_.impl_.release_key(len);
- }
- using index_t = std::uint32_t;
- template<class KeyValuePair>
- static
- index_t&
- next(KeyValuePair& e) noexcept
- {
- return e.next_;
- }
- template<class KeyValuePair>
- static
- index_t const&
- next(KeyValuePair const& e) noexcept
- {
- return e.next_;
- }
- };
- } // detail
- BOOST_JSON_NS_END
- #endif
|