static_resource.hpp 5.5 KB

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