1  
//
1  
//
2  
// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2022 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/url
7  
// Official repository: https://github.com/boostorg/url
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_URL_GRAMMAR_RECYCLED_HPP
10  
#ifndef BOOST_URL_GRAMMAR_RECYCLED_HPP
11  
#define BOOST_URL_GRAMMAR_RECYCLED_HPP
11  
#define BOOST_URL_GRAMMAR_RECYCLED_HPP
12  

12  

13  
#include <boost/url/detail/config.hpp>
13  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/grammar/detail/recycled.hpp>
14  
#include <boost/url/grammar/detail/recycled.hpp>
15  
#include <atomic>
15  
#include <atomic>
16  
#include <cstddef>
16  
#include <cstddef>
17  
#include <type_traits>
17  
#include <type_traits>
18  
#include <stddef.h> // ::max_align_t
18  
#include <stddef.h> // ::max_align_t
19  

19  

20  
#if !defined(BOOST_URL_DISABLE_THREADS)
20  
#if !defined(BOOST_URL_DISABLE_THREADS)
21  
# include <mutex>
21  
# include <mutex>
22  
#endif
22  
#endif
23  

23  

24  
namespace boost {
24  
namespace boost {
25  
namespace urls {
25  
namespace urls {
26  
namespace grammar {
26  
namespace grammar {
27  

27  

28  
/** Provides an aligned storage buffer aligned for T
28  
/** Provides an aligned storage buffer aligned for T
29  

29  

30  
    @code
30  
    @code
31  
    template<class T>
31  
    template<class T>
32  
    struct aligned_storage
32  
    struct aligned_storage
33  
    {
33  
    {
34  
        /// Return a pointer to the aligned storage area
34  
        /// Return a pointer to the aligned storage area
35  
        void* addr() noexcept;
35  
        void* addr() noexcept;
36  

36  

37  
        /// Return a pointer to the aligned storage area
37  
        /// Return a pointer to the aligned storage area
38  
        void const* addr() const noexcept;
38  
        void const* addr() const noexcept;
39  
    };
39  
    };
40  
    @endcode
40  
    @endcode
41  

41  

42  
 */
42  
 */
43  
template<class T>
43  
template<class T>
44  
using aligned_storage =
44  
using aligned_storage =
45  
    implementation_defined::aligned_storage_impl<
45  
    implementation_defined::aligned_storage_impl<
46  
        implementation_defined::nearest_pow2(sizeof(T), 64),
46  
        implementation_defined::nearest_pow2(sizeof(T), 64),
47  
            (alignof(::max_align_t) > alignof(T)) ?
47  
            (alignof(::max_align_t) > alignof(T)) ?
48  
                alignof(::max_align_t) : alignof(T)>;
48  
                alignof(::max_align_t) : alignof(T)>;
49  

49  

50  
//------------------------------------------------
50  
//------------------------------------------------
51  

51  

52  
/** A thread-safe collection of instances of T
52  
/** A thread-safe collection of instances of T
53  

53  

54  
    Instances of this type may be used to control
54  
    Instances of this type may be used to control
55  
    where recycled instances of T come from when
55  
    where recycled instances of T come from when
56  
    used with @ref recycled_ptr.
56  
    used with @ref recycled_ptr.
57  

57  

58  
    @par Example
58  
    @par Example
59  
    @code
59  
    @code
60  
    static recycled< std::string > bin;
60  
    static recycled< std::string > bin;
61  

61  

62  
    recycled_ptr< std::string > ps( bin );
62  
    recycled_ptr< std::string > ps( bin );
63  

63  

64  
    // Put the string into a known state
64  
    // Put the string into a known state
65  
    ps->clear();
65  
    ps->clear();
66  
    @endcode
66  
    @endcode
67  

67  

68  
    @see
68  
    @see
69  
        @ref recycled_ptr.
69  
        @ref recycled_ptr.
70  
*/
70  
*/
71  
template<class T>
71  
template<class T>
72  
class recycled
72  
class recycled
73  
{
73  
{
74  
public:
74  
public:
75  
    /** Destructor
75  
    /** Destructor
76  

76  

77  
        All recycled instances of T are destroyed.
77  
        All recycled instances of T are destroyed.
78  
        Undefined behavior results if there are
78  
        Undefined behavior results if there are
79  
        any @ref recycled_ptr which reference
79  
        any @ref recycled_ptr which reference
80  
        this recycle bin.
80  
        this recycle bin.
81  
    */
81  
    */
82  
    ~recycled();
82  
    ~recycled();
83  

83  

84  
    /** Constructor
84  
    /** Constructor
85  
    */
85  
    */
86  
    constexpr recycled() = default;
86  
    constexpr recycled() = default;
87  

87  

88  
private:
88  
private:
89  
    template<class>
89  
    template<class>
90  
    friend class recycled_ptr;
90  
    friend class recycled_ptr;
91  

91  

92  
    struct U
92  
    struct U
93  
    {
93  
    {
94  
        T t;
94  
        T t;
95  
        U* next = nullptr;
95  
        U* next = nullptr;
96  

96  

97  
#if !defined(BOOST_URL_DISABLE_THREADS)
97  
#if !defined(BOOST_URL_DISABLE_THREADS)
98  
        std::atomic<
98  
        std::atomic<
99  
            std::size_t> refs;
99  
            std::size_t> refs;
100  
#else
100  
#else
101  
        std::size_t refs;
101  
        std::size_t refs;
102  
#endif
102  
#endif
103  

103  

104  

104  

105  
        U()
105  
        U()
106  
            : refs{1}
106  
            : refs{1}
107  
        {
107  
        {
108  
        }
108  
        }
109  
    };
109  
    };
110  

110  

111  
    struct report;
111  
    struct report;
112  

112  

113  
    U* acquire();
113  
    U* acquire();
114  
    void release(U* u) noexcept;
114  
    void release(U* u) noexcept;
115  

115  

116  
    U* head_ = nullptr;
116  
    U* head_ = nullptr;
117  

117  

118  
#if !defined(BOOST_URL_DISABLE_THREADS)
118  
#if !defined(BOOST_URL_DISABLE_THREADS)
119  
    std::mutex m_;
119  
    std::mutex m_;
120  
#endif
120  
#endif
121  
};
121  
};
122  

122  

123  
//------------------------------------------------
123  
//------------------------------------------------
124  

124  

125  
/** A pointer to a shared instance of T
125  
/** A pointer to a shared instance of T
126  

126  

127  
    This is a smart pointer container which can
127  
    This is a smart pointer container which can
128  
    acquire shared ownership of an instance of
128  
    acquire shared ownership of an instance of
129  
    `T` upon or after construction. The instance
129  
    `T` upon or after construction. The instance
130  
    is guaranteed to be in a valid, but unknown
130  
    is guaranteed to be in a valid, but unknown
131  
    state. Every recycled pointer references
131  
    state. Every recycled pointer references
132  
    a valid recycle bin.
132  
    a valid recycle bin.
133  

133  

134  
    @par Example
134  
    @par Example
135  
    @code
135  
    @code
136  
    static recycled< std::string > bin;
136  
    static recycled< std::string > bin;
137  

137  

138  
    recycled_ptr< std::string > ps( bin );
138  
    recycled_ptr< std::string > ps( bin );
139  

139  

140  
    // Put the string into a known state
140  
    // Put the string into a known state
141  
    ps->clear();
141  
    ps->clear();
142  
    @endcode
142  
    @endcode
143  

143  

144  
    @tparam T the type of object to
144  
    @tparam T the type of object to
145  
        acquire, which must be
145  
        acquire, which must be
146  
        <em>DefaultConstructible</em>.
146  
        <em>DefaultConstructible</em>.
147  
*/
147  
*/
148  
template<class T>
148  
template<class T>
149  
class recycled_ptr
149  
class recycled_ptr
150  
{
150  
{
151  
    // T must be default constructible!
151  
    // T must be default constructible!
152  
    static_assert(
152  
    static_assert(
153  
        std::is_default_constructible<T>::value,
153  
        std::is_default_constructible<T>::value,
154  
        "T must be DefaultConstructible");
154  
        "T must be DefaultConstructible");
155  

155  

156  
    friend class recycled<T>;
156  
    friend class recycled<T>;
157  

157  

158  
    using B = recycled<T>;
158  
    using B = recycled<T>;
159  
    using U = typename B::U;
159  
    using U = typename B::U;
160  

160  

161  
    B* bin_ = nullptr;
161  
    B* bin_ = nullptr;
162  
    U* p_ = nullptr;
162  
    U* p_ = nullptr;
163  

163  

164  
public:
164  
public:
165  
    /** Destructor
165  
    /** Destructor
166  

166  

167  
        If this is not empty, shared ownership
167  
        If this is not empty, shared ownership
168  
        of the pointee is released. If this was
168  
        of the pointee is released. If this was
169  
        the last reference, the object is
169  
        the last reference, the object is
170  
        returned to the original recycle bin.
170  
        returned to the original recycle bin.
171  

171  

172  
        @par Effects
172  
        @par Effects
173  
        @code
173  
        @code
174  
        this->release();
174  
        this->release();
175  
        @endcode
175  
        @endcode
176  
    */
176  
    */
177  
    ~recycled_ptr();
177  
    ~recycled_ptr();
178  

178  

179  
    /** Constructor
179  
    /** Constructor
180  

180  

181  
        Upon construction, this acquires
181  
        Upon construction, this acquires
182  
        exclusive access to an object of type
182  
        exclusive access to an object of type
183  
        `T` which is either recycled from the
183  
        `T` which is either recycled from the
184  
        specified bin, or newly allocated.
184  
        specified bin, or newly allocated.
185  
        The object is in an unknown but
185  
        The object is in an unknown but
186  
        valid state.
186  
        valid state.
187  

187  

188  
        @par Example
188  
        @par Example
189  
        @code
189  
        @code
190  
        static recycled< std::string > bin;
190  
        static recycled< std::string > bin;
191  

191  

192  
        recycled_ptr< std::string > ps( bin );
192  
        recycled_ptr< std::string > ps( bin );
193  

193  

194  
        // Put the string into a known state
194  
        // Put the string into a known state
195  
        ps->clear();
195  
        ps->clear();
196  
        @endcode
196  
        @endcode
197  

197  

198  
        @par Postconditions
198  
        @par Postconditions
199  
        @code
199  
        @code
200  
        &this->bin() == &bin && ! this->empty()
200  
        &this->bin() == &bin && ! this->empty()
201  
        @endcode
201  
        @endcode
202  

202  

203  
        @param bin The recycle bin to use
203  
        @param bin The recycle bin to use
204  

204  

205  
        @see
205  
        @see
206  
            @ref recycled.
206  
            @ref recycled.
207  
    */
207  
    */
208  
    explicit
208  
    explicit
209  
    recycled_ptr(recycled<T>& bin);
209  
    recycled_ptr(recycled<T>& bin);
210  

210  

211  
    /** Constructor
211  
    /** Constructor
212  

212  

213  
        After construction, this is empty and
213  
        After construction, this is empty and
214  
        refers to the specified recycle bin.
214  
        refers to the specified recycle bin.
215  

215  

216  
        @par Example
216  
        @par Example
217  
        @code
217  
        @code
218  
        static recycled< std::string > bin;
218  
        static recycled< std::string > bin;
219  

219  

220  
        recycled_ptr< std::string > ps( bin, nullptr );
220  
        recycled_ptr< std::string > ps( bin, nullptr );
221  

221  

222  
        // Acquire a string and put it into a known state
222  
        // Acquire a string and put it into a known state
223  
        ps->acquire();
223  
        ps->acquire();
224  
        ps->clear();
224  
        ps->clear();
225  
        @endcode
225  
        @endcode
226  

226  

227  
        @par Postconditions
227  
        @par Postconditions
228  
        @code
228  
        @code
229  
        &this->bin() == &bin && this->empty()
229  
        &this->bin() == &bin && this->empty()
230  
        @endcode
230  
        @endcode
231  

231  

232  
        @par Exception Safety
232  
        @par Exception Safety
233  
        Throws nothing.
233  
        Throws nothing.
234  

234  

235  
        @param bin The recycle bin to use
235  
        @param bin The recycle bin to use
236  

236  

237  
        @see
237  
        @see
238  
            @ref acquire,
238  
            @ref acquire,
239  
            @ref recycled,
239  
            @ref recycled,
240  
            @ref release.
240  
            @ref release.
241  
    */
241  
    */
242  
    recycled_ptr(
242  
    recycled_ptr(
243  
        recycled<T>& bin,
243  
        recycled<T>& bin,
244  
        std::nullptr_t) noexcept;
244  
        std::nullptr_t) noexcept;
245  

245  

246  
    /** Constructor
246  
    /** Constructor
247  

247  

248  
        Upon construction, this acquires
248  
        Upon construction, this acquires
249  
        exclusive access to an object of type
249  
        exclusive access to an object of type
250  
        `T` which is either recycled from a
250  
        `T` which is either recycled from a
251  
        global recycle bin, or newly allocated.
251  
        global recycle bin, or newly allocated.
252  
        The object is in an unknown but
252  
        The object is in an unknown but
253  
        valid state.
253  
        valid state.
254  

254  

255  
        @par Example
255  
        @par Example
256  
        @code
256  
        @code
257  
        recycled_ptr< std::string > ps;
257  
        recycled_ptr< std::string > ps;
258  

258  

259  
        // Put the string into a known state
259  
        // Put the string into a known state
260  
        ps->clear();
260  
        ps->clear();
261  
        @endcode
261  
        @endcode
262  

262  

263  
        @par Postconditions
263  
        @par Postconditions
264  
        @code
264  
        @code
265  
        &this->bin() != nullptr && ! this->empty()
265  
        &this->bin() != nullptr && ! this->empty()
266  
        @endcode
266  
        @endcode
267  

267  

268  
        @see
268  
        @see
269  
            @ref recycled.
269  
            @ref recycled.
270  
    */
270  
    */
271  
    recycled_ptr();
271  
    recycled_ptr();
272  

272  

273  
    /** Constructor
273  
    /** Constructor
274  

274  

275  
        After construction, this is empty
275  
        After construction, this is empty
276  
        and refers to a global recycle bin.
276  
        and refers to a global recycle bin.
277  

277  

278  
        @par Example
278  
        @par Example
279  
        @code
279  
        @code
280  
        recycled_ptr< std::string > ps( nullptr );
280  
        recycled_ptr< std::string > ps( nullptr );
281  

281  

282  
        // Acquire a string and put it into a known state
282  
        // Acquire a string and put it into a known state
283  
        ps->acquire();
283  
        ps->acquire();
284  
        ps->clear();
284  
        ps->clear();
285  
        @endcode
285  
        @endcode
286  

286  

287  
        @par Postconditions
287  
        @par Postconditions
288  
        @code
288  
        @code
289  
        &this->bin() != nullptr && this->empty()
289  
        &this->bin() != nullptr && this->empty()
290  
        @endcode
290  
        @endcode
291  

291  

292  
        @par Exception Safety
292  
        @par Exception Safety
293  
        Throws nothing.
293  
        Throws nothing.
294  

294  

295  
        @see
295  
        @see
296  
            @ref acquire,
296  
            @ref acquire,
297  
            @ref recycled,
297  
            @ref recycled,
298  
            @ref release.
298  
            @ref release.
299  
    */
299  
    */
300  
    recycled_ptr(
300  
    recycled_ptr(
301  
        std::nullptr_t) noexcept;
301  
        std::nullptr_t) noexcept;
302  

302  

303  
    /** Constructor
303  
    /** Constructor
304  

304  

305  
        If `other` references an object, the
305  
        If `other` references an object, the
306  
        newly constructed pointer acquires
306  
        newly constructed pointer acquires
307  
        shared ownership. Otherwise this is
307  
        shared ownership. Otherwise this is
308  
        empty. The new pointer references
308  
        empty. The new pointer references
309  
        the same recycle bin as `other`.
309  
        the same recycle bin as `other`.
310  

310  

311  
        @par Postconditions
311  
        @par Postconditions
312  
        @code
312  
        @code
313  
        &this->bin() == &other->bin() && this->get() == other.get()
313  
        &this->bin() == &other->bin() && this->get() == other.get()
314  
        @endcode
314  
        @endcode
315  

315  

316  
        @par Exception Safety
316  
        @par Exception Safety
317  
        Throws nothing.
317  
        Throws nothing.
318  

318  

319  
        @param other The pointer to copy
319  
        @param other The pointer to copy
320  
    */
320  
    */
321  
    recycled_ptr(
321  
    recycled_ptr(
322  
        recycled_ptr const& other) noexcept;
322  
        recycled_ptr const& other) noexcept;
323  

323  

324  
    /** Constructor
324  
    /** Constructor
325  

325  

326  
        If `other` references an object,
326  
        If `other` references an object,
327  
        ownership is transferred including
327  
        ownership is transferred including
328  
        a reference to the recycle bin. After
328  
        a reference to the recycle bin. After
329  
        the move, the moved-from object is empty.
329  
        the move, the moved-from object is empty.
330  

330  

331  
        @par Postconditions
331  
        @par Postconditions
332  
        @code
332  
        @code
333  
        &this->bin() == &other->bin() && ! this->empty() && other.empty()
333  
        &this->bin() == &other->bin() && ! this->empty() && other.empty()
334  
        @endcode
334  
        @endcode
335  

335  

336  
        @par Exception Safety
336  
        @par Exception Safety
337  
        Throws nothing.
337  
        Throws nothing.
338  

338  

339  
        @param other The pointer to move from
339  
        @param other The pointer to move from
340  
    */
340  
    */
341  
    recycled_ptr(
341  
    recycled_ptr(
342  
        recycled_ptr&& other) noexcept;
342  
        recycled_ptr&& other) noexcept;
343  

343  

344  
    /** Assignment
344  
    /** Assignment
345  

345  

346  
        If `other` references an object,
346  
        If `other` references an object,
347  
        ownership is transferred including
347  
        ownership is transferred including
348  
        a reference to the recycle bin. After
348  
        a reference to the recycle bin. After
349  
        the move, the moved-from object is empty.
349  
        the move, the moved-from object is empty.
350  

350  

351  
        @par Effects
351  
        @par Effects
352  
        @code
352  
        @code
353  
        this->release()
353  
        this->release()
354  
        @endcode
354  
        @endcode
355  

355  

356  
        @par Postconditions
356  
        @par Postconditions
357  
        @code
357  
        @code
358  
        &this->bin() == &other->bin()
358  
        &this->bin() == &other->bin()
359  
        @endcode
359  
        @endcode
360  

360  

361  
        @par Exception Safety
361  
        @par Exception Safety
362  
        Throws nothing.
362  
        Throws nothing.
363  

363  

364  
        @param other The pointer to move from
364  
        @param other The pointer to move from
365  
        @return `*this`
365  
        @return `*this`
366  
    */
366  
    */
367  
    recycled_ptr&
367  
    recycled_ptr&
368  
    operator=(
368  
    operator=(
369  
        recycled_ptr&& other) noexcept;
369  
        recycled_ptr&& other) noexcept;
370  

370  

371  
    /** Assignment
371  
    /** Assignment
372  

372  

373  
        If `other` references an object,
373  
        If `other` references an object,
374  
        this acquires shared ownership and
374  
        this acquires shared ownership and
375  
        references the same recycle bin as
375  
        references the same recycle bin as
376  
        `other`. The previous object if any
376  
        `other`. The previous object if any
377  
        is released.
377  
        is released.
378  

378  

379  
        @par Effects
379  
        @par Effects
380  
        @code
380  
        @code
381  
        this->release()
381  
        this->release()
382  
        @endcode
382  
        @endcode
383  

383  

384  
        @par Postconditions
384  
        @par Postconditions
385  
        @code
385  
        @code
386  
        &this->bin() == &other->bin() && this->get() == other.get()
386  
        &this->bin() == &other->bin() && this->get() == other.get()
387  
        @endcode
387  
        @endcode
388  

388  

389  
        @par Exception Safety
389  
        @par Exception Safety
390  
        Throws nothing.
390  
        Throws nothing.
391  

391  

392  
        @param other The pointer to copy from
392  
        @param other The pointer to copy from
393  
        @return `*this`
393  
        @return `*this`
394  
    */
394  
    */
395  
    recycled_ptr&
395  
    recycled_ptr&
396  
    operator=(
396  
    operator=(
397  
        recycled_ptr const& other) noexcept;
397  
        recycled_ptr const& other) noexcept;
398  

398  

399  
    /** Return true if this does not reference an object
399  
    /** Return true if this does not reference an object
400  

400  

401  
        @par Exception Safety
401  
        @par Exception Safety
402  
        Throws nothing.
402  
        Throws nothing.
403  

403  

404  
        @return `p_ == nullptr`
404  
        @return `p_ == nullptr`
405  
    */
405  
    */
406  
    bool
406  
    bool
407  
    empty() const noexcept
407  
    empty() const noexcept
408  
    {
408  
    {
409  
        return p_ == nullptr;
409  
        return p_ == nullptr;
410  
    }
410  
    }
411  

411  

412  
    /** Return true if this references an object
412  
    /** Return true if this references an object
413  

413  

414  
        @par Effects
414  
        @par Effects
415  
        @code
415  
        @code
416  
        return ! this->empty();
416  
        return ! this->empty();
417  
        @endcode
417  
        @endcode
418  

418  

419  
        @par Exception Safety
419  
        @par Exception Safety
420  
        Throws nothing.
420  
        Throws nothing.
421  

421  

422  
        @return `!this->empty()`
422  
        @return `!this->empty()`
423  
    */
423  
    */
424  
    explicit
424  
    explicit
425  
    operator bool() const noexcept
425  
    operator bool() const noexcept
426  
    {
426  
    {
427  
        return p_ != nullptr;
427  
        return p_ != nullptr;
428  
    }
428  
    }
429  

429  

430  
    /** Return the referenced recycle bin
430  
    /** Return the referenced recycle bin
431  

431  

432  
        @par Exception Safety
432  
        @par Exception Safety
433  
        Throws nothing.
433  
        Throws nothing.
434  

434  

435  
        @return A reference to the recycle bin
435  
        @return A reference to the recycle bin
436  
    */
436  
    */
437  
    recycled<T>&
437  
    recycled<T>&
438  
    bin() const noexcept
438  
    bin() const noexcept
439  
    {
439  
    {
440  
        return *bin_;
440  
        return *bin_;
441  
    }
441  
    }
442  

442  

443  
    /** Return the referenced object
443  
    /** Return the referenced object
444  

444  

445  
        If this is empty, `nullptr` is returned.
445  
        If this is empty, `nullptr` is returned.
446  

446  

447  
        @par Exception Safety
447  
        @par Exception Safety
448  
        Throws nothing.
448  
        Throws nothing.
449  

449  

450  
        @return A pointer to the object
450  
        @return A pointer to the object
451  
    */
451  
    */
452  
    T* get() const noexcept
452  
    T* get() const noexcept
453  
    {
453  
    {
454  
        return &p_->t;
454  
        return &p_->t;
455  
    }
455  
    }
456  

456  

457  
    /** Return the referenced object
457  
    /** Return the referenced object
458  

458  

459  
        If this is empty, `nullptr` is returned.
459  
        If this is empty, `nullptr` is returned.
460  

460  

461  
        @par Exception Safety
461  
        @par Exception Safety
462  
        Throws nothing.
462  
        Throws nothing.
463  

463  

464  
        @return A pointer to the object
464  
        @return A pointer to the object
465  
    */
465  
    */
466  
    T* operator->() const noexcept
466  
    T* operator->() const noexcept
467  
    {
467  
    {
468  
        return get();
468  
        return get();
469  
    }
469  
    }
470  

470  

471  
    /** Return the referenced object
471  
    /** Return the referenced object
472  

472  

473  
        @par Preconditions
473  
        @par Preconditions
474  
        @code
474  
        @code
475  
        not this->empty()
475  
        not this->empty()
476  
        @endcode
476  
        @endcode
477  

477  

478  
        @return A reference to the object
478  
        @return A reference to the object
479  
    */
479  
    */
480  
    T& operator*() const noexcept
480  
    T& operator*() const noexcept
481  
    {
481  
    {
482  
        return *get();
482  
        return *get();
483  
    }
483  
    }
484  

484  

485  
    /** Return the referenced object
485  
    /** Return the referenced object
486  

486  

487  
        If this references an object, it is
487  
        If this references an object, it is
488  
        returned. Otherwise, exclusive ownership
488  
        returned. Otherwise, exclusive ownership
489  
        of a new object of type `T` is acquired
489  
        of a new object of type `T` is acquired
490  
        and returned.
490  
        and returned.
491  

491  

492  
        @par Postconditions
492  
        @par Postconditions
493  
        @code
493  
        @code
494  
        not this->empty()
494  
        not this->empty()
495  
        @endcode
495  
        @endcode
496  

496  

497  
        @return A reference to the object
497  
        @return A reference to the object
498  
    */
498  
    */
499  
    T& acquire();
499  
    T& acquire();
500  

500  

501  
    /** Release the referenced object
501  
    /** Release the referenced object
502  

502  

503  
        If this references an object, it is
503  
        If this references an object, it is
504  
        released to the referenced recycle bin.
504  
        released to the referenced recycle bin.
505  
        The pointer continues to reference
505  
        The pointer continues to reference
506  
        the same recycle bin.
506  
        the same recycle bin.
507  

507  

508  
        @par Postconditions
508  
        @par Postconditions
509  
        @code
509  
        @code
510  
        this->empty()
510  
        this->empty()
511  
        @endcode
511  
        @endcode
512  

512  

513  
        @par Exception Safety
513  
        @par Exception Safety
514  
        Throws nothing.
514  
        Throws nothing.
515  
    */
515  
    */
516  
    void release() noexcept;
516  
    void release() noexcept;
517  
};
517  
};
518  

518  

519  
} // grammar
519  
} // grammar
520  
} // urls
520  
} // urls
521  
} // boost
521  
} // boost
522  

522  

523  
#include <boost/url/grammar/impl/recycled.hpp>
523  
#include <boost/url/grammar/impl/recycled.hpp>
524  

524  

525  
#endif
525  
#endif