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