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: 2024-08-19 20:08:54 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              : #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            3 :         U()
     122            3 :             : refs{1}
     123              :         {
     124            3 :         }
     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           12 :     operator bool() const noexcept
     436              :     {
     437           12 :         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           30 :     T* get() const noexcept
     459              :     {
     460           30 :         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
        

Generated by: LCOV version 2.1