File indexing completed on 2025-01-18 09:53:27
0001
0002
0003
0004
0005
0006
0007
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
0027
0028
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
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
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 }
0218 }
0219 }
0220
0221 #endif