100.00% Lines (58/58) 100.00% Functions (19/19)
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   template<class T> 29   template<class T>
30   class to_number_limit 30   class to_number_limit
31   { 31   {
32   // unsigned 32   // unsigned
33   33  
34   static constexpr 34   static constexpr
HITCBC 35   16 double max1(std::false_type) 35   16 double max1(std::false_type)
36   { 36   {
HITCBC 37   16 return max2u(std::integral_constant< 37   16 return max2u(std::integral_constant<
38   bool, (std::numeric_limits<T>::max)() == 38   bool, (std::numeric_limits<T>::max)() ==
HITCBC 39   16 UINT64_MAX>{}); 39   16 UINT64_MAX>{});
40   } 40   }
41   41  
42   static constexpr 42   static constexpr
HITCBC 43   12 double max2u(std::false_type) 43   12 double max2u(std::false_type)
44   { 44   {
45   return static_cast<double>( 45   return static_cast<double>(
HITCBC 46   12 (std::numeric_limits<T>::max)()); 46   12 (std::numeric_limits<T>::max)());
47   } 47   }
48   48  
49   static constexpr 49   static constexpr
HITCBC 50   4 double max2u(std::true_type) 50   4 double max2u(std::true_type)
51   { 51   {
52   // largest uint64_t value exactly representable as double 52   // largest uint64_t value exactly representable as double
HITCBC 53   4 return 18446744073709549568.0; 53   4 return 18446744073709549568.0;
54   } 54   }
55   55  
56   // signed 56   // signed
57   57  
58   static constexpr 58   static constexpr
HITCBC 59   29 double max1(std::true_type) 59   29 double max1(std::true_type)
60   { 60   {
HITCBC 61   29 return max2s(std::integral_constant< 61   29 return max2s(std::integral_constant<
62   bool, (std::numeric_limits<T>::max)() == 62   bool, (std::numeric_limits<T>::max)() ==
HITCBC 63   29 INT64_MAX>{}); 63   29 INT64_MAX>{});
64   } 64   }
65   65  
66   static constexpr 66   static constexpr
HITCBC 67   23 double max2s(std::false_type) 67   23 double max2s(std::false_type)
68   { 68   {
69   return static_cast<double>( 69   return static_cast<double>(
HITCBC 70   23 (std::numeric_limits<T>::max)()); 70   23 (std::numeric_limits<T>::max)());
71   } 71   }
72   72  
73   static constexpr 73   static constexpr
HITCBC 74   6 double max2s(std::true_type) 74   6 double max2s(std::true_type)
75   { 75   {
76   // largest int64_t value exactly representable as double 76   // largest int64_t value exactly representable as double
HITCBC 77   6 return 9223372036854774784.0; 77   6 return 9223372036854774784.0;
78   } 78   }
79   79  
80   public: 80   public:
81   static constexpr 81   static constexpr
HITCBC 82   32 double (min)() noexcept 82   32 double (min)() noexcept
83   { 83   {
HITCBC 84   32 return static_cast<double>( (std::numeric_limits<T>::min)() ); 84   32 return static_cast<double>( (std::numeric_limits<T>::min)() );
85   } 85   }
86   86  
87   static constexpr 87   static constexpr
HITCBC 88   45 double (max)() noexcept 88   45 double (max)() noexcept
89   { 89   {
HITCBC 90   45 return max1(std::is_signed<T>{}); 90   45 return max1(std::is_signed<T>{});
91   } 91   }
92   }; 92   };
93   93  
94   struct scalar 94   struct scalar
95   { 95   {
96   storage_ptr sp; // must come first 96   storage_ptr sp; // must come first
97   kind k; // must come second 97   kind k; // must come second
98   union 98   union
99   { 99   {
100   bool b; 100   bool b;
101   std::int64_t i; 101   std::int64_t i;
102   std::uint64_t u; 102   std::uint64_t u;
103   double d; 103   double d;
104   }; 104   };
105   105  
106   explicit 106   explicit
HITCBC 107   2152210 scalar(storage_ptr sp_ = {}) noexcept 107   2152254 scalar(storage_ptr sp_ = {}) noexcept
HITCBC 108   2152210 : sp(std::move(sp_)) 108   2152254 : sp(std::move(sp_))
HITCBC 109   2152210 , k(json::kind::null) 109   2152254 , k(json::kind::null)
110   { 110   {
HITCBC 111   2152210 } 111   2152254 }
112   112  
113   explicit 113   explicit
HITCBC 114   1107 scalar(bool b_, 114   1107 scalar(bool b_,
115   storage_ptr sp_ = {}) noexcept 115   storage_ptr sp_ = {}) noexcept
HITCBC 116   1107 : sp(std::move(sp_)) 116   1107 : sp(std::move(sp_))
HITCBC 117   1107 , k(json::kind::bool_) 117   1107 , k(json::kind::bool_)
HITCBC 118   1107 , b(b_) 118   1107 , b(b_)
119   { 119   {
HITCBC 120   1107 } 120   1107 }
121   121  
122   explicit 122   explicit
HITCBC 123   34780 scalar(std::int64_t i_, 123   34796 scalar(std::int64_t i_,
124   storage_ptr sp_ = {}) noexcept 124   storage_ptr sp_ = {}) noexcept
HITCBC 125   34780 : sp(std::move(sp_)) 125   34796 : sp(std::move(sp_))
HITCBC 126   34780 , k(json::kind::int64) 126   34796 , k(json::kind::int64)
HITCBC 127   34780 , i(i_) 127   34796 , i(i_)
128   { 128   {
HITCBC 129   34780 } 129   34796 }
130   130  
131   explicit 131   explicit
HITCBC 132   406 scalar(std::uint64_t u_, 132   398 scalar(std::uint64_t u_,
133   storage_ptr sp_ = {}) noexcept 133   storage_ptr sp_ = {}) noexcept
HITCBC 134   406 : sp(std::move(sp_)) 134   398 : sp(std::move(sp_))
HITCBC 135   406 , k(json::kind::uint64) 135   398 , k(json::kind::uint64)
HITCBC 136   406 , u(u_) 136   398 , u(u_)
137   { 137   {
HITCBC 138   406 } 138   398 }
139   139  
140   explicit 140   explicit
HITCBC 141   2039974 scalar(double d_, 141   2039974 scalar(double d_,
142   storage_ptr sp_ = {}) noexcept 142   storage_ptr sp_ = {}) noexcept
HITCBC 143   2039974 : sp(std::move(sp_)) 143   2039974 : sp(std::move(sp_))
HITCBC 144   2039974 , k(json::kind::double_) 144   2039974 , k(json::kind::double_)
HITCBC 145   2039974 , d(d_) 145   2039974 , d(d_)
146   { 146   {
HITCBC 147   2039974 } 147   2039974 }
148   }; 148   };
149   149  
150   struct access 150   struct access
151   { 151   {
152   template<class Value, class... Args> 152   template<class Value, class... Args>
153   static 153   static
154   Value& 154   Value&
HITCBC 155   2156952 construct_value(Value* p, Args&&... args) 155   2156952 construct_value(Value* p, Args&&... args)
156   { 156   {
157   return *reinterpret_cast< 157   return *reinterpret_cast<
HITCBC 158   6396997 Value*>(::new(p) Value( 158   6396997 Value*>(::new(p) Value(
HITCBC 159   6489299 std::forward<Args>(args)...)); 159   6489299 std::forward<Args>(args)...));
160   } 160   }
161   161  
162   template<class KeyValuePair, class... Args> 162   template<class KeyValuePair, class... Args>
163   static 163   static
164   KeyValuePair& 164   KeyValuePair&
HITCBC 165   38151 construct_key_value_pair( 165   38151 construct_key_value_pair(
166   KeyValuePair* p, Args&&... args) 166   KeyValuePair* p, Args&&... args)
167   { 167   {
168   return *reinterpret_cast< 168   return *reinterpret_cast<
HITCBC 169   38151 KeyValuePair*>(::new(p) 169   38151 KeyValuePair*>(::new(p)
170   KeyValuePair( 170   KeyValuePair(
HITCBC 171   76302 std::forward<Args>(args)...)); 171   76302 std::forward<Args>(args)...));
172   } 172   }
173   173  
174   template<class Value> 174   template<class Value>
175   static 175   static
176   char const* 176   char const*
HITCBC 177   38151 release_key( 177   38151 release_key(
178   Value& jv, 178   Value& jv,
179   std::size_t& len) noexcept 179   std::size_t& len) noexcept
180   { 180   {
HITCBC 181   38151 BOOST_ASSERT(jv.is_string()); 181   38151 BOOST_ASSERT(jv.is_string());
HITCBC 182   38151 jv.str_.sp_.~storage_ptr(); 182   38151 jv.str_.sp_.~storage_ptr();
HITCBC 183   38151 return jv.str_.impl_.release_key(len); 183   38151 return jv.str_.impl_.release_key(len);
184   } 184   }
185   185  
186   using index_t = std::uint32_t; 186   using index_t = std::uint32_t;
187   187  
188   template<class KeyValuePair> 188   template<class KeyValuePair>
189   static 189   static
190   index_t& 190   index_t&
HITCBC 191   12256 next(KeyValuePair& e) noexcept 191   11365 next(KeyValuePair& e) noexcept
192   { 192   {
HITCBC 193   12256 return e.next_; 193   11365 return e.next_;
194   } 194   }
195   195  
196   template<class KeyValuePair> 196   template<class KeyValuePair>
197   static 197   static
198   index_t const& 198   index_t const&
199   next(KeyValuePair const& e) noexcept 199   next(KeyValuePair const& e) noexcept
200   { 200   {
201   return e.next_; 201   return e.next_;
202   } 202   }
203   203  
204   template<class Value> 204   template<class Value>
205   static 205   static
206   auto 206   auto
HITCBC 207   12 get_scalar(Value& jv) -> scalar& 207   12 get_scalar(Value& jv) -> scalar&
208   { 208   {
HITCBC 209   12 return jv.sca_; 209   12 return jv.sca_;
210   } 210   }
211   211  
212   template<class Value> 212   template<class Value>
213   static 213   static
214   auto 214   auto
HITCBC 215   264 get_scalar(Value const& jv) -> scalar const& 215   264 get_scalar(Value const& jv) -> scalar const&
216   { 216   {
HITCBC 217   264 return jv.sca_; 217   264 return jv.sca_;
218   } 218   }
219   }; 219   };
220   220  
221   BOOST_JSON_DECL 221   BOOST_JSON_DECL
222   std::size_t 222   std::size_t
223   hash_value_impl( value const& jv ) noexcept; 223   hash_value_impl( value const& jv ) noexcept;
224   224  
225   } // detail 225   } // detail
226   } // namespace json 226   } // namespace json
227   } // namespace boost 227   } // namespace boost
228   228  
229   #endif 229   #endif