value.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. //
  2. // Copyright (c) 2019 Vinnie Falco ([email protected])
  3. //
  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)
  6. //
  7. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_DETAIL_VALUE_HPP
  10. #define BOOST_JSON_DETAIL_VALUE_HPP
  11. #include <boost/json/fwd.hpp>
  12. #include <boost/json/kind.hpp>
  13. #include <boost/json/storage_ptr.hpp>
  14. #include <cstdint>
  15. #include <limits>
  16. #include <new>
  17. #include <utility>
  18. namespace boost {
  19. namespace json {
  20. namespace detail {
  21. struct key_t
  22. {
  23. };
  24. #if 0
  25. template<class T>
  26. struct to_number_limit
  27. : std::numeric_limits<T>
  28. {
  29. };
  30. template<class T>
  31. struct to_number_limit<T const>
  32. : to_number_limit<T>
  33. {
  34. };
  35. template<>
  36. struct to_number_limit<long long>
  37. {
  38. static constexpr long long (min)() noexcept
  39. {
  40. return -9223372036854774784;
  41. }
  42. static constexpr long long (max)() noexcept
  43. {
  44. return 9223372036854774784;
  45. }
  46. };
  47. template<>
  48. struct to_number_limit<unsigned long long>
  49. {
  50. static constexpr
  51. unsigned long long (min)() noexcept
  52. {
  53. return 0;
  54. }
  55. static constexpr
  56. unsigned long long (max)() noexcept
  57. {
  58. return 18446744073709549568ULL;
  59. }
  60. };
  61. #else
  62. template<class T>
  63. class to_number_limit
  64. {
  65. // unsigned
  66. static constexpr
  67. double min1(std::false_type)
  68. {
  69. return 0.0;
  70. }
  71. static constexpr
  72. double max1(std::false_type)
  73. {
  74. return max2u(std::integral_constant<
  75. bool, (std::numeric_limits<T>::max)() ==
  76. UINT64_MAX>{});
  77. }
  78. static constexpr
  79. double max2u(std::false_type)
  80. {
  81. return static_cast<double>(
  82. (std::numeric_limits<T>::max)());
  83. }
  84. static constexpr
  85. double max2u(std::true_type)
  86. {
  87. return 18446744073709549568.0;
  88. }
  89. // signed
  90. static constexpr
  91. double min1(std::true_type)
  92. {
  93. return min2s(std::integral_constant<
  94. bool, (std::numeric_limits<T>::max)() ==
  95. INT64_MAX>{});
  96. }
  97. static constexpr
  98. double min2s(std::false_type)
  99. {
  100. return static_cast<double>(
  101. (std::numeric_limits<T>::min)());
  102. }
  103. static constexpr
  104. double min2s(std::true_type)
  105. {
  106. return -9223372036854774784.0;
  107. }
  108. static constexpr
  109. double max1(std::true_type)
  110. {
  111. return max2s(std::integral_constant<
  112. bool, (std::numeric_limits<T>::max)() ==
  113. INT64_MAX>{});
  114. }
  115. static constexpr
  116. double max2s(std::false_type)
  117. {
  118. return static_cast<double>(
  119. (std::numeric_limits<T>::max)());
  120. }
  121. static constexpr
  122. double max2s(std::true_type)
  123. {
  124. return 9223372036854774784.0;
  125. }
  126. public:
  127. static constexpr
  128. double (min)() noexcept
  129. {
  130. return min1(std::is_signed<T>{});
  131. }
  132. static constexpr
  133. double (max)() noexcept
  134. {
  135. return max1(std::is_signed<T>{});
  136. }
  137. };
  138. #endif
  139. struct scalar
  140. {
  141. storage_ptr sp; // must come first
  142. kind k; // must come second
  143. union
  144. {
  145. bool b;
  146. std::int64_t i;
  147. std::uint64_t u;
  148. double d;
  149. };
  150. explicit
  151. scalar(storage_ptr sp_ = {}) noexcept
  152. : sp(std::move(sp_))
  153. , k(json::kind::null)
  154. {
  155. }
  156. explicit
  157. scalar(bool b_,
  158. storage_ptr sp_ = {}) noexcept
  159. : sp(std::move(sp_))
  160. , k(json::kind::bool_)
  161. , b(b_)
  162. {
  163. }
  164. explicit
  165. scalar(std::int64_t i_,
  166. storage_ptr sp_ = {}) noexcept
  167. : sp(std::move(sp_))
  168. , k(json::kind::int64)
  169. , i(i_)
  170. {
  171. }
  172. explicit
  173. scalar(std::uint64_t u_,
  174. storage_ptr sp_ = {}) noexcept
  175. : sp(std::move(sp_))
  176. , k(json::kind::uint64)
  177. , u(u_)
  178. {
  179. }
  180. explicit
  181. scalar(double d_,
  182. storage_ptr sp_ = {}) noexcept
  183. : sp(std::move(sp_))
  184. , k(json::kind::double_)
  185. , d(d_)
  186. {
  187. }
  188. };
  189. struct access
  190. {
  191. template<class Value, class... Args>
  192. static
  193. Value&
  194. construct_value(Value* p, Args&&... args)
  195. {
  196. return *reinterpret_cast<
  197. Value*>(::new(p) Value(
  198. std::forward<Args>(args)...));
  199. }
  200. template<class KeyValuePair, class... Args>
  201. static
  202. KeyValuePair&
  203. construct_key_value_pair(
  204. KeyValuePair* p, Args&&... args)
  205. {
  206. return *reinterpret_cast<
  207. KeyValuePair*>(::new(p)
  208. KeyValuePair(
  209. std::forward<Args>(args)...));
  210. }
  211. template<class Value>
  212. static
  213. char const*
  214. release_key(
  215. Value& jv,
  216. std::size_t& len) noexcept
  217. {
  218. BOOST_ASSERT(jv.is_string());
  219. jv.str_.sp_.~storage_ptr();
  220. return jv.str_.impl_.release_key(len);
  221. }
  222. using index_t = std::uint32_t;
  223. template<class KeyValuePair>
  224. static
  225. index_t&
  226. next(KeyValuePair& e) noexcept
  227. {
  228. return e.next_;
  229. }
  230. template<class KeyValuePair>
  231. static
  232. index_t const&
  233. next(KeyValuePair const& e) noexcept
  234. {
  235. return e.next_;
  236. }
  237. };
  238. BOOST_JSON_DECL
  239. std::size_t
  240. hash_value_impl( value const& jv ) noexcept;
  241. } // detail
  242. } // namespace json
  243. } // namespace boost
  244. #endif