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

Generated by: LCOV version 2.1