Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:27

0001 //
0002 // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_GRAMMAR_IMPL_RECYCLED_PTR_HPP
0011 #define BOOST_URL_GRAMMAR_IMPL_RECYCLED_PTR_HPP
0012 
0013 #include <boost/assert.hpp>
0014 
0015 namespace boost {
0016 namespace urls {
0017 namespace grammar {
0018 
0019 //------------------------------------------------
0020 
0021 template<class T>
0022 recycled<T>::
0023 ~recycled()
0024 {
0025     std::size_t n = 0;
0026     // VFALCO we should probably deallocate
0027     // in reverse order of allocation but
0028     // that requires a doubly-linked list.
0029     auto it = head_;
0030     while(it)
0031     {
0032         ++n;
0033         auto next = it->next;
0034         BOOST_ASSERT(
0035             it->refs == 0);
0036         delete it;
0037         it = next;
0038     }
0039     detail::recycled_remove(
0040         sizeof(U) * n);
0041 }
0042 
0043 template<class T>
0044 auto
0045 recycled<T>::
0046 acquire() ->
0047     U*
0048 {
0049     U* p;
0050     {
0051 #if !defined(BOOST_URL_DISABLE_THREADS)
0052         std::lock_guard<
0053             std::mutex> lock(m_);
0054 #endif
0055         p = head_;
0056         if(p)
0057         {
0058             // reuse
0059             head_ = head_->next;
0060             detail::recycled_remove(
0061                 sizeof(U));
0062             ++p->refs;
0063         }
0064         else
0065         {
0066             p = new U;
0067         }
0068     }
0069     BOOST_ASSERT(p->refs == 1);
0070     return p;
0071 }
0072 
0073 template<class T>
0074 void
0075 recycled<T>::
0076 release(U* u) noexcept
0077 {
0078     if(--u->refs != 0)
0079         return;
0080     {
0081 #if !defined(BOOST_URL_DISABLE_THREADS)
0082         std::lock_guard<
0083             std::mutex> lock(m_);
0084 #endif
0085         u->next = head_;
0086         head_ = u;
0087     }
0088     detail::recycled_add(
0089         sizeof(U));
0090 }
0091 
0092 //------------------------------------------------
0093 
0094 template<class T>
0095 recycled_ptr<T>::
0096 ~recycled_ptr()
0097 {
0098     if(p_)
0099         bin_->release(p_);
0100 }
0101 
0102 template<class T>
0103 recycled_ptr<T>::
0104 recycled_ptr(
0105     recycled<T>& bin)
0106     : bin_(&bin)
0107     , p_(bin.acquire())
0108 {
0109 }
0110 
0111 template<class T>
0112 recycled_ptr<T>::
0113 recycled_ptr(
0114     recycled<T>& bin,
0115     std::nullptr_t) noexcept
0116     : bin_(&bin)
0117 {
0118 }
0119 
0120 template<class T>
0121 recycled_ptr<T>::
0122 recycled_ptr()
0123     : recycled_ptr(nullptr)
0124 {
0125     p_ = bin_->acquire();
0126 }
0127 
0128 template<class T>
0129 recycled_ptr<T>::
0130 recycled_ptr(
0131     std::nullptr_t) noexcept
0132     : recycled_ptr([]() -> B&
0133         {
0134             // VFALCO need guaranteed constexpr-init
0135             static B r;
0136             return r;
0137         }(), nullptr)
0138 {
0139 }
0140 
0141 template<class T>
0142 recycled_ptr<T>::
0143 recycled_ptr(
0144     recycled_ptr const& other) noexcept
0145     : bin_(other.bin_)
0146     , p_(other.p_)
0147 {
0148     if(p_)
0149         ++p_->refs;
0150 }
0151 
0152 template<class T>
0153 recycled_ptr<T>::
0154 recycled_ptr(
0155     recycled_ptr&& other) noexcept
0156     : bin_(other.bin_)
0157     , p_(other.p_)
0158 {
0159     other.p_ = nullptr;
0160 }
0161 
0162 template<class T>
0163 auto
0164 recycled_ptr<T>::
0165 operator=(
0166     recycled_ptr&& other) noexcept ->
0167         recycled_ptr&
0168 {
0169     BOOST_ASSERT(
0170         bin_ == other.bin_);
0171     if(p_)
0172         bin_->release(p_);
0173     p_ = other.p_;
0174     other.p_ = nullptr;
0175     return *this;
0176 }
0177 
0178 template<class T>
0179 auto
0180 recycled_ptr<T>::
0181 operator=(
0182     recycled_ptr const& other) noexcept ->
0183         recycled_ptr&
0184 {
0185     BOOST_ASSERT(
0186         bin_ == other.bin_);
0187     if(p_)
0188         bin_->release(p_);
0189     p_ = other.p_;
0190     if(p_)
0191         ++p_->refs;
0192     return *this;
0193 }
0194 
0195 template<class T>
0196 T&
0197 recycled_ptr<T>::
0198 acquire()
0199 {
0200     if(! p_)
0201         p_ = bin_->acquire();
0202     return p_->t;
0203 }
0204 
0205 template<class T>
0206 void
0207 recycled_ptr<T>::
0208 release() noexcept
0209 {
0210     if(p_)
0211     {
0212         bin_->release(p_);
0213         p_ = nullptr;
0214     }
0215 }
0216 
0217 } // grammar
0218 } // urls
0219 } // boost
0220 
0221 #endif