GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/recycled.hpp
Date: 2024-08-20 16:05:55
Exec Total Coverage
Lines: 9 9 100.0%
Functions: 9 9 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2022 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/url
8 //
9
10 #ifndef BOOST_URL_GRAMMAR_RECYCLED_HPP
11 #define BOOST_URL_GRAMMAR_RECYCLED_HPP
12
13 #include <boost/url/detail/config.hpp>
14 #include <boost/url/grammar/detail/recycled.hpp>
15 #include <atomic>
16 #include <cstddef>
17 #include <type_traits>
18 #include <stddef.h> // ::max_align_t
19
20 #if !defined(BOOST_URL_DISABLE_THREADS)
21 # include <mutex>
22 #endif
23
24 namespace boost {
25 namespace urls {
26 namespace grammar {
27
28 /** Provides an aligned storage buffer aligned for T
29 */
30 #ifdef BOOST_URL_DOCS
31 template<class T>
32 struct aligned_storage
33 {
34 /** Return a pointer to the aligned storage area
35 */
36 void* addr() noexcept;
37
38 /** Return a pointer to the aligned storage area
39 */
40 void const* addr() const noexcept;
41 };
42 #else
43 /** Provides an aligned storage buffer aligned for T
44
45 @code
46 template<class T>
47 struct aligned_storage
48 {
49 /// Return a pointer to the aligned storage area
50 void* addr() noexcept;
51
52 /// Return a pointer to the aligned storage area
53 void const* addr() const noexcept;
54 };
55 @endcode
56
57 */
58 template<class T>
59 using aligned_storage =
60 see_below::aligned_storage_impl<
61 see_below::nearest_pow2(sizeof(T), 64),
62 (alignof(::max_align_t) > alignof(T)) ?
63 alignof(::max_align_t) : alignof(T)>;
64 #endif
65
66 //------------------------------------------------
67
68 /** A thread-safe collection of instances of T
69
70 Instances of this type may be used to control
71 where recycled instances of T come from when
72 used with @ref recycled_ptr.
73
74 @par Example
75 @code
76 static recycled< std::string > bin;
77
78 recycled_ptr< std::string > ps( bin );
79
80 // Put the string into a known state
81 ps->clear();
82 @endcode
83
84 @see
85 @ref recycled_ptr.
86 */
87 template<class T>
88 class recycled
89 {
90 public:
91 /** Destructor
92
93 All recycled instances of T are destroyed.
94 Undefined behavior results if there are
95 any @ref recycled_ptr which reference
96 this recycle bin.
97 */
98 ~recycled();
99
100 /** Constructor
101 */
102 constexpr recycled() = default;
103
104 private:
105 template<class>
106 friend class recycled_ptr;
107
108 struct U
109 {
110 T t;
111 U* next = nullptr;
112
113 #if !defined(BOOST_URL_DISABLE_THREADS)
114 std::atomic<
115 std::size_t> refs;
116 #else
117 std::size_t refs;
118 #endif
119
120
121 5 U()
122 5 : refs{1}
123 {
124 5 }
125 };
126
127 struct report;
128
129 U* acquire();
130 void release(U* u) noexcept;
131
132 U* head_ = nullptr;
133
134 #if !defined(BOOST_URL_DISABLE_THREADS)
135 std::mutex m_;
136 #endif
137 };
138
139 //------------------------------------------------
140
141 /** A pointer to a shared instance of T
142
143 This is a smart pointer container which can
144 acquire shared ownership of an instance of
145 `T` upon or after construction. The instance
146 is guaranteed to be in a valid, but unknown
147 state. Every recycled pointer references
148 a valid recycle bin.
149
150 @par Example
151 @code
152 static recycled< std::string > bin;
153
154 recycled_ptr< std::string > ps( bin );
155
156 // Put the string into a known state
157 ps->clear();
158 @endcode
159
160 @tparam T the type of object to
161 acquire, which must be
162 <em>DefaultConstructible</em>.
163 */
164 template<class T>
165 class recycled_ptr
166 {
167 // T must be default constructible!
168 static_assert(
169 std::is_default_constructible<T>::value,
170 "T must be DefaultConstructible");
171
172 friend class recycled<T>;
173
174 using B = recycled<T>;
175 using U = typename B::U;
176
177 B* bin_ = nullptr;
178 U* p_ = nullptr;
179
180 public:
181 /** Destructor
182
183 If this is not empty, shared ownership
184 of the pointee is released. If this was
185 the last reference, the object is
186 returned to the original recycle bin.
187
188 @par Effects
189 @code
190 this->release();
191 @endcode
192 */
193 ~recycled_ptr();
194
195 /** Constructor
196
197 Upon construction, this acquires
198 exclusive access to an object of type
199 `T` which is either recycled from the
200 specified bin, or newly allocated.
201 The object is in an unknown but
202 valid state.
203
204 @par Example
205 @code
206 static recycled< std::string > bin;
207
208 recycled_ptr< std::string > ps( bin );
209
210 // Put the string into a known state
211 ps->clear();
212 @endcode
213
214 @par Postconditions
215 @code
216 &this->bin() == &bin && ! this->empty()
217 @endcode
218
219 @param bin The recycle bin to use
220
221 @see
222 @ref recycled.
223 */
224 explicit
225 recycled_ptr(recycled<T>& bin);
226
227 /** Constructor
228
229 After construction, this is empty and
230 refers to the specified recycle bin.
231
232 @par Example
233 @code
234 static recycled< std::string > bin;
235
236 recycled_ptr< std::string > ps( bin, nullptr );
237
238 // Acquire a string and put it into a known state
239 ps->acquire();
240 ps->clear();
241 @endcode
242
243 @par Postconditions
244 @code
245 &this->bin() == &bin && this->empty()
246 @endcode
247
248 @par Exception Safety
249 Throws nothing.
250
251 @param bin The recycle bin to use
252
253 @see
254 @ref acquire,
255 @ref recycled,
256 @ref release.
257 */
258 recycled_ptr(
259 recycled<T>& bin,
260 std::nullptr_t) noexcept;
261
262 /** Constructor
263
264 Upon construction, this acquires
265 exclusive access to an object of type
266 `T` which is either recycled from a
267 global recycle bin, or newly allocated.
268 The object is in an unknown but
269 valid state.
270
271 @par Example
272 @code
273 recycled_ptr< std::string > ps;
274
275 // Put the string into a known state
276 ps->clear();
277 @endcode
278
279 @par Postconditions
280 @code
281 &this->bin() != nullptr && ! this->empty()
282 @endcode
283
284 @see
285 @ref recycled.
286 */
287 recycled_ptr();
288
289 /** Constructor
290
291 After construction, this is empty
292 and refers to a global recycle bin.
293
294 @par Example
295 @code
296 recycled_ptr< std::string > ps( nullptr );
297
298 // Acquire a string and put it into a known state
299 ps->acquire();
300 ps->clear();
301 @endcode
302
303 @par Postconditions
304 @code
305 &this->bin() != nullptr && this->empty()
306 @endcode
307
308 @par Exception Safety
309 Throws nothing.
310
311 @see
312 @ref acquire,
313 @ref recycled,
314 @ref release.
315 */
316 recycled_ptr(
317 std::nullptr_t) noexcept;
318
319 /** Constructor
320
321 If `other` references an object, the
322 newly constructed pointer acquires
323 shared ownership. Otherwise this is
324 empty. The new pointer references
325 the same recycle bin as `other`.
326
327 @par Postconditions
328 @code
329 &this->bin() == &other->bin() && this->get() == other.get()
330 @endcode
331
332 @par Exception Safety
333 Throws nothing.
334
335 @param other The pointer to copy
336 */
337 recycled_ptr(
338 recycled_ptr const& other) noexcept;
339
340 /** Constructor
341
342 If `other` references an object,
343 ownership is transferred including
344 a reference to the recycle bin. After
345 the move, the moved-from object is empty.
346
347 @par Postconditions
348 @code
349 &this->bin() == &other->bin() && ! this->empty() && other.empty()
350 @endcode
351
352 @par Exception Safety
353 Throws nothing.
354
355 @param other The pointer to move from
356 */
357 recycled_ptr(
358 recycled_ptr&& other) noexcept;
359
360 /** Assignment
361
362 If `other` references an object,
363 ownership is transferred including
364 a reference to the recycle bin. After
365 the move, the moved-from object is empty.
366
367 @par Effects
368 @code
369 this->release()
370 @endcode
371
372 @par Postconditions
373 @code
374 &this->bin() == &other->bin()
375 @endcode
376
377 @par Exception Safety
378 Throws nothing.
379
380 @param other The pointer to move from
381 */
382 recycled_ptr&
383 operator=(
384 recycled_ptr&& other) noexcept;
385
386 /** Assignment
387
388 If `other` references an object,
389 this acquires shared ownership and
390 references the same recycle bin as
391 `other`. The previous object if any
392 is released.
393
394 @par Effects
395 @code
396 this->release()
397 @endcode
398
399 @par Postconditions
400 @code
401 &this->bin() == &other->bin() && this->get() == other.get()
402 @endcode
403
404 @par Exception Safety
405 Throws nothing.
406
407 @param other The pointer to copy from
408 */
409 recycled_ptr&
410 operator=(
411 recycled_ptr const& other) noexcept;
412
413 /** Return true if this does not reference an object
414
415 @par Exception Safety
416 Throws nothing.
417 */
418 bool
419 empty() const noexcept
420 {
421 return p_ == nullptr;
422 }
423
424 /** Return true if this references an object
425
426 @par Effects
427 @code
428 return ! this->empty();
429 @endcode
430
431 @par Exception Safety
432 Throws nothing.
433 */
434 explicit
435 24 operator bool() const noexcept
436 {
437 24 return p_ != nullptr;
438 }
439
440 /** Return the referenced recycle bin
441
442 @par Exception Safety
443 Throws nothing.
444 */
445 recycled<T>&
446 bin() const noexcept
447 {
448 return *bin_;
449 }
450
451 /** Return the referenced object
452
453 If this is empty, `nullptr` is returned.
454
455 @par Exception Safety
456 Throws nothing.
457 */
458 52 T* get() const noexcept
459 {
460 52 return &p_->t;
461 }
462
463 /** Return the referenced object
464
465 If this is empty, `nullptr` is returned.
466
467 @par Exception Safety
468 Throws nothing.
469 */
470 30 T* operator->() const noexcept
471 {
472 30 return get();
473 }
474
475 /** Return the referenced object
476
477 @par Preconditions
478 @code
479 not this->empty()
480 @endcode
481 */
482 T& operator*() const noexcept
483 {
484 return *get();
485 }
486
487 /** Return the referenced object
488
489 If this references an object, it is
490 returned. Otherwise, exclusive ownership
491 of a new object of type `T` is acquired
492 and returned.
493
494 @par Postconditions
495 @code
496 not this->empty()
497 @endcode
498 */
499 T& acquire();
500
501 /** Release the referenced object
502
503 If this references an object, it is
504 released to the referenced recycle bin.
505 The pointer continues to reference
506 the same recycle bin.
507
508 @par Postconditions
509 @code
510 this->empty()
511 @endcode
512
513 @par Exception Safety
514 Throws nothing.
515 */
516 void release() noexcept;
517 };
518
519 } // grammar
520 } // urls
521 } // boost
522
523 #include <boost/url/grammar/impl/recycled.hpp>
524
525 #endif
526