File indexing completed on 2025-07-15 08:37:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_JSON_DETAIL_VALUE_HPP
0011 #define BOOST_JSON_DETAIL_VALUE_HPP
0012
0013 #include <boost/json/fwd.hpp>
0014 #include <boost/json/kind.hpp>
0015 #include <boost/json/storage_ptr.hpp>
0016 #include <cstdint>
0017 #include <limits>
0018 #include <new>
0019 #include <utility>
0020
0021 namespace boost {
0022 namespace json {
0023 namespace detail {
0024
0025 struct key_t
0026 {
0027 };
0028
0029 #if 0
0030 template<class T>
0031 struct to_number_limit
0032 : std::numeric_limits<T>
0033 {
0034 };
0035
0036 template<class T>
0037 struct to_number_limit<T const>
0038 : to_number_limit<T>
0039 {
0040 };
0041
0042 template<>
0043 struct to_number_limit<long long>
0044 {
0045 static constexpr long long (min)() noexcept
0046 {
0047 return -9223372036854774784;
0048 }
0049
0050 static constexpr long long (max)() noexcept
0051 {
0052 return 9223372036854774784;
0053 }
0054 };
0055
0056 template<>
0057 struct to_number_limit<unsigned long long>
0058 {
0059 static constexpr
0060 unsigned long long (min)() noexcept
0061 {
0062 return 0;
0063 }
0064
0065 static constexpr
0066 unsigned long long (max)() noexcept
0067 {
0068 return 18446744073709549568ULL;
0069 }
0070 };
0071 #else
0072
0073 template<class T>
0074 class to_number_limit
0075 {
0076
0077
0078 static constexpr
0079 double min1(std::false_type)
0080 {
0081 return 0.0;
0082 }
0083
0084 static constexpr
0085 double max1(std::false_type)
0086 {
0087 return max2u(std::integral_constant<
0088 bool, (std::numeric_limits<T>::max)() ==
0089 UINT64_MAX>{});
0090 }
0091
0092 static constexpr
0093 double max2u(std::false_type)
0094 {
0095 return static_cast<double>(
0096 (std::numeric_limits<T>::max)());
0097 }
0098
0099 static constexpr
0100 double max2u(std::true_type)
0101 {
0102 return 18446744073709549568.0;
0103 }
0104
0105
0106
0107 static constexpr
0108 double min1(std::true_type)
0109 {
0110 return min2s(std::integral_constant<
0111 bool, (std::numeric_limits<T>::max)() ==
0112 INT64_MAX>{});
0113 }
0114
0115 static constexpr
0116 double min2s(std::false_type)
0117 {
0118 return static_cast<double>(
0119 (std::numeric_limits<T>::min)());
0120 }
0121
0122 static constexpr
0123 double min2s(std::true_type)
0124 {
0125 return -9223372036854774784.0;
0126 }
0127
0128 static constexpr
0129 double max1(std::true_type)
0130 {
0131 return max2s(std::integral_constant<
0132 bool, (std::numeric_limits<T>::max)() ==
0133 INT64_MAX>{});
0134 }
0135
0136 static constexpr
0137 double max2s(std::false_type)
0138 {
0139 return static_cast<double>(
0140 (std::numeric_limits<T>::max)());
0141 }
0142
0143 static constexpr
0144 double max2s(std::true_type)
0145 {
0146 return 9223372036854774784.0;
0147 }
0148
0149 public:
0150 static constexpr
0151 double (min)() noexcept
0152 {
0153 return min1(std::is_signed<T>{});
0154 }
0155
0156 static constexpr
0157 double (max)() noexcept
0158 {
0159 return max1(std::is_signed<T>{});
0160 }
0161 };
0162
0163 #endif
0164
0165 struct scalar
0166 {
0167 storage_ptr sp;
0168 kind k;
0169 union
0170 {
0171 bool b;
0172 std::int64_t i;
0173 std::uint64_t u;
0174 double d;
0175 };
0176
0177 explicit
0178 scalar(storage_ptr sp_ = {}) noexcept
0179 : sp(std::move(sp_))
0180 , k(json::kind::null)
0181 {
0182 }
0183
0184 explicit
0185 scalar(bool b_,
0186 storage_ptr sp_ = {}) noexcept
0187 : sp(std::move(sp_))
0188 , k(json::kind::bool_)
0189 , b(b_)
0190 {
0191 }
0192
0193 explicit
0194 scalar(std::int64_t i_,
0195 storage_ptr sp_ = {}) noexcept
0196 : sp(std::move(sp_))
0197 , k(json::kind::int64)
0198 , i(i_)
0199 {
0200 }
0201
0202 explicit
0203 scalar(std::uint64_t u_,
0204 storage_ptr sp_ = {}) noexcept
0205 : sp(std::move(sp_))
0206 , k(json::kind::uint64)
0207 , u(u_)
0208 {
0209 }
0210
0211 explicit
0212 scalar(double d_,
0213 storage_ptr sp_ = {}) noexcept
0214 : sp(std::move(sp_))
0215 , k(json::kind::double_)
0216 , d(d_)
0217 {
0218 }
0219 };
0220
0221 struct access
0222 {
0223 template<class Value, class... Args>
0224 static
0225 Value&
0226 construct_value(Value* p, Args&&... args)
0227 {
0228 return *reinterpret_cast<
0229 Value*>(::new(p) Value(
0230 std::forward<Args>(args)...));
0231 }
0232
0233 template<class KeyValuePair, class... Args>
0234 static
0235 KeyValuePair&
0236 construct_key_value_pair(
0237 KeyValuePair* p, Args&&... args)
0238 {
0239 return *reinterpret_cast<
0240 KeyValuePair*>(::new(p)
0241 KeyValuePair(
0242 std::forward<Args>(args)...));
0243 }
0244
0245 template<class Value>
0246 static
0247 char const*
0248 release_key(
0249 Value& jv,
0250 std::size_t& len) noexcept
0251 {
0252 BOOST_ASSERT(jv.is_string());
0253 jv.str_.sp_.~storage_ptr();
0254 return jv.str_.impl_.release_key(len);
0255 }
0256
0257 using index_t = std::uint32_t;
0258
0259 template<class KeyValuePair>
0260 static
0261 index_t&
0262 next(KeyValuePair& e) noexcept
0263 {
0264 return e.next_;
0265 }
0266
0267 template<class KeyValuePair>
0268 static
0269 index_t const&
0270 next(KeyValuePair const& e) noexcept
0271 {
0272 return e.next_;
0273 }
0274 };
0275
0276 BOOST_JSON_DECL
0277 std::size_t
0278 hash_value_impl( value const& jv ) noexcept;
0279
0280 }
0281 }
0282 }
0283
0284 #endif