GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 97.1% 507 / 0 / 522
Functions: 100.0% 78 / 0 / 78
Branches: 77.8% 147 / 0 / 189

libs/capy/include/boost/capy/buffers/slice.hpp
Line Branch Exec Source
1 //
2 // Copyright (c) 2025 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/cppalliance/capy
8 //
9
10 #ifndef BOOST_CAPY_BUFFERS_SLICE_HPP
11 #define BOOST_CAPY_BUFFERS_SLICE_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/capy/buffers.hpp>
15 #include <boost/capy/buffers/range.hpp>
16 #include <boost/assert.hpp>
17 #include <array>
18 #include <iterator>
19 #include <type_traits>
20
21 namespace boost {
22 namespace capy {
23
24 template<class T> class slice_of;
25
26 namespace detail {
27
28 template<class T, class = void>
29 struct has_tag_invoke : std::false_type {};
30
31 template<class T>
32 struct has_tag_invoke<T, decltype(tag_invoke(
33 std::declval<slice_tag const&>(),
34 std::declval<T&>(),
35 std::declval<slice_how>(),
36 std::declval<std::size_t>()))>
37 : std::true_type {};
38
39 } // detail
40
41 /** Alias for the type representing a slice of T
42 */
43 template<class T>
44 using slice_type = std::conditional_t<
45 detail::has_tag_invoke<T>::value,
46 T, slice_of<T>>;
47
48 //------------------------------------------------
49
50 /** A wrapper enabling a buffer sequence to be consumed
51 */
52 template<ConstBufferSequence BufferSequence>
53 class slice_of<BufferSequence>
54 {
55 static_assert(!std::is_const_v<BufferSequence>,
56 "BufferSequence can't be const");
57
58 static_assert(!std::is_reference_v<BufferSequence>,
59 "BufferSequence can't be a reference");
60
61 using iter_type = decltype(
62 std::declval<BufferSequence const&>().begin());
63
64 using difference_type =
65 typename std::iterator_traits<iter_type>::difference_type;
66
67 BufferSequence bs_;
68 difference_type begin_ = 0; // index of first buffer in sequence
69 difference_type end_ = 0; // 1 + index of last buffer in sequence
70 std::size_t len_ = 0; // length of bs_
71 std::size_t size_ = 0; // total bytes
72 std::size_t prefix_ = 0; // used prefix bytes
73 std::size_t suffix_ = 0; // used suffix bytes
74
75 public:
76 /** The type of values returned by iterators
77 */
78 using value_type = std::conditional_t<
79 MutableBufferSequence<BufferSequence>,
80 mutable_buffer, const_buffer>;
81
82 /** The type of returned iterators
83 */
84 class const_iterator
85 {
86 iter_type it_;
87 // VFALCO we could just point back to
88 // the original sequence to save size
89 std::size_t prefix_ = 0;
90 std::size_t suffix_ = 0;
91 std::size_t i_ = 0;
92 std::size_t n_ = 0;
93
94 friend class slice_of<BufferSequence>;
95
96 6588 const_iterator(
97 iter_type it,
98 std::size_t prefix__,
99 std::size_t suffix__,
100 std::size_t i,
101 std::size_t n) noexcept
102 6588 : it_(it)
103 6588 , prefix_(prefix__)
104 6588 , suffix_(suffix__)
105 6588 , i_(i)
106 6588 , n_(n)
107 {
108 // n_ is the index of the end iterator
109 6588 }
110
111 public:
112 using value_type = typename slice_of::value_type;
113 using reference = value_type;
114 using pointer = void;
115 using difference_type = std::ptrdiff_t;
116 using iterator_category =
117 std::bidirectional_iterator_tag;
118 using iterator_concept = std::bidirectional_iterator_tag;
119
120 const_iterator() = default;
121
122 bool
123 9028 operator==(
124 const_iterator const& other) const noexcept
125 {
126 return
127 10040 it_ == other.it_ &&
128
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✗ Branch 1 not taken.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✗ Branch 1 not taken.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator==(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator const&) const:
✓ Branch 0 taken 2282 times.
✗ Branch 1 not taken.
3294 prefix_ == other.prefix_ &&
129
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✗ Branch 1 not taken.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✗ Branch 1 not taken.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator==(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator const&) const:
✓ Branch 0 taken 2282 times.
✗ Branch 1 not taken.
3294 suffix_ == other.suffix_ &&
130
9/12
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✓ Branch 1 taken 924 times.
✓ Branch 2 taken 506 times.
✗ Branch 3 not taken.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✓ Branch 1 taken 924 times.
✓ Branch 2 taken 506 times.
✗ Branch 3 not taken.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator==(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator const&) const:
✓ Branch 0 taken 2282 times.
✓ Branch 1 taken 3886 times.
✓ Branch 2 taken 2282 times.
✗ Branch 3 not taken.
15616 i_ == other.i_ &&
131
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✗ Branch 1 not taken.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator==(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator const&) const:
✓ Branch 0 taken 506 times.
✗ Branch 1 not taken.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator==(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator const&) const:
✓ Branch 0 taken 2282 times.
✗ Branch 1 not taken.
12322 n_ == other.n_;
132 }
133
134 bool
135 9028 operator!=(
136 const_iterator const& other) const noexcept
137 {
138 9028 return !(*this == other);
139 }
140
141 reference
142 5734 operator*() const noexcept
143 {
144 5734 value_type v = *it_;
145 using P = std::conditional_t<
146 MutableBufferSequence<BufferSequence>,
147 char*, char const*>;
148 5734 auto p = reinterpret_cast<P>(v.data());
149 5734 auto n = v.size();
150
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator*() const:
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 484 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator*() const:
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 484 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator*() const:
✓ Branch 0 taken 2036 times.
✓ Branch 1 taken 1850 times.
5734 if(i_ == 0)
151 {
152 2916 p += prefix_;
153 2916 n -= prefix_;
154 }
155
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator*() const:
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 484 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator*() const:
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 484 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator*() const:
✓ Branch 0 taken 2036 times.
✓ Branch 1 taken 1850 times.
5734 if(i_ == n_ - 1)
156 2916 n -= suffix_;
157 5734 return value_type(p, n);
158 }
159
160 const_iterator&
161 4446 operator++() noexcept
162 {
163
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator++():
✗ Branch 0 not taken.
✓ Branch 1 taken 612 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator++():
✗ Branch 0 not taken.
✓ Branch 1 taken 612 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator++():
✗ Branch 0 not taken.
✓ Branch 1 taken 3222 times.
4446 BOOST_ASSERT(i_ < n_);
164 4446 ++it_;
165 4446 ++i_;
166 4446 return *this;
167 }
168
169 const_iterator
170 644 operator++(int) noexcept
171 {
172 644 auto temp = *this;
173 644 ++(*this);
174 644 return temp;
175 }
176
177 const_iterator&
178 1288 operator--() noexcept
179 {
180
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::const_iterator::operator--():
✗ Branch 0 not taken.
✓ Branch 1 taken 312 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::const_iterator::operator--():
✗ Branch 0 not taken.
✓ Branch 1 taken 312 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::const_iterator::operator--():
✗ Branch 0 not taken.
✓ Branch 1 taken 664 times.
1288 BOOST_ASSERT(i_ > 0);
181 1288 --it_;
182 1288 --i_;
183 1288 return *this;
184 }
185
186 const_iterator
187 644 operator--(int) noexcept
188 {
189 644 auto temp = *this;
190 644 --(*this);
191 644 return temp;
192 }
193 };
194
195 /** Constructor
196 */
197 slice_of() = default;
198
199 /** Constructor
200 */
201 176 slice_of(
202 BufferSequence const& bs)
203 176 : bs_(bs)
204 {
205 176 iter_type it = capy::begin(bs_);
206 176 iter_type eit = capy::end(bs_);
207 176 begin_ = 0;
208 176 end_ = std::distance(it, eit);
209
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::slice_of(boost::span<boost::capy::const_buffer const, 18446744073709551615ul> const&):
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 44 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::slice_of(boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> const&):
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 44 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::slice_of(std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > const&):
✓ Branch 1 taken 264 times.
✓ Branch 2 taken 88 times.
704 while(it != eit)
210 {
211 528 value_type b(*it);
212 528 size_ += b.size();
213 528 ++len_;
214 528 ++it;
215 }
216 176 }
217
218 /** Return an iterator to the beginning of the sequence
219 */
220 const_iterator
221 3294 begin() const noexcept
222 {
223 return const_iterator(
224 3294 begin_iter_impl(), prefix_, suffix_, 0, len_);
225 }
226
227 /** Return an iterator to the end of the sequence
228 */
229 const_iterator
230 3294 end() const noexcept
231 {
232 return const_iterator(
233 3294 end_iter_impl(), prefix_, suffix_, len_, len_);
234 }
235
236 friend
237 void
238 653 tag_invoke(
239 slice_tag const&,
240 slice_of<BufferSequence>& bs,
241 slice_how how,
242 std::size_t n)
243 {
244 653 bs.slice_impl(how, n);
245 653 }
246
247 private:
248 iter_type
249 3890 begin_iter_impl() const noexcept
250 {
251 3890 iter_type it = capy::begin(bs_);
252 3890 std::advance(it, begin_);
253 3890 return it;
254 }
255
256 iter_type
257 3554 end_iter_impl() const noexcept
258 {
259 3554 iter_type it = capy::begin(bs_);
260 3554 std::advance(it, end_);
261 3554 return it;
262 }
263
264 void
265 336 remove_prefix_impl(
266 std::size_t n)
267 {
268
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_prefix_impl(unsigned long):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 19 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_prefix_impl(unsigned long):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 19 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_prefix_impl(unsigned long):
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 273 times.
336 if(n > size_)
269 25 n = size_;
270
271 // nice hack to simplify the loop (M. Nejati)
272 336 n += prefix_;
273 336 size_ += prefix_;
274 336 prefix_ = 0;
275
276 336 iter_type it = begin_iter_impl();
277
278
9/12
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_prefix_impl(unsigned long):
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_prefix_impl(unsigned long):
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_prefix_impl(unsigned long):
✓ Branch 0 taken 518 times.
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 518 times.
✗ Branch 3 not taken.
687 while(n > 0 && begin_ != end_)
279 {
280 596 value_type b = *it;
281
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_prefix_impl(unsigned long):
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 27 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_prefix_impl(unsigned long):
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 27 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_prefix_impl(unsigned long):
✓ Branch 1 taken 221 times.
✓ Branch 2 taken 297 times.
596 if(n < b.size())
282 {
283 245 prefix_ = n;
284 245 size_ -= n;
285 245 break;
286 }
287 351 n -= b.size();
288 351 size_ -= b.size();
289 351 ++begin_;
290 351 ++it;
291 351 --len_;
292 }
293 336 }
294
295 void
296 260 remove_suffix_impl(
297 std::size_t n)
298 {
299
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 228 times.
260 if(size_ == 0)
300 {
301 BOOST_ASSERT(begin_ == end_);
302 260 return;
303 }
304
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 228 times.
260 BOOST_ASSERT(begin_ != end_);
305
306
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_suffix_impl(unsigned long):
✗ Branch 0 not taken.
✓ Branch 1 taken 228 times.
260 if(n > size_)
307 n = size_;
308
309 260 n += suffix_;
310 260 size_ += suffix_;
311 260 suffix_ = 0;
312
313 260 iter_type bit = begin_iter_impl();
314 260 iter_type it = end_iter_impl();
315 260 it--;
316
317
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 6 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 6 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_suffix_impl(unsigned long):
✓ Branch 1 taken 325 times.
✓ Branch 2 taken 111 times.
504 while(it != bit)
318 {
319 381 value_type b = *it;
320
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 18 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 18 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_suffix_impl(unsigned long):
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 208 times.
381 if(n < b.size())
321 {
322 137 suffix_ = n;
323 137 size_ -= n;
324 137 return;
325 }
326 244 n -= b.size();
327 244 size_ -= b.size();
328 244 --it;
329 244 --end_;
330 244 --len_;
331 }
332 123 value_type b = *it;
333 123 auto m = b.size() - prefix_;
334
3/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::remove_suffix_impl(unsigned long):
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::remove_suffix_impl(unsigned long):
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
123 if(n < m)
335 {
336 123 suffix_ = n;
337 123 size_ -= n;
338 123 return;
339 }
340 end_ = begin_;
341 len_ = 0;
342 size_ = 0;
343 }
344
345 void
346 317 keep_prefix_impl(
347 std::size_t n)
348 {
349
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::keep_prefix_impl(unsigned long):
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::keep_prefix_impl(unsigned long):
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::keep_prefix_impl(unsigned long):
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 271 times.
317 if(n >= size_)
350 8 return;
351
6/6
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::keep_prefix_impl(unsigned long):
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::keep_prefix_impl(unsigned long):
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 16 times.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::keep_prefix_impl(unsigned long):
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 228 times.
309 if(n == 0)
352 {
353 49 end_ = begin_;
354 49 len_ = 0;
355 49 size_ = 0;
356 49 return;
357 }
358 260 remove_suffix_impl(size_ - n);
359 }
360
361 void
362 keep_suffix_impl(
363 std::size_t n)
364 {
365 if(n >= size_)
366 return;
367 if(n == 0)
368 {
369 begin_ = end_;
370 len_ = 0;
371 size_ = 0;
372 return;
373 }
374 remove_prefix_impl(size_ - n);
375 }
376
377 void
378 653 slice_impl(
379 slice_how how,
380 std::size_t n)
381 {
382
6/9
boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >::slice_impl(boost::capy::slice_how, unsigned long):
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >::slice_impl(boost::capy::slice_how, unsigned long):
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >::slice_impl(boost::capy::slice_how, unsigned long):
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 275 times.
✗ Branch 2 not taken.
653 switch(how)
383 {
384 336 case slice_how::remove_prefix:
385 {
386 336 remove_prefix_impl(n);
387 336 break;
388 }
389 317 case slice_how::keep_prefix:
390 {
391 317 keep_prefix_impl(n);
392 317 break;
393 }
394 }
395 653 }
396 };
397
398 //------------------------------------------------
399
400 // in-place modify return value
401 // -----------------------------
402 // keep_prefix* prefix
403 // keep_suffix suffix
404 // remove_prefix* sans_prefix
405 // remove_suffix sans_suffix
406
407 /** Remove all but the first `n` bytes from a buffer sequence
408 */
409 constexpr struct keep_prefix_mrdocs_workaround_t
410 {
411 template<ConstBufferSequence BufferSequence>
412 requires detail::has_tag_invoke<BufferSequence>::value
413 206454 void operator()(
414 BufferSequence& bs,
415 std::size_t n) const
416 {
417
3/3
void boost::capy::keep_prefix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 11 times.
void boost::capy::keep_prefix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 11 times.
void boost::capy::keep_prefix_mrdocs_workaround_t::operator()<boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > > >(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >&, unsigned long) const:
✓ Branch 1 taken 22 times.
206454 tag_invoke(slice_tag{}, bs, slice_how::keep_prefix, n);
418 206454 }
419 } const keep_prefix{};
420
421 /** Remove all but the last `n` bytes from a buffer sequence
422 */
423 constexpr struct keep_suffix_mrdocs_workaround_t
424 {
425 template<ConstBufferSequence BufferSequence>
426 requires detail::has_tag_invoke<BufferSequence>::value
427 70220 void operator()(
428 BufferSequence& bs,
429 std::size_t n) const
430 {
431 70220 auto n0 = buffer_size(bs);
432
10/10
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > > >(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >&, unsigned long) const:
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2 times.
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<std::array<boost::capy::const_buffer, 2ul> >(std::array<boost::capy::const_buffer, 2ul>&, unsigned long) const:
✓ Branch 0 taken 61680 times.
✓ Branch 1 taken 8224 times.
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<std::array<boost::capy::mutable_buffer, 2ul> >(std::array<boost::capy::mutable_buffer, 2ul>&, unsigned long) const:
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 32 times.
70220 if(n < n0)
433
3/3
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 9 times.
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 9 times.
void boost::capy::keep_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > > >(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >&, unsigned long) const:
✓ Branch 1 taken 20 times.
61958 tag_invoke(slice_tag{}, bs, slice_how::remove_prefix, n0 - n);
434 70220 }
435 } const keep_suffix{};
436
437 /** Remove `n` bytes from the beginning of a buffer sequence
438 */
439 constexpr struct remove_prefix_mrdocs_workaround_t
440 {
441 template<ConstBufferSequence BufferSequence>
442 requires detail::has_tag_invoke<BufferSequence>::value
443 202570 void operator()(
444 BufferSequence& bs,
445 std::size_t n) const
446 {
447
3/3
void boost::capy::remove_prefix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 11 times.
void boost::capy::remove_prefix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 11 times.
void boost::capy::remove_prefix_mrdocs_workaround_t::operator()<boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > > >(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >&, unsigned long) const:
✓ Branch 1 taken 276 times.
202570 tag_invoke(slice_tag{}, bs, slice_how::remove_prefix, n);
448 202570 }
449 } const remove_prefix{};
450
451 /** Remove `n` bytes from the end of a buffer sequence
452 */
453 constexpr struct remove_suffix_mrdocs_workaround_t
454 {
455 template<ConstBufferSequence BufferSequence>
456 requires detail::has_tag_invoke<BufferSequence>::value
457 70474 void operator()(
458 BufferSequence& bs,
459 std::size_t n) const
460 {
461 70474 auto n0 = buffer_size(bs);
462
10/10
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > > >(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >&, unsigned long) const:
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 23 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<std::array<boost::capy::const_buffer, 2ul> >(std::array<boost::capy::const_buffer, 2ul>&, unsigned long) const:
✓ Branch 0 taken 65792 times.
✓ Branch 1 taken 4112 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<std::array<boost::capy::mutable_buffer, 2ul> >(std::array<boost::capy::mutable_buffer, 2ul>&, unsigned long) const:
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 16 times.
70474 if(n > 0)
463 {
464
10/10
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 9 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 9 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > > >(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >&, unsigned long) const:
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 230 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<std::array<boost::capy::const_buffer, 2ul> >(std::array<boost::capy::const_buffer, 2ul>&, unsigned long) const:
✓ Branch 0 taken 4112 times.
✓ Branch 1 taken 61680 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<std::array<boost::capy::mutable_buffer, 2ul> >(std::array<boost::capy::mutable_buffer, 2ul>&, unsigned long) const:
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 240 times.
66321 if( n > n0)
465 4153 n = n0;
466
3/3
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::const_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 10 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::slice_of<boost::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >&, unsigned long) const:
✓ Branch 1 taken 10 times.
void boost::capy::remove_suffix_mrdocs_workaround_t::operator()<boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > > >(boost::capy::slice_of<std::vector<boost::capy::const_buffer, std::allocator<boost::capy::const_buffer> > >&, unsigned long) const:
✓ Branch 1 taken 253 times.
66321 tag_invoke(slice_tag{}, bs, slice_how::keep_prefix, n0 - n);
467 }
468 70474 }
469 } const remove_suffix{};
470
471 //------------------------------------------------
472
473 /** Return a sequence representing the first `n` bytes of a buffer sequence
474 */
475 constexpr struct prefix_mrdocs_workaround_t
476 {
477 template<ConstBufferSequence BufferSequence>
478 slice_type<BufferSequence> operator()(
479 BufferSequence const& bs,
480 std::size_t n) const noexcept
481 {
482 slice_type<BufferSequence> result(bs);
483 keep_prefix(result, n);
484 return result;
485 }
486 } prefix{};
487
488 /** Return a sequence representing the last `n` bytes of a buffer sequence
489 */
490 constexpr struct suffix_mrdocs_workaround_t
491 {
492 template<ConstBufferSequence BufferSequence>
493 slice_type<BufferSequence> operator()(
494 BufferSequence const& bs,
495 std::size_t n) const noexcept
496 {
497 slice_type<BufferSequence> result(bs);
498 keep_suffix(result, n);
499 return result;
500 }
501 } suffix{};
502
503 /** Return a sequence representing all but the first `n` bytes of a buffer sequence
504 */
505 constexpr struct sans_prefix_mrdocs_workaround_t
506 {
507 template<ConstBufferSequence BufferSequence>
508 slice_type<BufferSequence> operator()(
509 BufferSequence const& bs,
510 std::size_t n) const noexcept
511 {
512 slice_type<BufferSequence> result(bs);
513 remove_prefix(result, n);
514 return result;
515 }
516 } sans_prefix{};
517
518 /** Return a sequence representing all but the last `n` bytes of a buffer sequence
519 */
520 constexpr struct sans_suffix_mrdocs_workaround_t
521 {
522 template<ConstBufferSequence BufferSequence>
523 slice_type<BufferSequence> operator()(
524 BufferSequence const& bs,
525 std::size_t n) const noexcept
526 {
527 slice_type<BufferSequence> result(bs);
528 remove_suffix(result, n);
529 return result;
530 }
531 } sans_suffix{};
532
533 } // capy
534 } // boost
535
536 #endif
537