100.00% Lines (105/105) 100.00% Functions (30/30)
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   4047 make_buffer( 58   4046 make_buffer(
59   void* data, 59   void* data,
60   std::size_t size) noexcept 60   std::size_t size) noexcept
61   { 61   {
HITCBC 62   4047 return mutable_buffer(data, size); 62   4046 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   126  
  127 + /** Return a buffer from a C-style array.
  128 + */
  129 + template<class T, std::size_t N>
  130 + requires std::is_trivially_copyable_v<T>
  131 + [[nodiscard]]
  132 + mutable_buffer
HITGNC   133 + 657 make_buffer(
  134 + T (&data)[N]) noexcept
  135 + {
HITGNC   136 + 657 return mutable_buffer(
HITGNC   137 + 657 data, N * sizeof(T));
  138 + }
  139 +
  140 + /** Return a buffer from a C-style array with a maximum size.
  141 + */
  142 + template<class T, std::size_t N>
  143 + requires std::is_trivially_copyable_v<T>
  144 + [[nodiscard]]
  145 + mutable_buffer
HITGNC   146 + 45 make_buffer(
  147 + T (&data)[N],
  148 + std::size_t max_size) noexcept
  149 + {
HITGNC   150 + 90 return mutable_buffer(
  151 + data,
HITGNC   152 + 45 N * sizeof(T) < max_size ? N * sizeof(T) : max_size);
  153 + }
  154 +
  155 + /** Return a buffer from a const C-style array.
  156 + */
  157 + template<class T, std::size_t N>
  158 + requires std::is_trivially_copyable_v<T>
  159 + [[nodiscard]]
  160 + const_buffer
HITGNC   161 + 1 make_buffer(
  162 + T const (&data)[N]) noexcept
  163 + {
HITGNC   164 + 1 return const_buffer(
HITGNC   165 + 1 data, N * sizeof(T));
  166 + }
  167 +
  168 + /** Return a buffer from a const C-style array with a maximum size.
  169 + */
  170 + template<class T, std::size_t N>
  171 + requires std::is_trivially_copyable_v<T>
  172 + [[nodiscard]]
  173 + const_buffer
HITGNC   174 + 714 make_buffer(
  175 + T const (&data)[N],
  176 + std::size_t max_size) noexcept
  177 + {
HITGNC   178 + 1428 return const_buffer(
  179 + data,
HITGNC   180 + 714 N * sizeof(T) < max_size ? N * sizeof(T) : max_size);
  181 + }
  182 +
  183 + // std::array
  184 +
  185 + /** Return a buffer from a std::array.
  186 + */
  187 + template<class T, std::size_t N>
  188 + requires std::is_trivially_copyable_v<T>
  189 + [[nodiscard]]
  190 + mutable_buffer
HITGNC   191 + 2 make_buffer(
  192 + std::array<T, N>& data) noexcept
  193 + {
HITGNC   194 + 4 return mutable_buffer(
HITGNC   195 + 3 data.data(), data.size() * sizeof(T));
  196 + }
  197 +
  198 + /** Return a buffer from a std::array with a maximum size.
  199 + */
  200 + template<class T, std::size_t N>
  201 + requires std::is_trivially_copyable_v<T>
  202 + [[nodiscard]]
  203 + mutable_buffer
HITGNC   204 + 2 make_buffer(
  205 + std::array<T, N>& data,
  206 + std::size_t max_size) noexcept
  207 + {
HITGNC   208 + 6 return mutable_buffer(
HITGNC   209 + 2 data.data(),
HITGNC   210 + 2 data.size() * sizeof(T) < max_size
HITGNC   211 + 2 ? data.size() * sizeof(T) : max_size);
  212 + }
  213 +
  214 + /** Return a buffer from a const std::array.
  215 + */
  216 + template<class T, std::size_t N>
  217 + requires std::is_trivially_copyable_v<T>
  218 + [[nodiscard]]
  219 + const_buffer
HITGNC   220 + 1 make_buffer(
  221 + std::array<T, N> const& data) noexcept
  222 + {
HITGNC   223 + 1 return const_buffer(
HITGNC   224 + 2 data.data(), data.size() * sizeof(T));
  225 + }
  226 +
  227 + /** Return a buffer from a const std::array with a maximum size.
  228 + */
  229 + template<class T, std::size_t N>
  230 + requires std::is_trivially_copyable_v<T>
  231 + [[nodiscard]]
  232 + const_buffer
HITGNC   233 + 2 make_buffer(
  234 + std::array<T, N> const& data,
  235 + std::size_t max_size) noexcept
  236 + {
HITGNC   237 + 2 return const_buffer(
HITGNC   238 + 2 data.data(),
HITGNC   239 + 2 data.size() * sizeof(T) < max_size
HITGNC   240 + 2 ? data.size() * sizeof(T) : max_size);
  241 + }
  242 +
  243 + // std::vector
  244 +
  245 + /** Return a buffer from a std::vector.
  246 + */
  247 + template<class T, class Allocator>
  248 + requires std::is_trivially_copyable_v<T>
  249 + [[nodiscard]]
  250 + mutable_buffer
HITGNC   251 + 3 make_buffer(
  252 + std::vector<T, Allocator>& data) noexcept
  253 + {
HITGNC   254 + 7 return mutable_buffer(
HITGNC   255 + 5 data.size() ? data.data() : nullptr,
HITGNC   256 + 4 data.size() * sizeof(T));
  257 + }
  258 +
  259 + /** Return a buffer from a std::vector with a maximum size.
  260 + */
  261 + template<class T, class Allocator>
  262 + requires std::is_trivially_copyable_v<T>
  263 + [[nodiscard]]
  264 + mutable_buffer
HITGNC   265 + 2 make_buffer(
  266 + std::vector<T, Allocator>& data,
  267 + std::size_t max_size) noexcept
  268 + {
HITGNC   269 + 6 return mutable_buffer(
HITGNC   270 + 4 data.size() ? data.data() : nullptr,
HITGNC   271 + 2 data.size() * sizeof(T) < max_size
HITGNC   272 + 3 ? data.size() * sizeof(T) : max_size);
  273 + }
  274 +
  275 + /** Return a buffer from a const std::vector.
  276 + */
  277 + template<class T, class Allocator>
  278 + requires std::is_trivially_copyable_v<T>
  279 + [[nodiscard]]
  280 + const_buffer
HITGNC   281 + 1 make_buffer(
  282 + std::vector<T, Allocator> const& data) noexcept
  283 + {
HITGNC   284 + 3 return const_buffer(
HITGNC   285 + 2 data.size() ? data.data() : nullptr,
HITGNC   286 + 1 data.size() * sizeof(T));
  287 + }
  288 +
  289 + /** Return a buffer from a const std::vector with a maximum size.
  290 + */
  291 + template<class T, class Allocator>
  292 + requires std::is_trivially_copyable_v<T>
  293 + [[nodiscard]]
  294 + const_buffer
HITGNC   295 + 2 make_buffer(
  296 + std::vector<T, Allocator> const& data,
  297 + std::size_t max_size) noexcept
  298 + {
HITGNC   299 + 6 return const_buffer(
HITGNC   300 + 4 data.size() ? data.data() : nullptr,
HITGNC   301 + 2 data.size() * sizeof(T) < max_size
HITGNC   302 + 3 ? data.size() * sizeof(T) : max_size);
  303 + }
  304 +
  305 + // std::basic_string
  306 +
  307 + /** Return a buffer from a std::basic_string.
  308 + */
  309 + template<class CharT, class Traits, class Allocator>
  310 + [[nodiscard]]
  311 + mutable_buffer
HITGNC   312 + 169 make_buffer(
  313 + std::basic_string<CharT, Traits, Allocator>& data) noexcept
  314 + {
HITGNC   315 + 505 return mutable_buffer(
HITGNC   316 + 337 data.size() ? &data[0] : nullptr,
HITGNC   317 + 170 data.size() * sizeof(CharT));
  318 + }
  319 +
  320 + /** Return a buffer from a std::basic_string with a maximum size.
  321 + */
  322 + template<class CharT, class Traits, class Allocator>
  323 + [[nodiscard]]
  324 + mutable_buffer
HITGNC   325 + 2 make_buffer(
  326 + std::basic_string<CharT, Traits, Allocator>& data,
  327 + std::size_t max_size) noexcept
  328 + {
HITGNC   329 + 6 return mutable_buffer(
HITGNC   330 + 4 data.size() ? &data[0] : nullptr,
HITGNC   331 + 2 data.size() * sizeof(CharT) < max_size
HITGNC   332 + 3 ? data.size() * sizeof(CharT) : max_size);
  333 + }
  334 +
  335 + /** Return a buffer from a const std::basic_string.
  336 + */
  337 + template<class CharT, class Traits, class Allocator>
  338 + [[nodiscard]]
  339 + const_buffer
HITGNC   340 + 163 make_buffer(
  341 + std::basic_string<CharT, Traits, Allocator> const& data) noexcept
  342 + {
HITGNC   343 + 326 return const_buffer(
HITGNC   344 + 163 data.data(),
HITGNC   345 + 163 data.size() * sizeof(CharT));
  346 + }
  347 +
  348 + /** Return a buffer from a const std::basic_string with a maximum size.
  349 + */
  350 + template<class CharT, class Traits, class Allocator>
  351 + [[nodiscard]]
  352 + const_buffer
HITGNC   353 + 2 make_buffer(
  354 + std::basic_string<CharT, Traits, Allocator> const& data,
  355 + std::size_t max_size) noexcept
  356 + {
HITGNC   357 + 6 return const_buffer(
HITGNC   358 + 2 data.data(),
HITGNC   359 + 2 data.size() * sizeof(CharT) < max_size
HITGNC   360 + 3 ? data.size() * sizeof(CharT) : max_size);
  361 + }
  362 +
127   // std::basic_string_view 363   // std::basic_string_view
128   364  
129   /** Return a buffer from a std::basic_string_view. 365   /** Return a buffer from a std::basic_string_view.
130   */ 366   */
131   template<class CharT, class Traits> 367   template<class CharT, class Traits>
132   [[nodiscard]] 368   [[nodiscard]]
133   const_buffer 369   const_buffer
HITCBC 134   46 make_buffer( 370   46 make_buffer(
135   std::basic_string_view<CharT, Traits> data) noexcept 371   std::basic_string_view<CharT, Traits> data) noexcept
136   { 372   {
HITCBC 137   136 return const_buffer( 373   136 return const_buffer(
HITCBC 138   91 data.size() ? data.data() : nullptr, 374   91 data.size() ? data.data() : nullptr,
HITCBC 139   47 data.size() * sizeof(CharT)); 375   47 data.size() * sizeof(CharT));
140   } 376   }
141   377  
142   /** Return a buffer from a std::basic_string_view with a maximum size. 378   /** Return a buffer from a std::basic_string_view with a maximum size.
143   */ 379   */
144   template<class CharT, class Traits> 380   template<class CharT, class Traits>
145   [[nodiscard]] 381   [[nodiscard]]
146   const_buffer 382   const_buffer
HITCBC 147   2 make_buffer( 383   2 make_buffer(
148   std::basic_string_view<CharT, Traits> data, 384   std::basic_string_view<CharT, Traits> data,
149   std::size_t max_size) noexcept 385   std::size_t max_size) noexcept
150   { 386   {
HITCBC 151   6 return const_buffer( 387   6 return const_buffer(
HITCBC 152   4 data.size() ? data.data() : nullptr, 388   4 data.size() ? data.data() : nullptr,
HITCBC 153   2 data.size() * sizeof(CharT) < max_size 389   2 data.size() * sizeof(CharT) < max_size
HITCBC 154   3 ? data.size() * sizeof(CharT) : max_size); 390   3 ? data.size() * sizeof(CharT) : max_size);
155   } 391   }
156   392  
  393 + // std::span
  394 +
  395 + /** Return a buffer from a mutable std::span.
  396 + */
  397 + template<class T, std::size_t Extent>
  398 + requires (!std::is_const_v<T> && sizeof(T) == 1)
  399 + [[nodiscard]]
  400 + mutable_buffer
HITGNC   401 + 2 make_buffer(
  402 + std::span<T, Extent> data) noexcept
  403 + {
HITGNC   404 + 2 return mutable_buffer(data.data(), data.size());
  405 + }
  406 +
  407 + /** Return a buffer from a mutable std::span with a maximum size.
  408 + */
  409 + template<class T, std::size_t Extent>
  410 + requires (!std::is_const_v<T> && sizeof(T) == 1)
  411 + [[nodiscard]]
  412 + mutable_buffer
HITGNC   413 + 2 make_buffer(
  414 + std::span<T, Extent> data,
  415 + std::size_t max_size) noexcept
  416 + {
HITGNC   417 + 6 return mutable_buffer(
HITGNC   418 + 2 data.data(),
HITGNC   419 + 5 data.size() < max_size ? data.size() : max_size);
  420 + }
  421 +
  422 + /** Return a buffer from a const std::span.
  423 + */
  424 + template<class T, std::size_t Extent>
  425 + requires (sizeof(T) == 1)
  426 + [[nodiscard]]
  427 + const_buffer
HITGNC   428 + 1 make_buffer(
  429 + std::span<T const, Extent> data) noexcept
  430 + {
HITGNC   431 + 1 return const_buffer(data.data(), data.size());
  432 + }
  433 +
  434 + /** Return a buffer from a const std::span with a maximum size.
  435 + */
  436 + template<class T, std::size_t Extent>
  437 + requires (sizeof(T) == 1)
  438 + [[nodiscard]]
  439 + const_buffer
HITGNC   440 + 2 make_buffer(
  441 + std::span<T const, Extent> data,
  442 + std::size_t max_size) noexcept
  443 + {
HITGNC   444 + 6 return const_buffer(
HITGNC   445 + 2 data.data(),
HITGNC   446 + 5 data.size() < max_size ? data.size() : max_size);
  447 + }
  448 +
157   // Contiguous ranges 449   // Contiguous ranges
158   450  
159   namespace detail { 451   namespace detail {
160   452  
161   template<class T> 453   template<class T>
162   concept non_buffer_contiguous_range = 454   concept non_buffer_contiguous_range =
163   std::ranges::contiguous_range<T> && 455   std::ranges::contiguous_range<T> &&
164   std::ranges::sized_range<T> && 456   std::ranges::sized_range<T> &&
165   !std::convertible_to<T, const_buffer> && 457   !std::convertible_to<T, const_buffer> &&
166   !std::convertible_to<T, mutable_buffer> && 458   !std::convertible_to<T, mutable_buffer> &&
167   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>; 459   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>;
168   460  
169   template<class T> 461   template<class T>
170   concept mutable_contiguous_range = 462   concept mutable_contiguous_range =
171   non_buffer_contiguous_range<T> && 463   non_buffer_contiguous_range<T> &&
172   !std::is_const_v<std::remove_reference_t< 464   !std::is_const_v<std::remove_reference_t<
173   std::ranges::range_reference_t<T>>>; 465   std::ranges::range_reference_t<T>>>;
174   466  
175   template<class T> 467   template<class T>
176   concept const_contiguous_range = 468   concept const_contiguous_range =
177   non_buffer_contiguous_range<T> && 469   non_buffer_contiguous_range<T> &&
178   std::is_const_v<std::remove_reference_t< 470   std::is_const_v<std::remove_reference_t<
179   std::ranges::range_reference_t<T>>>; 471   std::ranges::range_reference_t<T>>>;
180   472  
181   } // detail 473   } // detail
182   474  
183 -  
184 - Accepts any sized, contiguous range of trivially-copyable,  
185 - non-const elements, including `std::vector`, `std::array`,  
186 - `std::string`, `std::span`, `boost::span`, and built-in arrays,  
187 - whether passed as an lvalue or a temporary. The returned buffer  
188 - refers to the range's storage, which must outlive the buffer.  
189   /** Return a buffer from a mutable contiguous range. 475   /** Return a buffer from a mutable contiguous range.
190   */ 476   */
191   template<detail::mutable_contiguous_range T> 477   template<detail::mutable_contiguous_range T>
192   [[nodiscard]] 478   [[nodiscard]]
193   mutable_buffer 479   mutable_buffer
ECB 194 - 836 make_buffer(T&& data) noexcept 480 + make_buffer(T& data) noexcept
195   { 481   {
ECB 196   2502 return mutable_buffer( 482   return mutable_buffer(
ECB 197   1670 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 483   std::ranges::size(data) ? std::ranges::data(data) : nullptr,
ECB 198   840 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 484   std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
199   } 485   }
200   486  
201   /** Return a buffer from a mutable contiguous range with a maximum size. 487   /** Return a buffer from a mutable contiguous range with a maximum size.
202   */ 488   */
203   template<detail::mutable_contiguous_range T> 489   template<detail::mutable_contiguous_range T>
204   [[nodiscard]] 490   [[nodiscard]]
205   mutable_buffer 491   mutable_buffer
ECB 206   53 make_buffer( 492   make_buffer(
207 - T&& data, 493 + T& data,
208   std::size_t max_size) noexcept 494   std::size_t max_size) noexcept
209   { 495   {
ECB 210   53 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>); 496   auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
ECB 211   111 return mutable_buffer( 497   return mutable_buffer(
ECB 212   106 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 498   std::ranges::size(data) ? std::ranges::data(data) : nullptr,
ECB 213   106 n < max_size ? n : max_size); 499   n < max_size ? n : max_size);
214   } 500   }
215   501  
216 -  
217 - Accepts any sized, contiguous range of trivially-copyable  
218 - elements with const access, including const `std::vector`,  
219 - `std::array`, `std::string`, `std::span`, `boost::span`, and  
220 - string literals. The returned buffer refers to the range's  
221 - storage, which must outlive the buffer.  
222   /** Return a buffer from a const contiguous range. 502   /** Return a buffer from a const contiguous range.
223   */ 503   */
224   template<detail::non_buffer_contiguous_range T> 504   template<detail::non_buffer_contiguous_range T>
225   [[nodiscard]] 505   [[nodiscard]]
226   const_buffer 506   const_buffer
ECB 227   169 make_buffer(T const& data) noexcept 507   make_buffer(T const& data) noexcept
228   { 508   {
ECB 229   507 return const_buffer( 509   return const_buffer(
ECB 230   338 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 510   std::ranges::size(data) ? std::ranges::data(data) : nullptr,
ECB 231   169 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 511   std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
232   } 512   }
233   513  
234   /** Return a buffer from a const contiguous range with a maximum size. 514   /** Return a buffer from a const contiguous range with a maximum size.
235   */ 515   */
236   template<detail::non_buffer_contiguous_range T> 516   template<detail::non_buffer_contiguous_range T>
237   [[nodiscard]] 517   [[nodiscard]]
238   const_buffer 518   const_buffer
ECB 239   722 make_buffer( 519   make_buffer(
240   T const& data, 520   T const& data,
241   std::size_t max_size) noexcept 521   std::size_t max_size) noexcept
242   { 522   {
ECB 243   722 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>); 523   auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
ECB 244   1449 return const_buffer( 524   return const_buffer(
ECB 245   1444 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 525   std::ranges::size(data) ? std::ranges::data(data) : nullptr,
ECB 246   1444 n < max_size ? n : max_size); 526   n < max_size ? n : max_size);
247   } 527   }
248   528  
249   } // capy 529   } // capy
250   } // boost 530   } // boost
251   531  
252   BOOST_CAPY_MSVC_WARNING_POP 532   BOOST_CAPY_MSVC_WARNING_POP
253   533  
254   #endif 534   #endif