static_resource.hpp 5.9 KB

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