LCOV - code coverage report
Current view: top level - boost/capy/buffers - make_buffer.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 105 105
Test Date: 2026-01-30 23:43:15 Functions: 100.0 % 47 47

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

Generated by: LCOV version 2.3