GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/impl/recycled.hpp
Date: 2024-08-20 16:05:55
Exec Total Coverage
Lines: 58 58 100.0%
Functions: 25 27 92.6%
Branches: 21 30 70.0%

Line Branch Exec Source
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
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
10 while(it)
31 {
32 5 ++n;
33 5 auto next = it->next;
34
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
5 BOOST_ASSERT(
35 it->refs == 0);
36
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
5 delete it;
37 5 it = next;
38 }
39 5 see_below::recycled_remove(
40 sizeof(U) * n);
41 5 }
42
43 template<class T>
44 auto
45 12 recycled<T>::
46 acquire() ->
47 U*
48 {
49 U* p;
50 {
51 #if !defined(BOOST_URL_DISABLE_THREADS)
52 std::lock_guard<
53
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
12 std::mutex> lock(m_);
54 #endif
55 12 p = head_;
56
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
12 if(p)
57 {
58 // reuse
59 7 head_ = head_->next;
60 7 see_below::recycled_remove(
61 sizeof(U));
62 7 ++p->refs;
63 }
64 else
65 {
66
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
5 p = new U;
67 }
68 12 }
69
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
12 BOOST_ASSERT(p->refs == 1);
70 12 return p;
71 }
72
73 template<class T>
74 void
75 14 recycled<T>::
76 release(U* u) noexcept
77 {
78
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8 times.
14 if(--u->refs != 0)
79 2 return;
80 {
81 #if !defined(BOOST_URL_DISABLE_THREADS)
82 std::lock_guard<
83 12 std::mutex> lock(m_);
84 #endif
85 12 u->next = head_;
86 12 head_ = u;
87 12 }
88 12 see_below::recycled_add(
89 sizeof(U));
90 }
91
92 //------------------------------------------------
93
94 template<class T>
95 30 recycled_ptr<T>::
96 ~recycled_ptr()
97 {
98
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
30 if(p_)
99 14 bin_->release(p_);
100 30 }
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 12 recycled_ptr<T>::
113 recycled_ptr(
114 recycled<T>& bin,
115 std::nullptr_t) noexcept
116 12 : bin_(&bin)
117 {
118 12 }
119
120 template<class T>
121 12 recycled_ptr<T>::
122 recycled_ptr()
123 12 : recycled_ptr(nullptr)
124 {
125
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
12 p_ = bin_->acquire();
126 12 }
127
128 template<class T>
129 12 recycled_ptr<T>::
130 recycled_ptr(
131 std::nullptr_t) noexcept
132 8 : recycled_ptr([]() -> B&
133 {
134 // VFALCO need guaranteed constexpr-init
135
6/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
8 static B r;
136 8 return r;
137 12 }(), nullptr)
138 {
139 12 }
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
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(p_)
149 2 ++p_->refs;
150 2 }
151
152 template<class T>
153 16 recycled_ptr<T>::
154 recycled_ptr(
155 recycled_ptr&& other) noexcept
156 16 : bin_(other.bin_)
157 16 , p_(other.p_)
158 {
159 16 other.p_ = nullptr;
160 16 }
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
222