GCC Code Coverage Report


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