include/boost/url/grammar/impl/recycled.hpp

90.9% Lines (70/77) 100.0% Functions (38/38)
include/boost/url/grammar/impl/recycled.hpp
Line TLA Hits 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 5 recycled<T>::
23 ~recycled()
24 {
25 5 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 5 auto it = head_;
30 12 while(it)
31 {
32 7 ++n;
33 7 auto next = it->next;
34 7 BOOST_ASSERT(
35 it->refs == 0);
36 7 delete it;
37 7 it = next;
38 }
39 5 implementation_defined::recycled_remove(
40 sizeof(U) * n);
41 5 }
42
43 template<class T>
44 auto
45 18 recycled<T>::
46 acquire() ->
47 U*
48 {
49 U* p;
50 {
51 #if !defined(BOOST_URL_DISABLE_THREADS)
52 std::lock_guard<
53 18 std::mutex> lock(m_);
54 #endif
55 18 p = head_;
56 18 if(p)
57 {
58 // reuse
59 11 head_ = head_->next;
60 11 implementation_defined::recycled_remove(
61 sizeof(U));
62 11 ++p->refs;
63 }
64 else
65 {
66 7 p = new U;
67 }
68 18 }
69 18 BOOST_ASSERT(p->refs == 1);
70 18 return p;
71 }
72
73 template<class T>
74 void
75 24 recycled<T>::
76 release(U* u) noexcept
77 {
78 24 if(--u->refs != 0)
79 6 return;
80 {
81 #if !defined(BOOST_URL_DISABLE_THREADS)
82 std::lock_guard<
83 18 std::mutex> lock(m_);
84 #endif
85 18 u->next = head_;
86 18 head_ = u;
87 18 }
88 18 implementation_defined::recycled_add(
89 sizeof(U));
90 }
91
92 //------------------------------------------------
93
94 template<class T>
95 52 recycled_ptr<T>::
96 ~recycled_ptr()
97 {
98 52 if(p_)
99 23 bin_->release(p_);
100 52 }
101
102 template<class T>
103 1 recycled_ptr<T>::
104 recycled_ptr(
105 recycled<T>& bin)
106 1 : bin_(&bin)
107 1 , p_(bin.acquire())
108 {
109 1 }
110
111 template<class T>
112 17 recycled_ptr<T>::
113 recycled_ptr(
114 recycled<T>& bin,
115 std::nullptr_t) noexcept
116 17 : bin_(&bin)
117 {
118 17 }
119
120 template<class T>
121 17 recycled_ptr<T>::
122 recycled_ptr()
123 17 : recycled_ptr(nullptr)
124 {
125 17 p_ = bin_->acquire();
126 17 }
127
128 template<class T>
129 17 recycled_ptr<T>::
130 recycled_ptr(
131 std::nullptr_t) noexcept
132 24 : recycled_ptr([]() -> B&
133 {
134 // VFALCO need guaranteed constexpr-init
135 7 static B r;
136 7 return r;
137 17 }(), nullptr)
138 {
139 17 }
140
141 template<class T>
142 6 recycled_ptr<T>::
143 recycled_ptr(
144 recycled_ptr const& other) noexcept
145 6 : bin_(other.bin_)
146 6 , p_(other.p_)
147 {
148 6 if(p_)
149 6 ++p_->refs;
150 6 }
151
152 template<class T>
153 28 recycled_ptr<T>::
154 recycled_ptr(
155 recycled_ptr&& other) noexcept
156 28 : bin_(other.bin_)
157 28 , p_(other.p_)
158 {
159 28 other.p_ = nullptr;
160 28 }
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 1 recycled_ptr<T>::
181 operator=(
182 recycled_ptr const& other) noexcept ->
183 recycled_ptr&
184 {
185 1 if(this == &other)
186 1 return *this;
187 BOOST_ASSERT(
188 bin_ == other.bin_);
189 if(p_)
190 bin_->release(p_);
191 p_ = other.p_;
192 if(p_)
193 ++p_->refs;
194 return *this;
195 }
196
197 template<class T>
198 T&
199 recycled_ptr<T>::
200 acquire()
201 {
202 if(! p_)
203 p_ = bin_->acquire();
204 return p_->t;
205 }
206
207 template<class T>
208 void
209 1 recycled_ptr<T>::
210 release() noexcept
211 {
212 1 if(p_)
213 {
214 1 bin_->release(p_);
215 1 p_ = nullptr;
216 }
217 1 }
218
219 } // grammar
220 } // urls
221 } // boost
222
223 #endif
224