Line data Source code
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_RANGE_HPP
11 : #define BOOST_BUFFERS_RANGE_HPP
12 :
13 : #include <boost/buffers/detail/config.hpp>
14 : #include <boost/buffers/const_buffer.hpp>
15 : #include <boost/buffers/mutable_buffer.hpp>
16 : #include <boost/buffers/type_traits.hpp>
17 : #include <type_traits>
18 :
19 : namespace boost {
20 : namespace buffers {
21 : namespace detail {
22 :
23 : struct begin_impl
24 : {
25 : template<class MutableBuffer>
26 : auto
27 578925 : operator()(
28 : MutableBuffer const& b) const noexcept ->
29 : typename std::enable_if<
30 : std::is_convertible<
31 : MutableBuffer const*,
32 : mutable_buffer const*>::value,
33 : mutable_buffer const*>::type
34 : {
35 : return static_cast<
36 : mutable_buffer const*>(
37 578925 : std::addressof(b));
38 : }
39 :
40 : template<class ConstBuffer>
41 : auto
42 295892 : operator()(
43 : ConstBuffer const& b) const noexcept ->
44 : typename std::enable_if<
45 : std::is_convertible<
46 : ConstBuffer const*,
47 : const_buffer const*>::value,
48 : const_buffer const*>::type
49 : {
50 : return static_cast<
51 : const_buffer const*>(
52 295892 : std::addressof(b));
53 : }
54 :
55 : template<class BufferSequence>
56 : auto
57 32944 : operator()(
58 : BufferSequence& bs) const noexcept ->
59 : typename std::enable_if<
60 : ! std::is_convertible<
61 : BufferSequence const*,
62 : const_buffer const*>::value &&
63 : ! std::is_convertible<
64 : BufferSequence const*,
65 : mutable_buffer const*>::value,
66 : decltype(bs.begin())>::type
67 : {
68 32944 : return bs.begin();
69 : }
70 :
71 : template<class BufferSequence>
72 : auto
73 1253720 : operator()(
74 : BufferSequence const& bs) const noexcept ->
75 : typename std::enable_if<
76 : ! std::is_convertible<
77 : BufferSequence const*,
78 : const_buffer const*>::value &&
79 : ! std::is_convertible<
80 : BufferSequence const*,
81 : mutable_buffer const*>::value,
82 : decltype(bs.begin())>::type
83 : {
84 1253720 : return bs.begin();
85 : }
86 : };
87 :
88 : struct end_impl
89 : {
90 : template<class MutableBuffer>
91 : auto
92 578925 : operator()(
93 : MutableBuffer const& b) const noexcept ->
94 : typename std::enable_if<
95 : std::is_convertible<
96 : MutableBuffer const*,
97 : mutable_buffer const*>::value,
98 : mutable_buffer const*>::type
99 : {
100 : return static_cast<
101 : mutable_buffer const*>(
102 578925 : std::addressof(b)) + 1;
103 : }
104 :
105 : template<class ConstBuffer>
106 : auto
107 295892 : operator()(
108 : ConstBuffer const& b) const noexcept ->
109 : typename std::enable_if<
110 : std::is_convertible<
111 : ConstBuffer const*,
112 : const_buffer const*>::value,
113 : const_buffer const*>::type
114 : {
115 : return static_cast<
116 : const_buffer const*>(
117 295892 : std::addressof(b)) + 1;
118 : }
119 :
120 : template<class BufferSequence>
121 : auto
122 32944 : operator()(
123 : BufferSequence& bs) const noexcept ->
124 : typename std::enable_if<
125 : ! std::is_convertible<
126 : BufferSequence const*,
127 : const_buffer const*>::value &&
128 : ! std::is_convertible<
129 : BufferSequence const*,
130 : mutable_buffer const*>::value,
131 : decltype(bs.end())>::type
132 : {
133 32944 : return bs.end();
134 : }
135 :
136 : template<class BufferSequence>
137 : auto
138 1253720 : operator()(
139 : BufferSequence const& bs) const noexcept ->
140 : typename std::enable_if<
141 : ! std::is_convertible<
142 : BufferSequence const*,
143 : const_buffer const*>::value &&
144 : ! std::is_convertible<
145 : BufferSequence const*,
146 : mutable_buffer const*>::value,
147 : decltype(bs.end())>::type
148 : {
149 1253720 : return bs.end();
150 : }
151 : };
152 :
153 : } // detail
154 :
155 : /** Return an iterator to the beginning of the buffer sequence.
156 : */
157 : constexpr detail::begin_impl begin{};
158 :
159 : /** Return an iterator to the end of the buffer sequence.
160 : */
161 : constexpr detail::end_impl end{};
162 :
163 : //------------------------------------------------
164 :
165 : namespace detail {
166 :
167 : template<class T>
168 : class iter_range
169 : {
170 : using begin_type = decltype(
171 : buffers::begin(std::declval<T&>()));
172 : using end_type = decltype(
173 : buffers::end(std::declval<T&>()));
174 :
175 : begin_type begin_;
176 : end_type end_;
177 :
178 : public:
179 892875 : iter_range(T& t) noexcept
180 892875 : : begin_(buffers::begin(t))
181 892875 : , end_(buffers::end(t))
182 : {
183 892875 : }
184 :
185 : begin_type
186 892875 : begin() const noexcept
187 : {
188 892875 : return begin_;
189 : }
190 :
191 : end_type
192 892875 : end() const noexcept
193 : {
194 892875 : return end_;
195 : }
196 : };
197 :
198 : struct range_impl
199 : {
200 : template<class BufferSequence>
201 : auto
202 892875 : operator()(
203 : BufferSequence&& bs) const noexcept ->
204 : iter_range<typename
205 : std::remove_reference<
206 : BufferSequence>::type>
207 : {
208 892875 : return { bs };
209 : }
210 : };
211 :
212 : } // detail
213 :
214 : /** Return a range representing the buffer sequence.
215 : */
216 : constexpr detail::range_impl range{};
217 :
218 : } // buffers
219 : } // boost
220 :
221 : #endif
|