LCOV - code coverage report
Current view: top level - boost/url/grammar/recycled.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 9 9
Test Date: 2025-01-10 18:07:09 Functions: 100.0 % 11 11

            Line data    Source code
       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            3 :         U()
     106            3 :             : refs{1}
     107              :         {
     108            3 :         }
     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              :     */
     366              :     recycled_ptr&
     367              :     operator=(
     368              :         recycled_ptr&& other) noexcept;
     369              : 
     370              :     /** Assignment
     371              : 
     372              :         If `other` references an object,
     373              :         this acquires shared ownership and
     374              :         references the same recycle bin as
     375              :         `other`. The previous object if any
     376              :         is released.
     377              : 
     378              :         @par Effects
     379              :         @code
     380              :         this->release()
     381              :         @endcode
     382              : 
     383              :         @par Postconditions
     384              :         @code
     385              :         &this->bin() == &other->bin() && this->get() == other.get()
     386              :         @endcode
     387              : 
     388              :         @par Exception Safety
     389              :         Throws nothing.
     390              : 
     391              :         @param other The pointer to copy from
     392              :     */
     393              :     recycled_ptr&
     394              :     operator=(
     395              :         recycled_ptr const& other) noexcept;
     396              : 
     397              :     /** Return true if this does not reference an object
     398              : 
     399              :         @par Exception Safety
     400              :         Throws nothing.
     401              :     */
     402              :     bool
     403              :     empty() const noexcept
     404              :     {
     405              :         return p_ == nullptr;
     406              :     }
     407              : 
     408              :     /** Return true if this references an object
     409              : 
     410              :         @par Effects
     411              :         @code
     412              :         return ! this->empty();
     413              :         @endcode
     414              : 
     415              :         @par Exception Safety
     416              :         Throws nothing.
     417              :     */
     418              :     explicit
     419           12 :     operator bool() const noexcept
     420              :     {
     421           12 :         return p_ != nullptr;
     422              :     }
     423              : 
     424              :     /** Return the referenced recycle bin
     425              : 
     426              :         @par Exception Safety
     427              :         Throws nothing.
     428              :     */
     429              :     recycled<T>&
     430              :     bin() const noexcept
     431              :     {
     432              :         return *bin_;
     433              :     }
     434              : 
     435              :     /** Return the referenced object
     436              : 
     437              :         If this is empty, `nullptr` is returned.
     438              : 
     439              :         @par Exception Safety
     440              :         Throws nothing.
     441              :     */
     442           30 :     T* get() const noexcept
     443              :     {
     444           30 :         return &p_->t;
     445              :     }
     446              : 
     447              :     /** Return the referenced object
     448              : 
     449              :         If this is empty, `nullptr` is returned.
     450              : 
     451              :         @par Exception Safety
     452              :         Throws nothing.
     453              :     */
     454           30 :     T* operator->() const noexcept
     455              :     {
     456           30 :         return get();
     457              :     }
     458              : 
     459              :     /** Return the referenced object
     460              : 
     461              :         @par Preconditions
     462              :         @code
     463              :         not this->empty()
     464              :         @endcode
     465              :     */
     466              :     T& operator*() const noexcept
     467              :     {
     468              :         return *get();
     469              :     }
     470              : 
     471              :     /** Return the referenced object
     472              : 
     473              :         If this references an object, it is
     474              :         returned. Otherwise, exclusive ownership
     475              :         of a new object of type `T` is acquired
     476              :         and returned.
     477              : 
     478              :         @par Postconditions
     479              :         @code
     480              :         not this->empty()
     481              :         @endcode
     482              :     */
     483              :     T& acquire();
     484              : 
     485              :     /** Release the referenced object
     486              : 
     487              :         If this references an object, it is
     488              :         released to the referenced recycle bin.
     489              :         The pointer continues to reference
     490              :         the same recycle bin.
     491              : 
     492              :         @par Postconditions
     493              :         @code
     494              :         this->empty()
     495              :         @endcode
     496              : 
     497              :         @par Exception Safety
     498              :         Throws nothing.
     499              :     */
     500              :     void release() noexcept;
     501              : };
     502              : 
     503              : } // grammar
     504              : } // urls
     505              : } // boost
     506              : 
     507              : #include <boost/url/grammar/impl/recycled.hpp>
     508              : 
     509              : #endif
        

Generated by: LCOV version 2.1