TLA 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/capy
8 : //
9 :
10 : #ifndef BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP
11 : #define BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP
12 :
13 : #include <boost/capy/detail/config.hpp>
14 : #include <boost/capy/buffers.hpp>
15 : #include <array>
16 : #include <cstdlib>
17 : #include <iterator>
18 : #include <ranges>
19 : #include <span>
20 : #include <string>
21 : #include <string_view>
22 : #include <type_traits>
23 : #include <vector>
24 :
25 : BOOST_CAPY_MSVC_WARNING_PUSH
26 : BOOST_CAPY_MSVC_WARNING_DISABLE(4459)
27 :
28 : namespace boost {
29 : namespace capy {
30 :
31 : /** Return a buffer.
32 : */
33 : [[nodiscard]] inline
34 : mutable_buffer
35 HIT 1 : make_buffer(
36 : mutable_buffer const& b) noexcept
37 : {
38 1 : return b;
39 : }
40 :
41 : /** Return a buffer with a maximum size.
42 : */
43 : [[nodiscard]] inline
44 : mutable_buffer
45 2 : make_buffer(
46 : mutable_buffer const& b,
47 : std::size_t max_size) noexcept
48 : {
49 5 : return mutable_buffer(
50 : b.data(),
51 5 : b.size() < max_size ? b.size() : max_size);
52 : }
53 :
54 : /** Return a buffer.
55 : */
56 : [[nodiscard]] inline
57 : mutable_buffer
58 4047 : make_buffer(
59 : void* data,
60 : std::size_t size) noexcept
61 : {
62 4047 : return mutable_buffer(data, size);
63 : }
64 :
65 : /** Return a buffer with a maximum size.
66 : */
67 : [[nodiscard]] inline
68 : mutable_buffer
69 2 : make_buffer(
70 : void* data,
71 : std::size_t size,
72 : std::size_t max_size) noexcept
73 : {
74 2 : return mutable_buffer(
75 : data,
76 2 : size < max_size ? size : max_size);
77 : }
78 :
79 : /** Return a buffer.
80 : */
81 : [[nodiscard]] inline
82 : const_buffer
83 1 : make_buffer(
84 : const_buffer const& b) noexcept
85 : {
86 1 : return b;
87 : }
88 :
89 : /** Return a buffer with a maximum size.
90 : */
91 : [[nodiscard]] inline
92 : const_buffer
93 2 : make_buffer(
94 : const_buffer const& b,
95 : std::size_t max_size) noexcept
96 : {
97 5 : return const_buffer(
98 : b.data(),
99 5 : b.size() < max_size ? b.size() : max_size);
100 : }
101 :
102 : /** Return a buffer.
103 : */
104 : [[nodiscard]] inline
105 : const_buffer
106 2 : make_buffer(
107 : void const* data,
108 : std::size_t size) noexcept
109 : {
110 2 : return const_buffer(data, size);
111 : }
112 :
113 : /** Return a buffer with a maximum size.
114 : */
115 : [[nodiscard]] inline
116 : const_buffer
117 2 : make_buffer(
118 : void const* data,
119 : std::size_t size,
120 : std::size_t max_size) noexcept
121 : {
122 2 : return const_buffer(
123 : data,
124 2 : size < max_size ? size : max_size);
125 : }
126 :
127 : // std::basic_string_view
128 :
129 : /** Return a buffer from a std::basic_string_view.
130 : */
131 : template<class CharT, class Traits>
132 : [[nodiscard]]
133 : const_buffer
134 46 : make_buffer(
135 : std::basic_string_view<CharT, Traits> data) noexcept
136 : {
137 136 : return const_buffer(
138 91 : data.size() ? data.data() : nullptr,
139 47 : data.size() * sizeof(CharT));
140 : }
141 :
142 : /** Return a buffer from a std::basic_string_view with a maximum size.
143 : */
144 : template<class CharT, class Traits>
145 : [[nodiscard]]
146 : const_buffer
147 2 : make_buffer(
148 : std::basic_string_view<CharT, Traits> data,
149 : std::size_t max_size) noexcept
150 : {
151 6 : return const_buffer(
152 4 : data.size() ? data.data() : nullptr,
153 2 : data.size() * sizeof(CharT) < max_size
154 3 : ? data.size() * sizeof(CharT) : max_size);
155 : }
156 :
157 : // Contiguous ranges
158 :
159 : namespace detail {
160 :
161 : template<class T>
162 : concept non_buffer_contiguous_range =
163 : std::ranges::contiguous_range<T> &&
164 : std::ranges::sized_range<T> &&
165 : !std::convertible_to<T, const_buffer> &&
166 : !std::convertible_to<T, mutable_buffer> &&
167 : std::is_trivially_copyable_v<std::ranges::range_value_t<T>>;
168 :
169 : template<class T>
170 : concept mutable_contiguous_range =
171 : non_buffer_contiguous_range<T> &&
172 : !std::is_const_v<std::remove_reference_t<
173 : std::ranges::range_reference_t<T>>>;
174 :
175 : template<class T>
176 : concept const_contiguous_range =
177 : non_buffer_contiguous_range<T> &&
178 : std::is_const_v<std::remove_reference_t<
179 : std::ranges::range_reference_t<T>>>;
180 :
181 : } // detail
182 :
183 : /** Return a buffer from a mutable contiguous range.
184 :
185 : Accepts any sized, contiguous range of trivially-copyable,
186 : non-const elements, including `std::vector`, `std::array`,
187 : `std::string`, `std::span`, `boost::span`, and built-in arrays,
188 : whether passed as an lvalue or a temporary. The returned buffer
189 : refers to the range's storage, which must outlive the buffer.
190 : */
191 : template<detail::mutable_contiguous_range T>
192 : [[nodiscard]]
193 : mutable_buffer
194 836 : make_buffer(T&& data) noexcept
195 : {
196 2502 : return mutable_buffer(
197 1670 : std::ranges::size(data) ? std::ranges::data(data) : nullptr,
198 840 : std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
199 : }
200 :
201 : /** Return a buffer from a mutable contiguous range with a maximum size.
202 : */
203 : template<detail::mutable_contiguous_range T>
204 : [[nodiscard]]
205 : mutable_buffer
206 53 : make_buffer(
207 : T&& data,
208 : std::size_t max_size) noexcept
209 : {
210 53 : auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
211 111 : return mutable_buffer(
212 106 : std::ranges::size(data) ? std::ranges::data(data) : nullptr,
213 106 : n < max_size ? n : max_size);
214 : }
215 :
216 : /** Return a buffer from a const contiguous range.
217 :
218 : Accepts any sized, contiguous range of trivially-copyable
219 : elements with const access, including const `std::vector`,
220 : `std::array`, `std::string`, `std::span`, `boost::span`, and
221 : string literals. The returned buffer refers to the range's
222 : storage, which must outlive the buffer.
223 : */
224 : template<detail::non_buffer_contiguous_range T>
225 : [[nodiscard]]
226 : const_buffer
227 169 : make_buffer(T const& data) noexcept
228 : {
229 507 : return const_buffer(
230 338 : std::ranges::size(data) ? std::ranges::data(data) : nullptr,
231 169 : std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
232 : }
233 :
234 : /** Return a buffer from a const contiguous range with a maximum size.
235 : */
236 : template<detail::non_buffer_contiguous_range T>
237 : [[nodiscard]]
238 : const_buffer
239 722 : make_buffer(
240 : T const& data,
241 : std::size_t max_size) noexcept
242 : {
243 722 : auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
244 1449 : return const_buffer(
245 1444 : std::ranges::size(data) ? std::ranges::data(data) : nullptr,
246 1444 : n < max_size ? n : max_size);
247 : }
248 :
249 : } // capy
250 : } // boost
251 :
252 : BOOST_CAPY_MSVC_WARNING_POP
253 :
254 : #endif
|