value.hpp 5.0 KB

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