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