100.00% Lines (47/47) 100.00% Functions (14/14)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/capy 7   // Official repository: https://github.com/cppalliance/capy
8   // 8   //
9   9  
10   #ifndef BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP 10   #ifndef BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP
11   #define BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP 11   #define BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP
12   12  
13   #include <boost/capy/detail/config.hpp> 13   #include <boost/capy/detail/config.hpp>
14   #include <boost/capy/buffers.hpp> 14   #include <boost/capy/buffers.hpp>
15   #include <array> 15   #include <array>
16   #include <cstdlib> 16   #include <cstdlib>
17   #include <iterator> 17   #include <iterator>
18   #include <ranges> 18   #include <ranges>
19   #include <span> 19   #include <span>
20   #include <string> 20   #include <string>
21   #include <string_view> 21   #include <string_view>
22   #include <type_traits> 22   #include <type_traits>
23   #include <vector> 23   #include <vector>
24   24  
25   BOOST_CAPY_MSVC_WARNING_PUSH 25   BOOST_CAPY_MSVC_WARNING_PUSH
26   BOOST_CAPY_MSVC_WARNING_DISABLE(4459) 26   BOOST_CAPY_MSVC_WARNING_DISABLE(4459)
27   27  
28   namespace boost { 28   namespace boost {
29   namespace capy { 29   namespace capy {
30   30  
31   /** Return a buffer. 31   /** Return a buffer.
32   */ 32   */
33   [[nodiscard]] inline 33   [[nodiscard]] inline
34   mutable_buffer 34   mutable_buffer
HITCBC 35   1 make_buffer( 35   1 make_buffer(
36   mutable_buffer const& b) noexcept 36   mutable_buffer const& b) noexcept
37   { 37   {
HITCBC 38   1 return b; 38   1 return b;
39   } 39   }
40   40  
41   /** Return a buffer with a maximum size. 41   /** Return a buffer with a maximum size.
42   */ 42   */
43   [[nodiscard]] inline 43   [[nodiscard]] inline
44   mutable_buffer 44   mutable_buffer
HITCBC 45   2 make_buffer( 45   2 make_buffer(
46   mutable_buffer const& b, 46   mutable_buffer const& b,
47   std::size_t max_size) noexcept 47   std::size_t max_size) noexcept
48   { 48   {
HITCBC 49   5 return mutable_buffer( 49   5 return mutable_buffer(
50   b.data(), 50   b.data(),
HITCBC 51   5 b.size() < max_size ? b.size() : max_size); 51   5 b.size() < max_size ? b.size() : max_size);
52   } 52   }
53   53  
54   /** Return a buffer. 54   /** Return a buffer.
55   */ 55   */
56   [[nodiscard]] inline 56   [[nodiscard]] inline
57   mutable_buffer 57   mutable_buffer
HITCBC 58   4046 make_buffer( 58   4047 make_buffer(
59   void* data, 59   void* data,
60   std::size_t size) noexcept 60   std::size_t size) noexcept
61   { 61   {
HITCBC 62   4046 return mutable_buffer(data, size); 62   4047 return mutable_buffer(data, size);
63   } 63   }
64   64  
65   /** Return a buffer with a maximum size. 65   /** Return a buffer with a maximum size.
66   */ 66   */
67   [[nodiscard]] inline 67   [[nodiscard]] inline
68   mutable_buffer 68   mutable_buffer
HITCBC 69   2 make_buffer( 69   2 make_buffer(
70   void* data, 70   void* data,
71   std::size_t size, 71   std::size_t size,
72   std::size_t max_size) noexcept 72   std::size_t max_size) noexcept
73   { 73   {
HITCBC 74   2 return mutable_buffer( 74   2 return mutable_buffer(
75   data, 75   data,
HITCBC 76   2 size < max_size ? size : max_size); 76   2 size < max_size ? size : max_size);
77   } 77   }
78   78  
79   /** Return a buffer. 79   /** Return a buffer.
80   */ 80   */
81   [[nodiscard]] inline 81   [[nodiscard]] inline
82   const_buffer 82   const_buffer
HITCBC 83   1 make_buffer( 83   1 make_buffer(
84   const_buffer const& b) noexcept 84   const_buffer const& b) noexcept
85   { 85   {
HITCBC 86   1 return b; 86   1 return b;
87   } 87   }
88   88  
89   /** Return a buffer with a maximum size. 89   /** Return a buffer with a maximum size.
90   */ 90   */
91   [[nodiscard]] inline 91   [[nodiscard]] inline
92   const_buffer 92   const_buffer
HITCBC 93   2 make_buffer( 93   2 make_buffer(
94   const_buffer const& b, 94   const_buffer const& b,
95   std::size_t max_size) noexcept 95   std::size_t max_size) noexcept
96   { 96   {
HITCBC 97   5 return const_buffer( 97   5 return const_buffer(
98   b.data(), 98   b.data(),
HITCBC 99   5 b.size() < max_size ? b.size() : max_size); 99   5 b.size() < max_size ? b.size() : max_size);
100   } 100   }
101   101  
102   /** Return a buffer. 102   /** Return a buffer.
103   */ 103   */
104   [[nodiscard]] inline 104   [[nodiscard]] inline
105   const_buffer 105   const_buffer
HITCBC 106   2 make_buffer( 106   2 make_buffer(
107   void const* data, 107   void const* data,
108   std::size_t size) noexcept 108   std::size_t size) noexcept
109   { 109   {
HITCBC 110   2 return const_buffer(data, size); 110   2 return const_buffer(data, size);
111   } 111   }
112   112  
113   /** Return a buffer with a maximum size. 113   /** Return a buffer with a maximum size.
114   */ 114   */
115   [[nodiscard]] inline 115   [[nodiscard]] inline
116   const_buffer 116   const_buffer
HITCBC 117   2 make_buffer( 117   2 make_buffer(
118   void const* data, 118   void const* data,
119   std::size_t size, 119   std::size_t size,
120   std::size_t max_size) noexcept 120   std::size_t max_size) noexcept
121   { 121   {
HITCBC 122   2 return const_buffer( 122   2 return const_buffer(
123   data, 123   data,
HITCBC 124   2 size < max_size ? size : max_size); 124   2 size < max_size ? size : max_size);
125   } 125   }
126 - /** Return a buffer from a C-style array.  
127 - */  
128 - template<class T, std::size_t N>  
129 - requires std::is_trivially_copyable_v<T>  
130 - [[nodiscard]]  
131 - mutable_buffer  
132 - make_buffer(  
DCB 133 - 657 T (&data)[N]) noexcept  
134 - {  
135 - return mutable_buffer(  
DCB 136 - 657 data, N * sizeof(T));  
DCB 137 - 657 }  
138 -  
139 - /** Return a buffer from a C-style array with a maximum size.  
140 - */  
141 - template<class T, std::size_t N>  
142 - requires std::is_trivially_copyable_v<T>  
143 - [[nodiscard]]  
144 - mutable_buffer  
145 - make_buffer(  
DCB 146 - 45 T (&data)[N],  
147 - std::size_t max_size) noexcept  
148 - {  
149 - return mutable_buffer(  
DCB 150 - 90 data,  
151 - N * sizeof(T) < max_size ? N * sizeof(T) : max_size);  
DCB 152 - 45 }  
153 -  
154 - /** Return a buffer from a const C-style array.  
155 - */  
156 - template<class T, std::size_t N>  
157 - requires std::is_trivially_copyable_v<T>  
158 - [[nodiscard]]  
159 - const_buffer  
160 - make_buffer(  
DCB 161 - 1 T const (&data)[N]) noexcept  
162 - {  
163 - return const_buffer(  
DCB 164 - 1 data, N * sizeof(T));  
DCB 165 - 1 }  
166 -  
167 - /** Return a buffer from a const C-style array with a maximum size.  
168 - */  
169 - template<class T, std::size_t N>  
170 - requires std::is_trivially_copyable_v<T>  
171 - [[nodiscard]]  
172 - const_buffer  
173 - make_buffer(  
DCB 174 - 714 T const (&data)[N],  
175 - std::size_t max_size) noexcept  
176 - {  
177 - return const_buffer(  
DCB 178 - 1428 data,  
179 - N * sizeof(T) < max_size ? N * sizeof(T) : max_size);  
DCB 180 - 714 }  
181 -  
182 - // std::array  
183 -  
184 - /** Return a buffer from a std::array.  
185 - */  
186 - template<class T, std::size_t N>  
187 - requires std::is_trivially_copyable_v<T>  
188 - [[nodiscard]]  
189 - mutable_buffer  
190 - make_buffer(  
DCB 191 - 2 std::array<T, N>& data) noexcept  
192 - {  
193 - return mutable_buffer(  
DCB 194 - 4 data.data(), data.size() * sizeof(T));  
DCB 195 - 3 }  
196 -  
197 - /** Return a buffer from a std::array with a maximum size.  
198 - */  
199 - template<class T, std::size_t N>  
200 - requires std::is_trivially_copyable_v<T>  
201 - [[nodiscard]]  
202 - mutable_buffer  
203 - make_buffer(  
DCB 204 - 2 std::array<T, N>& data,  
205 - std::size_t max_size) noexcept  
206 - {  
207 - return mutable_buffer(  
DCB 208 - 6 data.data(),  
DCB 209 - 2 data.size() * sizeof(T) < max_size  
DCB 210 - 2 ? data.size() * sizeof(T) : max_size);  
DCB 211 - 2 }  
212 -  
213 - /** Return a buffer from a const std::array.  
214 - */  
215 - template<class T, std::size_t N>  
216 - requires std::is_trivially_copyable_v<T>  
217 - [[nodiscard]]  
218 - const_buffer  
219 - make_buffer(  
DCB 220 - 1 std::array<T, N> const& data) noexcept  
221 - {  
222 - return const_buffer(  
DCB 223 - 1 data.data(), data.size() * sizeof(T));  
DCB 224 - 2 }  
225 -  
226 - /** Return a buffer from a const std::array with a maximum size.  
227 - */  
228 - template<class T, std::size_t N>  
229 - requires std::is_trivially_copyable_v<T>  
230 - [[nodiscard]]  
231 - const_buffer  
232 - make_buffer(  
DCB 233 - 2 std::array<T, N> const& data,  
234 - std::size_t max_size) noexcept  
235 - {  
236 - return const_buffer(  
DCB 237 - 2 data.data(),  
DCB 238 - 2 data.size() * sizeof(T) < max_size  
DCB 239 - 2 ? data.size() * sizeof(T) : max_size);  
DCB 240 - 2 }  
241 -  
242 - // std::vector  
243 -  
244 - /** Return a buffer from a std::vector.  
245 - */  
246 - template<class T, class Allocator>  
247 - requires std::is_trivially_copyable_v<T>  
248 - [[nodiscard]]  
249 - mutable_buffer  
250 - make_buffer(  
DCB 251 - 3 std::vector<T, Allocator>& data) noexcept  
252 - {  
253 - return mutable_buffer(  
DCB 254 - 7 data.size() ? data.data() : nullptr,  
DCB 255 - 5 data.size() * sizeof(T));  
DCB 256 - 4 }  
257 -  
258 - /** Return a buffer from a std::vector with a maximum size.  
259 - */  
260 - template<class T, class Allocator>  
261 - requires std::is_trivially_copyable_v<T>  
262 - [[nodiscard]]  
263 - mutable_buffer  
264 - make_buffer(  
DCB 265 - 2 std::vector<T, Allocator>& data,  
266 - std::size_t max_size) noexcept  
267 - {  
268 - return mutable_buffer(  
DCB 269 - 6 data.size() ? data.data() : nullptr,  
DCB 270 - 4 data.size() * sizeof(T) < max_size  
DCB 271 - 2 ? data.size() * sizeof(T) : max_size);  
DCB 272 - 3 }  
273 -  
274 - /** Return a buffer from a const std::vector.  
275 - */  
276 - template<class T, class Allocator>  
277 - requires std::is_trivially_copyable_v<T>  
278 - [[nodiscard]]  
279 - const_buffer  
280 - make_buffer(  
DCB 281 - 1 std::vector<T, Allocator> const& data) noexcept  
282 - {  
283 - return const_buffer(  
DCB 284 - 3 data.size() ? data.data() : nullptr,  
DCB 285 - 2 data.size() * sizeof(T));  
DCB 286 - 1 }  
287 -  
288 - /** Return a buffer from a const std::vector with a maximum size.  
289 - */  
290 - template<class T, class Allocator>  
291 - requires std::is_trivially_copyable_v<T>  
292 - [[nodiscard]]  
293 - const_buffer  
294 - make_buffer(  
DCB 295 - 2 std::vector<T, Allocator> const& data,  
296 - std::size_t max_size) noexcept  
297 - {  
298 - return const_buffer(  
DCB 299 - 6 data.size() ? data.data() : nullptr,  
DCB 300 - 4 data.size() * sizeof(T) < max_size  
DCB 301 - 2 ? data.size() * sizeof(T) : max_size);  
DCB 302 - 3 }  
303 -  
304 - // std::basic_string  
305 -  
306 - /** Return a buffer from a std::basic_string.  
307 - */  
308 - template<class CharT, class Traits, class Allocator>  
309 - [[nodiscard]]  
310 - mutable_buffer  
311 - make_buffer(  
DCB 312 - 169 std::basic_string<CharT, Traits, Allocator>& data) noexcept  
313 - {  
314 - return mutable_buffer(  
DCB 315 - 505 data.size() ? &data[0] : nullptr,  
DCB 316 - 337 data.size() * sizeof(CharT));  
DCB 317 - 170 }  
318 -  
319 - /** Return a buffer from a std::basic_string with a maximum size.  
320 - */  
321 - template<class CharT, class Traits, class Allocator>  
322 - [[nodiscard]]  
323 - mutable_buffer  
324 - make_buffer(  
DCB 325 - 2 std::basic_string<CharT, Traits, Allocator>& data,  
326 - std::size_t max_size) noexcept  
327 - {  
328 - return mutable_buffer(  
DCB 329 - 6 data.size() ? &data[0] : nullptr,  
DCB 330 - 4 data.size() * sizeof(CharT) < max_size  
DCB 331 - 2 ? data.size() * sizeof(CharT) : max_size);  
DCB 332 - 3 }  
333 -  
334 - /** Return a buffer from a const std::basic_string.  
335 - */  
336 - template<class CharT, class Traits, class Allocator>  
337 - [[nodiscard]]  
338 - const_buffer  
339 - make_buffer(  
DCB 340 - 163 std::basic_string<CharT, Traits, Allocator> const& data) noexcept  
341 - {  
342 - return const_buffer(  
DCB 343 - 326 data.data(),  
DCB 344 - 163 data.size() * sizeof(CharT));  
DCB 345 - 163 }  
346 -  
347 - /** Return a buffer from a const std::basic_string with a maximum size.  
348 - */  
349 - template<class CharT, class Traits, class Allocator>  
350 - [[nodiscard]]  
351 - const_buffer  
352 - make_buffer(  
DCB 353 - 2 std::basic_string<CharT, Traits, Allocator> const& data,  
354 - std::size_t max_size) noexcept  
355 - {  
356 - return const_buffer(  
DCB 357 - 6 data.data(),  
DCB 358 - 2 data.size() * sizeof(CharT) < max_size  
DCB 359 - 2 ? data.size() * sizeof(CharT) : max_size);  
DCB 360 - 3 }  
361 -  
362   126  
363   // std::basic_string_view 127   // std::basic_string_view
364   128  
365   /** Return a buffer from a std::basic_string_view. 129   /** Return a buffer from a std::basic_string_view.
366   */ 130   */
367   template<class CharT, class Traits> 131   template<class CharT, class Traits>
368   [[nodiscard]] 132   [[nodiscard]]
369   const_buffer 133   const_buffer
HITCBC 370   46 make_buffer( 134   46 make_buffer(
371   std::basic_string_view<CharT, Traits> data) noexcept 135   std::basic_string_view<CharT, Traits> data) noexcept
372   { 136   {
HITCBC 373   136 return const_buffer( 137   136 return const_buffer(
HITCBC 374   91 data.size() ? data.data() : nullptr, 138   91 data.size() ? data.data() : nullptr,
HITCBC 375   47 data.size() * sizeof(CharT)); 139   47 data.size() * sizeof(CharT));
376   } 140   }
377   141  
378   /** Return a buffer from a std::basic_string_view with a maximum size. 142   /** Return a buffer from a std::basic_string_view with a maximum size.
379   */ 143   */
380   template<class CharT, class Traits> 144   template<class CharT, class Traits>
381   [[nodiscard]] 145   [[nodiscard]]
382   const_buffer 146   const_buffer
HITCBC 383   2 make_buffer( 147   2 make_buffer(
384   std::basic_string_view<CharT, Traits> data, 148   std::basic_string_view<CharT, Traits> data,
385   std::size_t max_size) noexcept 149   std::size_t max_size) noexcept
386   { 150   {
HITCBC 387   6 return const_buffer( 151   6 return const_buffer(
HITCBC 388   4 data.size() ? data.data() : nullptr, 152   4 data.size() ? data.data() : nullptr,
HITCBC 389   2 data.size() * sizeof(CharT) < max_size 153   2 data.size() * sizeof(CharT) < max_size
HITCBC 390   3 ? data.size() * sizeof(CharT) : max_size); 154   3 ? data.size() * sizeof(CharT) : max_size);
391   } 155   }
392 - // std::span  
393 -  
394 - /** Return a buffer from a mutable std::span.  
395 - */  
396 - template<class T, std::size_t Extent>  
397 - requires (!std::is_const_v<T> && sizeof(T) == 1)  
398 - [[nodiscard]]  
399 - mutable_buffer  
400 - make_buffer(  
DCB 401 - 2 std::span<T, Extent> data) noexcept  
402 - {  
403 - return mutable_buffer(data.data(), data.size());  
DCB 404 - 2 }  
405 -  
406 - /** Return a buffer from a mutable std::span with a maximum size.  
407 - */  
408 - template<class T, std::size_t Extent>  
409 - requires (!std::is_const_v<T> && sizeof(T) == 1)  
410 - [[nodiscard]]  
411 - mutable_buffer  
412 - make_buffer(  
DCB 413 - 2 std::span<T, Extent> data,  
414 - std::size_t max_size) noexcept  
415 - {  
416 - return mutable_buffer(  
DCB 417 - 6 data.data(),  
DCB 418 - 2 data.size() < max_size ? data.size() : max_size);  
DCB 419 - 5 }  
420 -  
421 - /** Return a buffer from a const std::span.  
422 - */  
423 - template<class T, std::size_t Extent>  
424 - requires (sizeof(T) == 1)  
425 - [[nodiscard]]  
426 - const_buffer  
427 - make_buffer(  
DCB 428 - 1 std::span<T const, Extent> data) noexcept  
429 - {  
430 - return const_buffer(data.data(), data.size());  
DCB 431 - 1 }  
432 -  
433 - /** Return a buffer from a const std::span with a maximum size.  
434 - */  
435 - template<class T, std::size_t Extent>  
436 - requires (sizeof(T) == 1)  
437 - [[nodiscard]]  
438 - const_buffer  
439 - make_buffer(  
DCB 440 - 2 std::span<T const, Extent> data,  
441 - std::size_t max_size) noexcept  
442 - {  
443 - return const_buffer(  
DCB 444 - 6 data.data(),  
DCB 445 - 2 data.size() < max_size ? data.size() : max_size);  
DCB 446 - 5 }  
447 -  
448   156  
449   // Contiguous ranges 157   // Contiguous ranges
450   158  
451   namespace detail { 159   namespace detail {
452   160  
453   template<class T> 161   template<class T>
454   concept non_buffer_contiguous_range = 162   concept non_buffer_contiguous_range =
455   std::ranges::contiguous_range<T> && 163   std::ranges::contiguous_range<T> &&
456   std::ranges::sized_range<T> && 164   std::ranges::sized_range<T> &&
457   !std::convertible_to<T, const_buffer> && 165   !std::convertible_to<T, const_buffer> &&
458   !std::convertible_to<T, mutable_buffer> && 166   !std::convertible_to<T, mutable_buffer> &&
459   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>; 167   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>;
460   168  
461   template<class T> 169   template<class T>
462   concept mutable_contiguous_range = 170   concept mutable_contiguous_range =
463   non_buffer_contiguous_range<T> && 171   non_buffer_contiguous_range<T> &&
464   !std::is_const_v<std::remove_reference_t< 172   !std::is_const_v<std::remove_reference_t<
465   std::ranges::range_reference_t<T>>>; 173   std::ranges::range_reference_t<T>>>;
466   174  
467   template<class T> 175   template<class T>
468   concept const_contiguous_range = 176   concept const_contiguous_range =
469   non_buffer_contiguous_range<T> && 177   non_buffer_contiguous_range<T> &&
470   std::is_const_v<std::remove_reference_t< 178   std::is_const_v<std::remove_reference_t<
471   std::ranges::range_reference_t<T>>>; 179   std::ranges::range_reference_t<T>>>;
472   180  
473   } // detail 181   } // detail
474   182  
475   /** Return a buffer from a mutable contiguous range. 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.
476   */ 190   */
477   template<detail::mutable_contiguous_range T> 191   template<detail::mutable_contiguous_range T>
478   [[nodiscard]] 192   [[nodiscard]]
479   mutable_buffer 193   mutable_buffer
HITGIC 480 - make_buffer(T& data) noexcept 194 + 836 make_buffer(T&& data) noexcept
481   { 195   {
HITGIC 482   return mutable_buffer( 196   2502 return mutable_buffer(
HITGIC 483   std::ranges::size(data) ? std::ranges::data(data) : nullptr, 197   1670 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITGIC 484   std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 198   840 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
485   } 199   }
486   200  
487   /** Return a buffer from a mutable contiguous range with a maximum size. 201   /** Return a buffer from a mutable contiguous range with a maximum size.
488   */ 202   */
489   template<detail::mutable_contiguous_range T> 203   template<detail::mutable_contiguous_range T>
490   [[nodiscard]] 204   [[nodiscard]]
491   mutable_buffer 205   mutable_buffer
HITGIC 492   make_buffer( 206   53 make_buffer(
493 - T& data, 207 + T&& data,
494   std::size_t max_size) noexcept 208   std::size_t max_size) noexcept
495   { 209   {
HITGIC 496   auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>); 210   53 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
HITGIC 497   return mutable_buffer( 211   111 return mutable_buffer(
HITGIC 498   std::ranges::size(data) ? std::ranges::data(data) : nullptr, 212   106 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITGIC 499   n < max_size ? n : max_size); 213   106 n < max_size ? n : max_size);
500   } 214   }
501   215  
502   /** Return a buffer from a const contiguous range. 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.
503   */ 223   */
504   template<detail::non_buffer_contiguous_range T> 224   template<detail::non_buffer_contiguous_range T>
505   [[nodiscard]] 225   [[nodiscard]]
506   const_buffer 226   const_buffer
HITGIC 507   make_buffer(T const& data) noexcept 227   169 make_buffer(T const& data) noexcept
508   { 228   {
HITGIC 509   return const_buffer( 229   507 return const_buffer(
HITGIC 510   std::ranges::size(data) ? std::ranges::data(data) : nullptr, 230   338 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITGIC 511   std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 231   169 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
512   } 232   }
513   233  
514   /** Return a buffer from a const contiguous range with a maximum size. 234   /** Return a buffer from a const contiguous range with a maximum size.
515   */ 235   */
516   template<detail::non_buffer_contiguous_range T> 236   template<detail::non_buffer_contiguous_range T>
517   [[nodiscard]] 237   [[nodiscard]]
518   const_buffer 238   const_buffer
HITGIC 519   make_buffer( 239   722 make_buffer(
520   T const& data, 240   T const& data,
521   std::size_t max_size) noexcept 241   std::size_t max_size) noexcept
522   { 242   {
HITGIC 523   auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>); 243   722 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
HITGIC 524   return const_buffer( 244   1449 return const_buffer(
HITGIC 525   std::ranges::size(data) ? std::ranges::data(data) : nullptr, 245   1444 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITGIC 526   n < max_size ? n : max_size); 246   1444 n < max_size ? n : max_size);
527   } 247   }
528   248  
529   } // capy 249   } // capy
530   } // boost 250   } // boost
531   251  
532   BOOST_CAPY_MSVC_WARNING_POP 252   BOOST_CAPY_MSVC_WARNING_POP
533   253  
534   #endif 254   #endif