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   4047 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   4047 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   126  
127   // std::basic_string_view 127   // std::basic_string_view
128   128  
129   /** Return a buffer from a std::basic_string_view. 129   /** Return a buffer from a std::basic_string_view.
130   */ 130   */
131   template<class CharT, class Traits> 131   template<class CharT, class Traits>
132   [[nodiscard]] 132   [[nodiscard]]
133   const_buffer 133   const_buffer
HITCBC 134   46 make_buffer( 134   46 make_buffer(
135   std::basic_string_view<CharT, Traits> data) noexcept 135   std::basic_string_view<CharT, Traits> data) noexcept
136   { 136   {
HITCBC 137   136 return const_buffer( 137   136 return const_buffer(
HITCBC 138   91 data.size() ? data.data() : nullptr, 138   91 data.size() ? data.data() : nullptr,
HITCBC 139   47 data.size() * sizeof(CharT)); 139   47 data.size() * sizeof(CharT));
140   } 140   }
141   141  
142   /** 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.
143   */ 143   */
144   template<class CharT, class Traits> 144   template<class CharT, class Traits>
145   [[nodiscard]] 145   [[nodiscard]]
146   const_buffer 146   const_buffer
HITCBC 147   2 make_buffer( 147   2 make_buffer(
148   std::basic_string_view<CharT, Traits> data, 148   std::basic_string_view<CharT, Traits> data,
149   std::size_t max_size) noexcept 149   std::size_t max_size) noexcept
150   { 150   {
HITCBC 151   6 return const_buffer( 151   6 return const_buffer(
HITCBC 152   4 data.size() ? data.data() : nullptr, 152   4 data.size() ? data.data() : nullptr,
HITCBC 153   2 data.size() * sizeof(CharT) < max_size 153   2 data.size() * sizeof(CharT) < max_size
HITCBC 154   3 ? data.size() * sizeof(CharT) : max_size); 154   3 ? data.size() * sizeof(CharT) : max_size);
155   } 155   }
156   156  
157   // Contiguous ranges 157   // Contiguous ranges
158   158  
159   namespace detail { 159   namespace detail {
160   160  
161   template<class T> 161   template<class T>
162   concept non_buffer_contiguous_range = 162   concept non_buffer_contiguous_range =
163   std::ranges::contiguous_range<T> && 163   std::ranges::contiguous_range<T> &&
164   std::ranges::sized_range<T> && 164   std::ranges::sized_range<T> &&
165   !std::convertible_to<T, const_buffer> && 165   !std::convertible_to<T, const_buffer> &&
166   !std::convertible_to<T, mutable_buffer> && 166   !std::convertible_to<T, mutable_buffer> &&
167   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>; 167   std::is_trivially_copyable_v<std::ranges::range_value_t<T>>;
168   168  
169   template<class T> 169   template<class T>
170   concept mutable_contiguous_range = 170   concept mutable_contiguous_range =
171   non_buffer_contiguous_range<T> && 171   non_buffer_contiguous_range<T> &&
172   !std::is_const_v<std::remove_reference_t< 172   !std::is_const_v<std::remove_reference_t<
173   std::ranges::range_reference_t<T>>>; 173   std::ranges::range_reference_t<T>>>;
174   174  
175   template<class T> 175   template<class T>
176   concept const_contiguous_range = 176   concept const_contiguous_range =
177   non_buffer_contiguous_range<T> && 177   non_buffer_contiguous_range<T> &&
178   std::is_const_v<std::remove_reference_t< 178   std::is_const_v<std::remove_reference_t<
179   std::ranges::range_reference_t<T>>>; 179   std::ranges::range_reference_t<T>>>;
180   180  
181   } // detail 181   } // detail
182   182  
183   /** Return a buffer from a mutable contiguous range. 183   /** Return a buffer from a mutable contiguous range.
184   184  
185   Accepts any sized, contiguous range of trivially-copyable, 185   Accepts any sized, contiguous range of trivially-copyable,
186   non-const elements, including `std::vector`, `std::array`, 186   non-const elements, including `std::vector`, `std::array`,
187   `std::string`, `std::span`, `boost::span`, and built-in arrays, 187   `std::string`, `std::span`, `boost::span`, and built-in arrays,
188   whether passed as an lvalue or a temporary. The returned buffer 188   whether passed as an lvalue or a temporary. The returned buffer
189   refers to the range's storage, which must outlive the buffer. 189   refers to the range's storage, which must outlive the buffer.
190   */ 190   */
191   template<detail::mutable_contiguous_range T> 191   template<detail::mutable_contiguous_range T>
192   [[nodiscard]] 192   [[nodiscard]]
193   mutable_buffer 193   mutable_buffer
HITCBC 194   836 make_buffer(T&& data) noexcept 194   836 make_buffer(T&& data) noexcept
195   { 195   {
HITCBC 196   2502 return mutable_buffer( 196   2502 return mutable_buffer(
HITCBC 197   1670 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 197   1670 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 198   840 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 198   840 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
199   } 199   }
200   200  
201   /** 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.
202   */ 202   */
203   template<detail::mutable_contiguous_range T> 203   template<detail::mutable_contiguous_range T>
204   [[nodiscard]] 204   [[nodiscard]]
205   mutable_buffer 205   mutable_buffer
HITCBC 206   53 make_buffer( 206   53 make_buffer(
207   T&& data, 207   T&& data,
208   std::size_t max_size) noexcept 208   std::size_t max_size) noexcept
209   { 209   {
HITCBC 210   53 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>);
HITCBC 211   111 return mutable_buffer( 211   111 return mutable_buffer(
HITCBC 212   106 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 212   106 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 213   106 n < max_size ? n : max_size); 213   106 n < max_size ? n : max_size);
214   } 214   }
215   215  
216   /** Return a buffer from a const contiguous range. 216   /** Return a buffer from a const contiguous range.
217   217  
218   Accepts any sized, contiguous range of trivially-copyable 218   Accepts any sized, contiguous range of trivially-copyable
219   elements with const access, including const `std::vector`, 219   elements with const access, including const `std::vector`,
220   `std::array`, `std::string`, `std::span`, `boost::span`, and 220   `std::array`, `std::string`, `std::span`, `boost::span`, and
221   string literals. The returned buffer refers to the range's 221   string literals. The returned buffer refers to the range's
222   storage, which must outlive the buffer. 222   storage, which must outlive the buffer.
223   */ 223   */
224   template<detail::non_buffer_contiguous_range T> 224   template<detail::non_buffer_contiguous_range T>
225   [[nodiscard]] 225   [[nodiscard]]
226   const_buffer 226   const_buffer
HITCBC 227   171 make_buffer(T const& data) noexcept 227   171 make_buffer(T const& data) noexcept
228   { 228   {
HITCBC 229   513 return const_buffer( 229   513 return const_buffer(
HITCBC 230   342 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 230   342 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 231   171 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>)); 231   171 std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
232   } 232   }
233   233  
234   /** 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.
235   */ 235   */
236   template<detail::non_buffer_contiguous_range T> 236   template<detail::non_buffer_contiguous_range T>
237   [[nodiscard]] 237   [[nodiscard]]
238   const_buffer 238   const_buffer
HITCBC 239   722 make_buffer( 239   722 make_buffer(
240   T const& data, 240   T const& data,
241   std::size_t max_size) noexcept 241   std::size_t max_size) noexcept
242   { 242   {
HITCBC 243   722 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>);
HITCBC 244   1449 return const_buffer( 244   1449 return const_buffer(
HITCBC 245   1444 std::ranges::size(data) ? std::ranges::data(data) : nullptr, 245   1444 std::ranges::size(data) ? std::ranges::data(data) : nullptr,
HITCBC 246   1444 n < max_size ? n : max_size); 246   1444 n < max_size ? n : max_size);
247   } 247   }
248   248  
249   } // capy 249   } // capy
250   } // boost 250   } // boost
251   251  
252   BOOST_CAPY_MSVC_WARNING_POP 252   BOOST_CAPY_MSVC_WARNING_POP
253   253  
254   #endif 254   #endif