static_resource.hpp 5.8 KB

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