value.hpp 5.4 KB

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