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