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

          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 :     detail::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          16 :             std::mutex> lock(m_);
      54             : #endif
      55           8 :         p = head_;
      56           8 :         if(p)
      57             :         {
      58             :             // reuse
      59           5 :             head_ = head_->next;
      60           5 :             detail::recycled_remove(
      61             :                 sizeof(U));
      62           5 :             ++p->refs;
      63             :         }
      64             :         else
      65             :         {
      66           3 :             p = new U;
      67             :         }
      68             :     }
      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             :     }
      88           8 :     detail::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 1.15