LCOV - code coverage report
Current view: top level - boost/url/grammar/impl/recycled.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 58 58
Test Date: 2024-08-19 20:08:54 Functions: 93.1 % 29 27

            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_IMPL_RECYCLED_PTR_HPP
      11              : #define BOOST_URL_GRAMMAR_IMPL_RECYCLED_PTR_HPP
      12              : 
      13              : #include <boost/assert.hpp>
      14              : 
      15              : namespace boost {
      16              : namespace urls {
      17              : namespace grammar {
      18              : 
      19              : //------------------------------------------------
      20              : 
      21              : template<class T>
      22            3 : recycled<T>::
      23              : ~recycled()
      24              : {
      25            3 :     std::size_t n = 0;
      26              :     // VFALCO we should probably deallocate
      27              :     // in reverse order of allocation but
      28              :     // that requires a doubly-linked list.
      29            3 :     auto it = head_;
      30            6 :     while(it)
      31              :     {
      32            3 :         ++n;
      33            3 :         auto next = it->next;
      34            3 :         BOOST_ASSERT(
      35              :             it->refs == 0);
      36            3 :         delete it;
      37            3 :         it = next;
      38              :     }
      39            3 :     see_below::recycled_remove(
      40              :         sizeof(U) * n);
      41            3 : }
      42              : 
      43              : template<class T>
      44              : auto
      45            8 : recycled<T>::
      46              : acquire() ->
      47              :     U*
      48              : {
      49              :     U* p;
      50              :     {
      51              : #if !defined(BOOST_URL_DISABLE_THREADS)
      52              :         std::lock_guard<
      53            8 :             std::mutex> lock(m_);
      54              : #endif
      55            8 :         p = head_;
      56            8 :         if(p)
      57              :         {
      58              :             // reuse
      59            5 :             head_ = head_->next;
      60            5 :             see_below::recycled_remove(
      61              :                 sizeof(U));
      62            5 :             ++p->refs;
      63              :         }
      64              :         else
      65              :         {
      66            3 :             p = new U;
      67              :         }
      68            8 :     }
      69            8 :     BOOST_ASSERT(p->refs == 1);
      70            8 :     return p;
      71              : }
      72              : 
      73              : template<class T>
      74              : void
      75           10 : recycled<T>::
      76              : release(U* u) noexcept
      77              : {
      78           10 :     if(--u->refs != 0)
      79            2 :         return;
      80              :     {
      81              : #if !defined(BOOST_URL_DISABLE_THREADS)
      82              :         std::lock_guard<
      83            8 :             std::mutex> lock(m_);
      84              : #endif
      85            8 :         u->next = head_;
      86            8 :         head_ = u;
      87            8 :     }
      88            8 :     see_below::recycled_add(
      89              :         sizeof(U));
      90              : }
      91              : 
      92              : //------------------------------------------------
      93              : 
      94              : template<class T>
      95           18 : recycled_ptr<T>::
      96              : ~recycled_ptr()
      97              : {
      98           18 :     if(p_)
      99           10 :         bin_->release(p_);
     100           18 : }
     101              : 
     102              : template<class T>
     103              : recycled_ptr<T>::
     104              : recycled_ptr(
     105              :     recycled<T>& bin)
     106              :     : bin_(&bin)
     107              :     , p_(bin.acquire())
     108              : {
     109              : }
     110              : 
     111              : template<class T>
     112            8 : recycled_ptr<T>::
     113              : recycled_ptr(
     114              :     recycled<T>& bin,
     115              :     std::nullptr_t) noexcept
     116            8 :     : bin_(&bin)
     117              : {
     118            8 : }
     119              : 
     120              : template<class T>
     121            8 : recycled_ptr<T>::
     122              : recycled_ptr()
     123            8 :     : recycled_ptr(nullptr)
     124              : {
     125            8 :     p_ = bin_->acquire();
     126            8 : }
     127              : 
     128              : template<class T>
     129            8 : recycled_ptr<T>::
     130              : recycled_ptr(
     131              :     std::nullptr_t) noexcept
     132            8 :     : recycled_ptr([]() -> B&
     133              :         {
     134              :             // VFALCO need guaranteed constexpr-init
     135            8 :             static B r;
     136            8 :             return r;
     137            8 :         }(), nullptr)
     138              : {
     139            8 : }
     140              : 
     141              : template<class T>
     142            2 : recycled_ptr<T>::
     143              : recycled_ptr(
     144              :     recycled_ptr const& other) noexcept
     145            2 :     : bin_(other.bin_)
     146            2 :     , p_(other.p_)
     147              : {
     148            2 :     if(p_)
     149            2 :         ++p_->refs;
     150            2 : }
     151              : 
     152              : template<class T>
     153            8 : recycled_ptr<T>::
     154              : recycled_ptr(
     155              :     recycled_ptr&& other) noexcept
     156            8 :     : bin_(other.bin_)
     157            8 :     , p_(other.p_)
     158              : {
     159            8 :     other.p_ = nullptr;
     160            8 : }
     161              : 
     162              : template<class T>
     163              : auto
     164              : recycled_ptr<T>::
     165              : operator=(
     166              :     recycled_ptr&& other) noexcept ->
     167              :         recycled_ptr&
     168              : {
     169              :     BOOST_ASSERT(
     170              :         bin_ == other.bin_);
     171              :     if(p_)
     172              :         bin_->release(p_);
     173              :     p_ = other.p_;
     174              :     other.p_ = nullptr;
     175              :     return *this;
     176              : }
     177              : 
     178              : template<class T>
     179              : auto
     180              : recycled_ptr<T>::
     181              : operator=(
     182              :     recycled_ptr const& other) noexcept ->
     183              :         recycled_ptr&
     184              : {
     185              :     BOOST_ASSERT(
     186              :         bin_ == other.bin_);
     187              :     if(p_)
     188              :         bin_->release(p_);
     189              :     p_ = other.p_;
     190              :     if(p_)
     191              :         ++p_->refs;
     192              :     return *this;
     193              : }
     194              : 
     195              : template<class T>
     196              : T&
     197              : recycled_ptr<T>::
     198              : acquire()
     199              : {
     200              :     if(! p_)
     201              :         p_ = bin_->acquire();
     202              :     return p_->t;
     203              : }
     204              : 
     205              : template<class T>
     206              : void
     207              : recycled_ptr<T>::
     208              : release() noexcept
     209              : {
     210              :     if(p_)
     211              :     {
     212              :         bin_->release(p_);
     213              :         p_ = nullptr;
     214              :     }
     215              : }
     216              : 
     217              : } // grammar
     218              : } // urls
     219              : } // boost
     220              : 
     221              : #endif
        

Generated by: LCOV version 2.1