100.00% Lines (65/65) 100.00% Functions (22/22)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/boostorg/json 7   // Official repository: https://github.com/boostorg/json
8   // 8   //
9   9  
10   #ifndef BOOST_JSON_DETAIL_VALUE_HPP 10   #ifndef BOOST_JSON_DETAIL_VALUE_HPP
11   #define BOOST_JSON_DETAIL_VALUE_HPP 11   #define BOOST_JSON_DETAIL_VALUE_HPP
12   12  
13   #include <boost/json/fwd.hpp> 13   #include <boost/json/fwd.hpp>
14   #include <boost/json/kind.hpp> 14   #include <boost/json/kind.hpp>
15   #include <boost/json/storage_ptr.hpp> 15   #include <boost/json/storage_ptr.hpp>
16   #include <cstdint> 16   #include <cstdint>
17   #include <limits> 17   #include <limits>
18   #include <new> 18   #include <new>
19   #include <utility> 19   #include <utility>
20   20  
21   namespace boost { 21   namespace boost {
22   namespace json { 22   namespace json {
23   namespace detail { 23   namespace detail {
24   24  
25   struct key_t 25   struct key_t
26   { 26   {
27   }; 27   };
28   28  
29   #if 0 29   #if 0
30   template<class T> 30   template<class T>
31   struct to_number_limit 31   struct to_number_limit
32   : std::numeric_limits<T> 32   : std::numeric_limits<T>
33   { 33   {
34   }; 34   };
35   35  
36   template<class T> 36   template<class T>
37   struct to_number_limit<T const> 37   struct to_number_limit<T const>
38   : to_number_limit<T> 38   : to_number_limit<T>
39   { 39   {
40   }; 40   };
41   41  
42   template<> 42   template<>
43   struct to_number_limit<long long> 43   struct to_number_limit<long long>
44   { 44   {
45   static constexpr long long (min)() noexcept 45   static constexpr long long (min)() noexcept
46   { 46   {
47   return -9223372036854774784; 47   return -9223372036854774784;
48   } 48   }
49   49  
50   static constexpr long long (max)() noexcept 50   static constexpr long long (max)() noexcept
51   { 51   {
52   return 9223372036854774784; 52   return 9223372036854774784;
53   } 53   }
54   }; 54   };
55   55  
56   template<> 56   template<>
57   struct to_number_limit<unsigned long long> 57   struct to_number_limit<unsigned long long>
58   { 58   {
59   static constexpr 59   static constexpr
60   unsigned long long (min)() noexcept 60   unsigned long long (min)() noexcept
61   { 61   {
62   return 0; 62   return 0;
63   } 63   }
64   64  
65   static constexpr 65   static constexpr
66   unsigned long long (max)() noexcept 66   unsigned long long (max)() noexcept
67   { 67   {
68   return 18446744073709549568ULL; 68   return 18446744073709549568ULL;
69   } 69   }
70   }; 70   };
71   #else 71   #else
72   72  
73   template<class T> 73   template<class T>
74   class to_number_limit 74   class to_number_limit
75   { 75   {
76   // unsigned 76   // unsigned
77   77  
78   static constexpr 78   static constexpr
79   double min1(std::false_type) 79   double min1(std::false_type)
80   { 80   {
81   return 0.0; 81   return 0.0;
82   } 82   }
83   83  
84   static constexpr 84   static constexpr
HITCBC 85   8 double max1(std::false_type) 85   8 double max1(std::false_type)
86   { 86   {
HITCBC 87   8 return max2u(std::integral_constant< 87   8 return max2u(std::integral_constant<
88   bool, (std::numeric_limits<T>::max)() == 88   bool, (std::numeric_limits<T>::max)() ==
HITCBC 89   8 UINT64_MAX>{}); 89   8 UINT64_MAX>{});
90   } 90   }
91   91  
92   static constexpr 92   static constexpr
HITCBC 93   6 double max2u(std::false_type) 93   6 double max2u(std::false_type)
94   { 94   {
95   return static_cast<double>( 95   return static_cast<double>(
HITCBC 96   6 (std::numeric_limits<T>::max)()); 96   6 (std::numeric_limits<T>::max)());
97   } 97   }
98   98  
99   static constexpr 99   static constexpr
HITCBC 100   2 double max2u(std::true_type) 100   2 double max2u(std::true_type)
101   { 101   {
HITCBC 102   2 return 18446744073709549568.0; 102   2 return 18446744073709549568.0;
103   } 103   }
104   104  
105   // signed 105   // signed
106   106  
107   static constexpr 107   static constexpr
HITCBC 108   20 double min1(std::true_type) 108   20 double min1(std::true_type)
109   { 109   {
HITCBC 110   20 return min2s(std::integral_constant< 110   20 return min2s(std::integral_constant<
111   bool, (std::numeric_limits<T>::max)() == 111   bool, (std::numeric_limits<T>::max)() ==
HITCBC 112   20 INT64_MAX>{}); 112   20 INT64_MAX>{});
113   } 113   }
114   114  
115   static constexpr 115   static constexpr
HITCBC 116   17 double min2s(std::false_type) 116   17 double min2s(std::false_type)
117   { 117   {
118   return static_cast<double>( 118   return static_cast<double>(
HITCBC 119   17 (std::numeric_limits<T>::min)()); 119   17 (std::numeric_limits<T>::min)());
120   } 120   }
121   121  
122   static constexpr 122   static constexpr
HITCBC 123   3 double min2s(std::true_type) 123   3 double min2s(std::true_type)
124   { 124   {
HITCBC 125   3 return -9223372036854774784.0; 125   3 return -9223372036854774784.0;
126   } 126   }
127   127  
128   static constexpr 128   static constexpr
HITCBC 129   20 double max1(std::true_type) 129   20 double max1(std::true_type)
130   { 130   {
HITCBC 131   20 return max2s(std::integral_constant< 131   20 return max2s(std::integral_constant<
132   bool, (std::numeric_limits<T>::max)() == 132   bool, (std::numeric_limits<T>::max)() ==
HITCBC 133   20 INT64_MAX>{}); 133   20 INT64_MAX>{});
134   } 134   }
135   135  
136   static constexpr 136   static constexpr
HITCBC 137   17 double max2s(std::false_type) 137   17 double max2s(std::false_type)
138   { 138   {
139   return static_cast<double>( 139   return static_cast<double>(
HITCBC 140   17 (std::numeric_limits<T>::max)()); 140   17 (std::numeric_limits<T>::max)());
141   } 141   }
142   142  
143   static constexpr 143   static constexpr
HITCBC 144   3 double max2s(std::true_type) 144   3 double max2s(std::true_type)
145   { 145   {
HITCBC 146   3 return 9223372036854774784.0; 146   3 return 9223372036854774784.0;
147   } 147   }
148   148  
149   public: 149   public:
150   static constexpr 150   static constexpr
HITCBC 151   20 double (min)() noexcept 151   20 double (min)() noexcept
152   { 152   {
HITCBC 153   20 return min1(std::is_signed<T>{}); 153   20 return min1(std::is_signed<T>{});
154   } 154   }
155   155  
156   static constexpr 156   static constexpr
HITCBC 157   28 double (max)() noexcept 157   28 double (max)() noexcept
158   { 158   {
HITCBC 159   28 return max1(std::is_signed<T>{}); 159   28 return max1(std::is_signed<T>{});
160   } 160   }
161   }; 161   };
162   162  
163   #endif 163   #endif
164   164  
165   struct scalar 165   struct scalar
166   { 166   {
167   storage_ptr sp; // must come first 167   storage_ptr sp; // must come first
168   kind k; // must come second 168   kind k; // must come second
169   union 169   union
170   { 170   {
171   bool b; 171   bool b;
172   std::int64_t i; 172   std::int64_t i;
173   std::uint64_t u; 173   std::uint64_t u;
174   double d; 174   double d;
175   }; 175   };
176   176  
177   explicit 177   explicit
HITCBC 178   2152100 scalar(storage_ptr sp_ = {}) noexcept 178   2152100 scalar(storage_ptr sp_ = {}) noexcept
HITCBC 179   2152100 : sp(std::move(sp_)) 179   2152100 : sp(std::move(sp_))
HITCBC 180   2152100 , k(json::kind::null) 180   2152100 , k(json::kind::null)
181   { 181   {
HITCBC 182   2152100 } 182   2152100 }
183   183  
184   explicit 184   explicit
HITCBC 185   1088 scalar(bool b_, 185   1088 scalar(bool b_,
186   storage_ptr sp_ = {}) noexcept 186   storage_ptr sp_ = {}) noexcept
HITCBC 187   1088 : sp(std::move(sp_)) 187   1088 : sp(std::move(sp_))
HITCBC 188   1088 , k(json::kind::bool_) 188   1088 , k(json::kind::bool_)
HITCBC 189   1088 , b(b_) 189   1088 , b(b_)
190   { 190   {
HITCBC 191   1088 } 191   1088 }
192   192  
193   explicit 193   explicit
HITCBC 194   34593 scalar(std::int64_t i_, 194   34593 scalar(std::int64_t i_,
195   storage_ptr sp_ = {}) noexcept 195   storage_ptr sp_ = {}) noexcept
HITCBC 196   34593 : sp(std::move(sp_)) 196   34593 : sp(std::move(sp_))
HITCBC 197   34593 , k(json::kind::int64) 197   34593 , k(json::kind::int64)
HITCBC 198   34593 , i(i_) 198   34593 , i(i_)
199   { 199   {
HITCBC 200   34593 } 200   34593 }
201   201  
202   explicit 202   explicit
HITCBC 203   406 scalar(std::uint64_t u_, 203   406 scalar(std::uint64_t u_,
204   storage_ptr sp_ = {}) noexcept 204   storage_ptr sp_ = {}) noexcept
HITCBC 205   406 : sp(std::move(sp_)) 205   406 : sp(std::move(sp_))
HITCBC 206   406 , k(json::kind::uint64) 206   406 , k(json::kind::uint64)
HITCBC 207   406 , u(u_) 207   406 , u(u_)
208   { 208   {
HITCBC 209   406 } 209   406 }
210   210  
211   explicit 211   explicit
HITCBC 212   2040002 scalar(double d_, 212   2040002 scalar(double d_,
213   storage_ptr sp_ = {}) noexcept 213   storage_ptr sp_ = {}) noexcept
HITCBC 214   2040002 : sp(std::move(sp_)) 214   2040002 : sp(std::move(sp_))
HITCBC 215   2040002 , k(json::kind::double_) 215   2040002 , k(json::kind::double_)
HITCBC 216   2040002 , d(d_) 216   2040002 , d(d_)
217   { 217   {
HITCBC 218   2040002 } 218   2040002 }
219   }; 219   };
220   220  
221   struct access 221   struct access
222   { 222   {
223   template<class Value, class... Args> 223   template<class Value, class... Args>
224   static 224   static
225   Value& 225   Value&
HITCBC 226   2156934 construct_value(Value* p, Args&&... args) 226   2156934 construct_value(Value* p, Args&&... args)
227   { 227   {
228   return *reinterpret_cast< 228   return *reinterpret_cast<
HITCBC 229   6396945 Value*>(::new(p) Value( 229   6396945 Value*>(::new(p) Value(
HITCBC 230   6489244 std::forward<Args>(args)...)); 230   6489244 std::forward<Args>(args)...));
231   } 231   }
232   232  
233   template<class KeyValuePair, class... Args> 233   template<class KeyValuePair, class... Args>
234   static 234   static
235   KeyValuePair& 235   KeyValuePair&
HITCBC 236   38150 construct_key_value_pair( 236   38150 construct_key_value_pair(
237   KeyValuePair* p, Args&&... args) 237   KeyValuePair* p, Args&&... args)
238   { 238   {
239   return *reinterpret_cast< 239   return *reinterpret_cast<
HITCBC 240   38150 KeyValuePair*>(::new(p) 240   38150 KeyValuePair*>(::new(p)
241   KeyValuePair( 241   KeyValuePair(
HITCBC 242   76300 std::forward<Args>(args)...)); 242   76300 std::forward<Args>(args)...));
243   } 243   }
244   244  
245   template<class Value> 245   template<class Value>
246   static 246   static
247   char const* 247   char const*
HITCBC 248   38150 release_key( 248   38150 release_key(
249   Value& jv, 249   Value& jv,
250   std::size_t& len) noexcept 250   std::size_t& len) noexcept
251   { 251   {
HITCBC 252   38150 BOOST_ASSERT(jv.is_string()); 252   38150 BOOST_ASSERT(jv.is_string());
HITCBC 253   38150 jv.str_.sp_.~storage_ptr(); 253   38150 jv.str_.sp_.~storage_ptr();
HITCBC 254   38150 return jv.str_.impl_.release_key(len); 254   38150 return jv.str_.impl_.release_key(len);
255   } 255   }
256   256  
257   using index_t = std::uint32_t; 257   using index_t = std::uint32_t;
258   258  
259   template<class KeyValuePair> 259   template<class KeyValuePair>
260   static 260   static
261   index_t& 261   index_t&
HITCBC 262   11205 next(KeyValuePair& e) noexcept 262   10766 next(KeyValuePair& e) noexcept
263   { 263   {
HITCBC 264   11205 return e.next_; 264   10766 return e.next_;
265   } 265   }
266   266  
267   template<class KeyValuePair> 267   template<class KeyValuePair>
268   static 268   static
269   index_t const& 269   index_t const&
270   next(KeyValuePair const& e) noexcept 270   next(KeyValuePair const& e) noexcept
271   { 271   {
272   return e.next_; 272   return e.next_;
273   } 273   }
274   274  
275   template<class Value> 275   template<class Value>
276   static 276   static
277   auto 277   auto
HITCBC 278   12 get_scalar(Value& jv) -> scalar& 278   12 get_scalar(Value& jv) -> scalar&
279   { 279   {
HITCBC 280   12 return jv.sca_; 280   12 return jv.sca_;
281   } 281   }
282   282  
283   template<class Value> 283   template<class Value>
284   static 284   static
285   auto 285   auto
HITCBC 286   264 get_scalar(Value const& jv) -> scalar const& 286   264 get_scalar(Value const& jv) -> scalar const&
287   { 287   {
HITCBC 288   264 return jv.sca_; 288   264 return jv.sca_;
289   } 289   }
290   }; 290   };
291   291  
292   BOOST_JSON_DECL 292   BOOST_JSON_DECL
293   std::size_t 293   std::size_t
294   hash_value_impl( value const& jv ) noexcept; 294   hash_value_impl( value const& jv ) noexcept;
295   295  
296   } // detail 296   } // detail
297   } // namespace json 297   } // namespace json
298   } // namespace boost 298   } // namespace boost
299   299  
300   #endif 300   #endif