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