static_resource.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. //
  2. // Copyright (c) 2020 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_STATIC_RESOURCE_HPP
  10. #define BOOST_JSON_STATIC_RESOURCE_HPP
  11. #include <boost/json/detail/config.hpp>
  12. #include <boost/json/memory_resource.hpp>
  13. #include <cstddef>
  14. BOOST_JSON_NS_BEGIN
  15. #ifdef _MSC_VER
  16. #pragma warning(push)
  17. #pragma warning(disable: 4275) // non dll-interface class used as base for dll-interface class
  18. #endif
  19. //----------------------------------------------------------
  20. /** A resource using a caller-owned buffer, with a trivial deallocate
  21. This memory resource is a special-purpose resource
  22. that releases allocated memory only when the resource
  23. is destroyed (or when @ref release is called).
  24. It has a trivial deallocate function; that is, the
  25. metafunction @ref is_deallocate_trivial returns `true`.
  26. \n
  27. The resource is constructed from a caller-owned buffer
  28. from which subsequent calls to allocate are apportioned.
  29. When a memory request cannot be satisfied from the
  30. free bytes remaining in the buffer, the allocation
  31. request fails with the exception `std::bad_alloc`.
  32. \n
  33. @par Example
  34. This parses a JSON into a value which uses a local
  35. stack buffer, then prints the result.
  36. @code
  37. unsigned char buf[ 4000 ];
  38. static_resource mr( buf );
  39. // Parse the string, using our memory resource
  40. value const jv = parse( "[1,2,3]", &mr );
  41. // Print the JSON
  42. std::cout << jv;
  43. @endcode
  44. @par Thread Safety
  45. Members of the same instance may not be
  46. called concurrently.
  47. @see
  48. https://en.wikipedia.org/wiki/Region-based_memory_management
  49. */
  50. class BOOST_JSON_CLASS_DECL
  51. static_resource final
  52. : public memory_resource
  53. {
  54. void* p_;
  55. std::size_t n_;
  56. std::size_t size_;
  57. public:
  58. /// Copy constructor (deleted)
  59. static_resource(
  60. static_resource const&) = delete;
  61. /// Copy assignment (deleted)
  62. static_resource& operator=(
  63. static_resource const&) = delete;
  64. /** Destructor
  65. @par Complexity
  66. Constant.
  67. @par Exception Safety
  68. No-throw guarantee.
  69. */
  70. ~static_resource() noexcept;
  71. /** Constructor
  72. This constructs the resource to use the specified
  73. buffer for subsequent calls to allocate. When the
  74. buffer is exhausted, allocate will throw
  75. `std::bad_alloc`.
  76. @par Complexity
  77. Constant.
  78. @par Exception Safety
  79. No-throw guarantee.
  80. @param buffer The buffer to use.
  81. Ownership is not transferred; the caller is
  82. responsible for ensuring that the lifetime of
  83. the buffer extends until the resource is destroyed.
  84. @param size The number of valid bytes pointed
  85. to by `buffer`.
  86. */
  87. /** @{ */
  88. static_resource(
  89. unsigned char* buffer,
  90. std::size_t size) noexcept;
  91. #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
  92. static_resource(
  93. std::byte* buffer,
  94. std::size_t size) noexcept
  95. : static_resource(reinterpret_cast<
  96. unsigned char*>(buffer), size)
  97. {
  98. }
  99. #endif
  100. /** @} */
  101. /** Constructor
  102. This constructs the resource to use the specified
  103. buffer for subsequent calls to allocate. When the
  104. buffer is exhausted, allocate will throw
  105. `std::bad_alloc`.
  106. @par Complexity
  107. Constant.
  108. @par Exception Safety
  109. No-throw guarantee.
  110. @param buffer The buffer to use.
  111. Ownership is not transferred; the caller is
  112. responsible for ensuring that the lifetime of
  113. the buffer extends until the resource is destroyed.
  114. */
  115. /** @{ */
  116. template<std::size_t N>
  117. explicit
  118. static_resource(
  119. unsigned char(&buffer)[N]) noexcept
  120. : static_resource(&buffer[0], N)
  121. {
  122. }
  123. #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
  124. template<std::size_t N>
  125. explicit
  126. static_resource(
  127. std::byte(&buffer)[N]) noexcept
  128. : static_resource(&buffer[0], N)
  129. {
  130. }
  131. #endif
  132. /** @} */
  133. #ifndef BOOST_JSON_DOCS
  134. // Safety net for accidental buffer overflows
  135. template<std::size_t N>
  136. static_resource(
  137. unsigned char(&buffer)[N], std::size_t n) noexcept
  138. : static_resource(&buffer[0], n)
  139. {
  140. // If this goes off, check your parameters
  141. // closely, chances are you passed an array
  142. // thinking it was a pointer.
  143. BOOST_ASSERT(n <= N);
  144. }
  145. #ifdef __cpp_lib_byte
  146. // Safety net for accidental buffer overflows
  147. template<std::size_t N>
  148. static_resource(
  149. std::byte(&buffer)[N], std::size_t n) noexcept
  150. : static_resource(&buffer[0], n)
  151. {
  152. // If this goes off, check your parameters
  153. // closely, chances are you passed an array
  154. // thinking it was a pointer.
  155. BOOST_ASSERT(n <= N);
  156. }
  157. #endif
  158. #endif
  159. /** Release all allocated memory.
  160. This function resets the buffer provided upon
  161. construction so that all of the valid bytes are
  162. available for subsequent allocation.
  163. @par Complexity
  164. Constant
  165. @par Exception Safety
  166. No-throw guarantee.
  167. */
  168. void
  169. release() noexcept;
  170. protected:
  171. #ifndef BOOST_JSON_DOCS
  172. void*
  173. do_allocate(
  174. std::size_t n,
  175. std::size_t align) override;
  176. void
  177. do_deallocate(
  178. void* p,
  179. std::size_t n,
  180. std::size_t align) override;
  181. bool
  182. do_is_equal(
  183. memory_resource const& mr
  184. ) const noexcept override;
  185. #endif
  186. };
  187. #ifdef _MSC_VER
  188. #pragma warning(pop)
  189. #endif
  190. template<>
  191. struct is_deallocate_trivial<
  192. static_resource>
  193. {
  194. static constexpr bool value = true;
  195. };
  196. BOOST_JSON_NS_END
  197. #endif