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 the buffer unchanged.
  32 +
  33 + @param b The buffer to return.
  34 + @return A copy of `b`, referring to the same storage.
32   */ 35   */
33   [[nodiscard]] inline 36   [[nodiscard]] inline
34   mutable_buffer 37   mutable_buffer
HITCBC 35   1 make_buffer( 38   1 make_buffer(
36   mutable_buffer const& b) noexcept 39   mutable_buffer const& b) noexcept
37   { 40   {
HITCBC 38   1 return b; 41   1 return b;
39   } 42   }
40   43  
41 - /** Return a buffer with a maximum size. 44 + /** Return the buffer, clamped to a maximum size.
  45 +
  46 + @param b The buffer to return.
  47 + @param max_size The maximum size, in bytes, of the result.
  48 + @return A buffer referring to the storage of `b` whose size
  49 + is the smaller of `b.size()` and `max_size`.
42   */ 50   */
43   [[nodiscard]] inline 51   [[nodiscard]] inline
44   mutable_buffer 52   mutable_buffer
HITCBC 45   2 make_buffer( 53   2 make_buffer(
46   mutable_buffer const& b, 54   mutable_buffer const& b,
47   std::size_t max_size) noexcept 55   std::size_t max_size) noexcept
48   { 56   {
HITCBC 49   5 return mutable_buffer( 57   5 return mutable_buffer(
50   b.data(), 58   b.data(),
HITCBC 51   5 b.size() < max_size ? b.size() : max_size); 59   5 b.size() < max_size ? b.size() : max_size);
52   } 60   }
53   61  
54 - /** Return a buffer. 62 + /** Return a buffer referring to a region of memory.
  63 +
  64 + @param data A pointer to the start of the region. The region
  65 + must outlive the returned buffer.
  66 + @param size The size of the region, in bytes.
  67 + @return A buffer referring to `[data, data + size)`.
55   */ 68   */
56   [[nodiscard]] inline 69   [[nodiscard]] inline
57   mutable_buffer 70   mutable_buffer
HITCBC 58   4055 make_buffer( 71   4047 make_buffer(
59   void* data, 72   void* data,
60   std::size_t size) noexcept 73   std::size_t size) noexcept
61   { 74   {
HITCBC 62   4055 return mutable_buffer(data, size); 75   4047 return mutable_buffer(data, size);
63   } 76   }
64   77  
65 - /** Return a buffer with a maximum size. 78 + /** Return a buffer referring to a region of memory, clamped to a maximum size.
  79 +
  80 + @param data A pointer to the start of the region. The region
  81 + must outlive the returned buffer.
  82 + @param size The size of the region, in bytes.
  83 + @param max_size The maximum size, in bytes, of the result.
  84 + @return A buffer referring to `data` whose size is the smaller
  85 + of `size` and `max_size`.
66   */ 86   */
67   [[nodiscard]] inline 87   [[nodiscard]] inline
68   mutable_buffer 88   mutable_buffer
HITCBC 69   2 make_buffer( 89   2 make_buffer(
70   void* data, 90   void* data,
71   std::size_t size, 91   std::size_t size,
72   std::size_t max_size) noexcept 92   std::size_t max_size) noexcept
73   { 93   {
HITCBC 74   2 return mutable_buffer( 94   2 return mutable_buffer(
75   data, 95   data,
HITCBC 76   2 size < max_size ? size : max_size); 96   2 size < max_size ? size : max_size);
77   } 97   }
78   98  
79 - /** Return a buffer. 99 + /** Return the buffer unchanged.
  100 +
  101 + @param b The buffer to return.
  102 + @return A copy of `b`, referring to the same storage.
80   */ 103   */
81   [[nodiscard]] inline 104   [[nodiscard]] inline
82   const_buffer 105   const_buffer
HITCBC 83   1 make_buffer( 106   1 make_buffer(
84   const_buffer const& b) noexcept 107   const_buffer const& b) noexcept
85   { 108   {
HITCBC 86   1 return b; 109   1 return b;
87   } 110   }
88   111  
89 - /** Return a buffer with a maximum size. 112 + /** Return the buffer, clamped to a maximum size.
  113 +
  114 + @param b The buffer to return.
  115 + @param max_size The maximum size, in bytes, of the result.
  116 + @return A buffer referring to the storage of `b` whose size
  117 + is the smaller of `b.size()` and `max_size`.
90   */ 118   */
91   [[nodiscard]] inline 119   [[nodiscard]] inline
92   const_buffer 120   const_buffer
HITCBC 93   2 make_buffer( 121   2 make_buffer(
94   const_buffer const& b, 122   const_buffer const& b,
95   std::size_t max_size) noexcept 123   std::size_t max_size) noexcept
96   { 124   {
HITCBC 97   5 return const_buffer( 125   5 return const_buffer(
98   b.data(), 126   b.data(),
HITCBC 99   5 b.size() < max_size ? b.size() : max_size); 127   5 b.size() < max_size ? b.size() : max_size);
100   } 128   }
101   129  
102 - /** Return a buffer. 130 + /** Return a buffer referring to a region of memory.
  131 +
  132 + @param data A pointer to the start of the region. The region
  133 + must outlive the returned buffer.
  134 + @param size The size of the region, in bytes.
  135 + @return A buffer referring to `[data, data + size)`.
103   */ 136   */
104   [[nodiscard]] inline 137   [[nodiscard]] inline
105   const_buffer 138   const_buffer
HITCBC 106   2 make_buffer( 139   2 make_buffer(
107   void const* data, 140   void const* data,
108   std::size_t size) noexcept 141   std::size_t size) noexcept
109   { 142   {
HITCBC 110   2 return const_buffer(data, size); 143   2 return const_buffer(data, size);
111   } 144   }
112   145  
113 - /** Return a buffer with a maximum size. 146 + /** Return a buffer referring to a region of memory, clamped to a maximum size.
  147 +
  148 + @param data A pointer to the start of the region. The region
  149 + must outlive the returned buffer.
  150 + @param size The size of the region, in bytes.
  151 + @param max_size The maximum size, in bytes, of the result.
  152 + @return A buffer referring to `data` whose size is the smaller
  153 + of `size` and `max_size`.
114   */ 154   */
115   [[nodiscard]] inline 155   [[nodiscard]] inline
116   const_buffer 156   const_buffer
HITCBC 117   2 make_buffer( 157   2 make_buffer(
118   void const* data, 158   void const* data,
119   std::size_t size, 159   std::size_t size,
120   std::size_t max_size) noexcept 160   std::size_t max_size) noexcept
121   { 161   {
HITCBC 122   2 return const_buffer( 162   2 return const_buffer(
123   data, 163   data,
HITCBC 124   2 size < max_size ? size : max_size); 164   2 size < max_size ? size : max_size);
125   } 165   }
126   166  
127   // std::basic_string_view 167   // std::basic_string_view
128   168  
129 - /** Return a buffer from a std::basic_string_view. 169 + /** Return a buffer from a `std::basic_string_view`.
  170 +
  171 + @param data The view whose characters are referenced. The
  172 + underlying storage must outlive the returned buffer.
  173 + @return A buffer referring to the view's storage. The size,
  174 + in bytes, is `data.size() * sizeof(CharT)`.
130   */ 175   */
131   template<class CharT, class Traits> 176   template<class CharT, class Traits>
132   [[nodiscard]] 177   [[nodiscard]]
133   const_buffer 178   const_buffer
HITCBC 134   46 make_buffer( 179   46 make_buffer(
135   std::basic_string_view<CharT, Traits> data) noexcept 180   std::basic_string_view<CharT, Traits> data) noexcept
136   { 181   {
HITCBC 137   136 return const_buffer( 182   136 return const_buffer(
HITCBC 138   91 data.size() ? data.data() : nullptr, 183   91 data.size() ? data.data() : nullptr,
HITCBC 139   47 data.size() * sizeof(CharT)); 184   47 data.size() * sizeof(CharT));
140   } 185   }
141   186  
142 - /** Return a buffer from a std::basic_string_view with a maximum size. 187 + /** Return a buffer from a `std::basic_string_view`, clamped to a maximum size.
  188 +
  189 + @param data The view whose characters are referenced. The
  190 + underlying storage must outlive the returned buffer.
  191 + @param max_size The maximum size, in bytes, of the result.
  192 + @return A buffer referring to the view's storage whose size is
  193 + the smaller of `data.size() * sizeof(CharT)` and `max_size`.
143   */ 194   */
144   template<class CharT, class Traits> 195   template<class CharT, class Traits>
145   [[nodiscard]] 196   [[nodiscard]]
146   const_buffer 197   const_buffer
HITCBC 147   2 make_buffer( 198   2 make_buffer(
148   std::basic_string_view<CharT, Traits> data, 199   std::basic_string_view<CharT, Traits> data,
149   std::size_t max_size) noexcept 200   std::size_t max_size) noexcept
150   { 201   {
HITCBC 151   6 return const_buffer( 202   6 return const_buffer(
HITCBC 152   4 data.size() ? data.data() : nullptr, 203   4 data.size() ? data.data() : nullptr,
HITCBC 153   2 data.size() * sizeof(CharT) < max_size 204   2 data.size() * sizeof(CharT) < max_size
HITCBC 154   3 ? data.size() * sizeof(CharT) : max_size); 205   3 ? data.size() * sizeof(CharT) : max_size);
155   } 206   }
156   207  
157   // Contiguous ranges 208   // Contiguous ranges
158   209  
159   namespace detail { 210   namespace detail {
160   211  
161   template<class T> 212   template<class T>
162   concept non_buffer_contiguous_range = 213   concept non_buffer_contiguous_range =
163   std::ranges::contiguous_range<T> && 214   std::ranges::contiguous_range<T> &&
164   std::ranges::sized_range<T> && 215   std::ranges::sized_range<T> &&
165   !std::convertible_to<T, const_buffer> && 216   !std::convertible_to<T, const_buffer> &&
166   !std::convertible_to<T, mutable_buffer> && 217   !std::convertible_to<T, mutable_buffer> &&
167   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>; 218   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>;
168   219  
169   template<class T> 220   template<class T>
170   concept mutable_contiguous_range = 221   concept mutable_contiguous_range =
171   non_buffer_contiguous_range<T> && 222   non_buffer_contiguous_range<T> &&
172   !std::is_const_v<std::remove_reference_t< 223   !std::is_const_v<std::remove_reference_t<
173   std::ranges::range_reference_t<T>>>; 224   std::ranges::range_reference_t<T>>>;
174   225  
175   template<class T> 226   template<class T>
176   concept const_contiguous_range = 227   concept const_contiguous_range =
177   non_buffer_contiguous_range<T> && 228   non_buffer_contiguous_range<T> &&
178   std::is_const_v<std::remove_reference_t< 229   std::is_const_v<std::remove_reference_t<
179   std::ranges::range_reference_t<T>>>; 230   std::ranges::range_reference_t<T>>>;
180   231  
181   } // detail 232   } // detail
182   233  
183   /** Return a buffer from a mutable contiguous range. 234   /** Return a buffer from a mutable contiguous range.
184   235  
185   Accepts any sized, contiguous range of trivially-copyable, 236   Accepts any sized, contiguous range of trivially-copyable,
186   non-const elements, including `std::vector`, `std::array`, 237   non-const elements, including `std::vector`, `std::array`,
187   `std::string`, `std::span`, `boost::span`, and built-in arrays, 238   `std::string`, `std::span`, `boost::span`, and built-in arrays,
188   whether passed as an lvalue or a temporary. The returned buffer 239   whether passed as an lvalue or a temporary. The returned buffer
189   refers to the range's storage, which must outlive the buffer. 240   refers to the range's storage, which must outlive the buffer.
  241 + Its size, in bytes, is `size() * sizeof(element)`.
190   */ 242   */
191   template<detail::mutable_contiguous_range T> 243   template<detail::mutable_contiguous_range T>
192   [[nodiscard]] 244   [[nodiscard]]
193   mutable_buffer 245   mutable_buffer
HITCBC 194   845 make_buffer(T&& data) noexcept 246   836 make_buffer(T&& data) noexcept
195   { 247   {
HITCBC 196   2529 return mutable_buffer( 248   2502 return mutable_buffer(
HITCBC 197   1688 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 249   1670 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 198   849 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 250   840 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
199   } 251   }
200   252  
201 - /** Return a buffer from a mutable contiguous range with a maximum size. 253 + /** Return a buffer from a mutable contiguous range, clamped to a maximum size.
  254 +
  255 + Like the unclamped overload, but the result is no larger than
  256 + `max_size` bytes.
  257 +
  258 + @param data The range whose storage is referenced. It must
  259 + outlive the returned buffer.
  260 + @param max_size The maximum size, in bytes, of the result.
  261 + @return A buffer whose size is the smaller of
  262 + `size() * sizeof(element)` and `max_size`.
202   */ 263   */
203   template<detail::mutable_contiguous_range T> 264   template<detail::mutable_contiguous_range T>
204   [[nodiscard]] 265   [[nodiscard]]
205   mutable_buffer 266   mutable_buffer
HITCBC 206   53 make_buffer( 267   53 make_buffer(
207   T&& data, 268   T&& data,
208   std::size_t max_size) noexcept 269   std::size_t max_size) noexcept
209   { 270   {
HITCBC 210   53 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>); 271   53 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
HITCBC 211   111 return mutable_buffer( 272   111 return mutable_buffer(
HITCBC 212   106 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 273   106 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 213   106 n < max_size ? n : max_size); 274   106 n < max_size ? n : max_size);
214   } 275   }
215   276  
216   /** Return a buffer from a const contiguous range. 277   /** Return a buffer from a const contiguous range.
217   278  
218   Accepts any sized, contiguous range of trivially-copyable 279   Accepts any sized, contiguous range of trivially-copyable
219   elements with const access, including const `std::vector`, 280   elements with const access, including const `std::vector`,
220   `std::array`, `std::string`, `std::span`, `boost::span`, and 281   `std::array`, `std::string`, `std::span`, `boost::span`, and
221   string literals. The returned buffer refers to the range's 282   string literals. The returned buffer refers to the range's
222 - storage, which must outlive the buffer. 283 + storage, which must outlive the buffer. Its size, in bytes,
  284 + is `size() * sizeof(element)`.
223   */ 285   */
224   template<detail::non_buffer_contiguous_range T> 286   template<detail::non_buffer_contiguous_range T>
225   [[nodiscard]] 287   [[nodiscard]]
226   const_buffer 288   const_buffer
HITCBC 227   171 make_buffer(T const& data) noexcept 289   171 make_buffer(T const& data) noexcept
228   { 290   {
HITCBC 229   513 return const_buffer( 291   513 return const_buffer(
HITCBC 230   342 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 292   342 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 231   171 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 293   171 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
232   } 294   }
233   295  
234 - /** Return a buffer from a const contiguous range with a maximum size. 296 + /** Return a buffer from a const contiguous range, clamped to a maximum size.
  297 +
  298 + Like the unclamped overload, but the result is no larger than
  299 + `max_size` bytes.
  300 +
  301 + @param data The range whose storage is referenced. It must
  302 + outlive the returned buffer.
  303 + @param max_size The maximum size, in bytes, of the result.
  304 + @return A buffer whose size is the smaller of
  305 + `size() * sizeof(element)` and `max_size`.
235   */ 306   */
236   template<detail::non_buffer_contiguous_range T> 307   template<detail::non_buffer_contiguous_range T>
237   [[nodiscard]] 308   [[nodiscard]]
238   const_buffer 309   const_buffer
HITCBC 239   722 make_buffer( 310   722 make_buffer(
240   T const& data, 311   T const& data,
241   std::size_t max_size) noexcept 312   std::size_t max_size) noexcept
242   { 313   {
HITCBC 243   722 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>); 314   722 auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
HITCBC 244   1449 return const_buffer( 315   1449 return const_buffer(
HITCBC 245   1444 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 316   1444 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 246   1444 n < max_size ? n : max_size); 317   1444 n < max_size ? n : max_size);
247   } 318   }
248   319  
249   } // capy 320   } // capy
250   } // boost 321   } // boost
251   322  
252   BOOST_CAPY_MSVC_WARNING_POP 323   BOOST_CAPY_MSVC_WARNING_POP
253   324  
254   #endif 325   #endif