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