Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2023 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/buffers | ||
8 | // | ||
9 | |||
10 | #ifndef BOOST_BUFFERS_ALGORITHM_HPP | ||
11 | #define BOOST_BUFFERS_ALGORITHM_HPP | ||
12 | |||
13 | #include <boost/buffers/detail/config.hpp> | ||
14 | #include <boost/buffers/buffer_size.hpp> | ||
15 | #include <boost/buffers/const_buffer.hpp> | ||
16 | #include <boost/buffers/mutable_buffer.hpp> | ||
17 | #include <boost/buffers/range.hpp> | ||
18 | #include <boost/buffers/tag_invoke.hpp> | ||
19 | #include <boost/buffers/type_traits.hpp> | ||
20 | |||
21 | namespace boost { | ||
22 | namespace buffers { | ||
23 | |||
24 | template<class BufferSequence> | ||
25 | void | ||
26 | tag_invoke( | ||
27 | prefix_tag const&, | ||
28 | BufferSequence const&, | ||
29 | std::size_t) = delete; | ||
30 | |||
31 | template<class BufferSequence> | ||
32 | void | ||
33 | tag_invoke( | ||
34 | suffix_tag const&, | ||
35 | BufferSequence const&, | ||
36 | std::size_t) = delete; | ||
37 | |||
38 | /** Returns the type of a prefix of a buffer sequence. | ||
39 | */ | ||
40 | template<class BufferSequence> | ||
41 | using prefix_type = decltype( | ||
42 | tag_invoke( | ||
43 | prefix_tag{}, | ||
44 | std::declval<BufferSequence const&>(), | ||
45 | std::size_t{})); | ||
46 | |||
47 | /** Returns the type of a suffix of a buffer sequence. | ||
48 | */ | ||
49 | template<class BufferSequence> | ||
50 | using suffix_type = decltype( | ||
51 | tag_invoke( | ||
52 | suffix_tag{}, | ||
53 | std::declval<BufferSequence const&>(), | ||
54 | std::size_t{})); | ||
55 | |||
56 | namespace detail { | ||
57 | |||
58 | struct prefix_impl | ||
59 | { | ||
60 | template<class BufferSequence> | ||
61 | prefix_type<BufferSequence> | ||
62 | 528670 | operator()( | |
63 | BufferSequence const& b, | ||
64 | std::size_t n) const | ||
65 | { | ||
66 | static_assert( | ||
67 | is_const_buffer_sequence< | ||
68 | BufferSequence>::value, | ||
69 | "Type requirements not met"); | ||
70 | |||
71 | 1057340 | return tag_invoke( | |
72 | 528670 | prefix_tag{}, b, n); | |
73 | } | ||
74 | }; | ||
75 | |||
76 | struct sans_suffix_impl | ||
77 | { | ||
78 | template<class BufferSequence> | ||
79 | prefix_type<BufferSequence> | ||
80 | 516 | operator()( | |
81 | BufferSequence const& b, | ||
82 | std::size_t n) const | ||
83 | { | ||
84 | 516 | auto const n0 = buffer_size(b); | |
85 |
2/2✓ Branch 0 taken 482 times.
✓ Branch 1 taken 32 times.
|
516 | if(n < n0) |
86 | 968 | return tag_invoke( | |
87 | 484 | prefix_tag{}, b, n0 - n); | |
88 | 64 | return tag_invoke( | |
89 | 32 | prefix_tag{}, b, 0); | |
90 | } | ||
91 | }; | ||
92 | |||
93 | struct suffix_impl | ||
94 | { | ||
95 | template<class BufferSequence> | ||
96 | suffix_type<BufferSequence> | ||
97 | 280608 | operator()( | |
98 | BufferSequence const& b, | ||
99 | std::size_t n) const | ||
100 | { | ||
101 | static_assert( | ||
102 | is_const_buffer_sequence< | ||
103 | BufferSequence>::value, | ||
104 | "Type requirements not met"); | ||
105 | |||
106 | 561216 | return tag_invoke( | |
107 | 280608 | suffix_tag{}, b, n); | |
108 | } | ||
109 | }; | ||
110 | |||
111 | struct sans_prefix_impl | ||
112 | { | ||
113 | template<class BufferSequence> | ||
114 | suffix_type<BufferSequence> | ||
115 | 280468 | operator()( | |
116 | BufferSequence const& b, | ||
117 | std::size_t n) const | ||
118 | { | ||
119 | static_assert( | ||
120 | is_const_buffer_sequence< | ||
121 | BufferSequence>::value, | ||
122 | "Type requirements not met"); | ||
123 | |||
124 | 280468 | auto const n0 = buffer_size(b); | |
125 |
2/2✓ Branch 0 taken 280432 times.
✓ Branch 1 taken 34 times.
|
280468 | if(n < n0) |
126 | 560868 | return tag_invoke( | |
127 | 280434 | suffix_tag{}, b, n0 - n); | |
128 | 68 | return tag_invoke( | |
129 | 34 | suffix_tag{}, b, 0); | |
130 | } | ||
131 | }; | ||
132 | |||
133 | struct front_impl | ||
134 | { | ||
135 | template< | ||
136 | class MutableBufferSequence | ||
137 | , class = typename std::enable_if< | ||
138 | is_mutable_buffer_sequence< | ||
139 | MutableBufferSequence>::value | ||
140 | >::type> | ||
141 | mutable_buffer | ||
142 | operator()( | ||
143 | MutableBufferSequence const& bs) const noexcept | ||
144 | { | ||
145 | auto const it = begin(bs); | ||
146 | if(it != end(bs)) | ||
147 | return *it; | ||
148 | return {}; | ||
149 | } | ||
150 | |||
151 | template< | ||
152 | class ConstBufferSequence | ||
153 | , class = typename std::enable_if< | ||
154 | ! is_mutable_buffer_sequence< | ||
155 | ConstBufferSequence>::value | ||
156 | >::type> | ||
157 | const_buffer | ||
158 | operator()( | ||
159 | ConstBufferSequence const& bs) const noexcept | ||
160 | { | ||
161 | static_assert( | ||
162 | is_const_buffer_sequence< | ||
163 | ConstBufferSequence>::value, | ||
164 | "Type requirements not met"); | ||
165 | |||
166 | auto const it = bs.begin(); | ||
167 | if(it != bs.end()) | ||
168 | return *it; | ||
169 | return {}; | ||
170 | } | ||
171 | }; | ||
172 | |||
173 | } // detail | ||
174 | |||
175 | /** Return a prefix of the buffer sequence. | ||
176 | */ | ||
177 | constexpr detail::prefix_impl prefix{}; | ||
178 | |||
179 | /** Return a suffix of the buffer sequence. | ||
180 | */ | ||
181 | constexpr detail::suffix_impl suffix{}; | ||
182 | |||
183 | /** Return a suffix of the buffer sequence. | ||
184 | */ | ||
185 | constexpr detail::sans_prefix_impl sans_prefix{}; | ||
186 | |||
187 | /** Return a prefix of the buffer sequence. | ||
188 | */ | ||
189 | constexpr detail::sans_suffix_impl sans_suffix{}; | ||
190 | |||
191 | /** Return the first buffer in a sequence. | ||
192 | */ | ||
193 | constexpr detail::front_impl front{}; | ||
194 | |||
195 | } // buffers | ||
196 | } // boost | ||
197 | |||
198 | #endif | ||
199 |