LCOV - code coverage report
Current view: top level - capy/buffers - make_buffer.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 105 105
Test Date: 2026-03-12 20:08:21 Functions: 100.0 % 55 55

           TLA  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                 : BOOST_CAPY_MSVC_WARNING_PUSH
      26                 : BOOST_CAPY_MSVC_WARNING_DISABLE(4459)
      27                 : 
      28                 : namespace boost {
      29                 : namespace capy {
      30                 : 
      31                 : /** Return a buffer.
      32                 : */
      33                 : [[nodiscard]] inline
      34                 : mutable_buffer
      35 HIT           1 : make_buffer(
      36                 :     mutable_buffer const& b) noexcept
      37                 : {
      38               1 :     return b;
      39                 : }
      40                 : 
      41                 : /** Return a buffer with a maximum size.
      42                 : */
      43                 : [[nodiscard]] inline
      44                 : mutable_buffer
      45               2 : make_buffer(
      46                 :     mutable_buffer const& b,
      47                 :     std::size_t max_size) noexcept
      48                 : {
      49               5 :     return mutable_buffer(
      50                 :         b.data(),
      51               5 :         b.size() < max_size ? b.size() : max_size);
      52                 : }
      53                 : 
      54                 : /** Return a buffer.
      55                 : */
      56                 : [[nodiscard]] inline
      57                 : mutable_buffer
      58            4029 : make_buffer(
      59                 :     void* data,
      60                 :     std::size_t size) noexcept
      61                 : {
      62            4029 :     return mutable_buffer(data, size);
      63                 : }
      64                 : 
      65                 : /** Return a buffer with a maximum size.
      66                 : */
      67                 : [[nodiscard]] inline
      68                 : mutable_buffer
      69               2 : make_buffer(
      70                 :     void* data,
      71                 :     std::size_t size,
      72                 :     std::size_t max_size) noexcept
      73                 : {
      74               2 :     return mutable_buffer(
      75                 :         data,
      76               2 :         size < max_size ? size : max_size);
      77                 : }
      78                 : 
      79                 : /** Return a buffer.
      80                 : */
      81                 : [[nodiscard]] inline
      82                 : const_buffer
      83               1 : make_buffer(
      84                 :     const_buffer const& b) noexcept
      85                 : {
      86               1 :     return b;
      87                 : }
      88                 : 
      89                 : /** Return a buffer with a maximum size.
      90                 : */
      91                 : [[nodiscard]] inline
      92                 : const_buffer
      93               2 : make_buffer(
      94                 :     const_buffer const& b,
      95                 :     std::size_t max_size) noexcept
      96                 : {
      97               5 :     return const_buffer(
      98                 :         b.data(),
      99               5 :         b.size() < max_size ? b.size() : max_size);
     100                 : }
     101                 : 
     102                 : /** Return a buffer.
     103                 : */
     104                 : [[nodiscard]] inline
     105                 : const_buffer
     106               1 : make_buffer(
     107                 :     void const* data,
     108                 :     std::size_t size) noexcept
     109                 : {
     110               1 :     return const_buffer(data, size);
     111                 : }
     112                 : 
     113                 : /** Return a buffer with a maximum size.
     114                 : */
     115                 : [[nodiscard]] inline
     116                 : const_buffer
     117               2 : make_buffer(
     118                 :     void const* data,
     119                 :     std::size_t size,
     120                 :     std::size_t max_size) noexcept
     121                 : {
     122               2 :     return const_buffer(
     123                 :         data,
     124               2 :         size < max_size ? size : max_size);
     125                 : }
     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
     133             656 : make_buffer(
     134                 :     T (&data)[N]) noexcept
     135                 : {
     136             656 :     return mutable_buffer(
     137             656 :         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
     146              39 : make_buffer(
     147                 :     T (&data)[N],
     148                 :     std::size_t max_size) noexcept
     149                 : {
     150              78 :     return mutable_buffer(
     151                 :         data,
     152              39 :         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
     161               1 : make_buffer(
     162                 :     T const (&data)[N]) noexcept
     163                 : {
     164               1 :     return const_buffer(
     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
     174             714 : make_buffer(
     175                 :     T const (&data)[N],
     176                 :     std::size_t max_size) noexcept
     177                 : {
     178            1428 :     return const_buffer(
     179                 :         data,
     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
     191               2 : make_buffer(
     192                 :     std::array<T, N>& data) noexcept
     193                 : {
     194               4 :     return mutable_buffer(
     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
     204               2 : make_buffer(
     205                 :     std::array<T, N>& data,
     206                 :     std::size_t max_size) noexcept
     207                 : {
     208               6 :     return mutable_buffer(
     209               2 :         data.data(),
     210               2 :         data.size() * sizeof(T) < max_size
     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
     220               1 : make_buffer(
     221                 :     std::array<T, N> const& data) noexcept
     222                 : {
     223               1 :     return const_buffer(
     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
     233               2 : make_buffer(
     234                 :     std::array<T, N> const& data,
     235                 :     std::size_t max_size) noexcept
     236                 : {
     237               2 :     return const_buffer(
     238               2 :         data.data(),
     239               2 :         data.size() * sizeof(T) < max_size
     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
     251               3 : make_buffer(
     252                 :     std::vector<T, Allocator>& data) noexcept
     253                 : {
     254               7 :     return mutable_buffer(
     255               5 :         data.size() ? data.data() : nullptr,
     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
     265               2 : make_buffer(
     266                 :     std::vector<T, Allocator>& data,
     267                 :     std::size_t max_size) noexcept
     268                 : {
     269               6 :     return mutable_buffer(
     270               4 :         data.size() ? data.data() : nullptr,
     271               2 :         data.size() * sizeof(T) < max_size
     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
     281               1 : make_buffer(
     282                 :     std::vector<T, Allocator> const& data) noexcept
     283                 : {
     284               3 :     return const_buffer(
     285               2 :         data.size() ? data.data() : nullptr,
     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
     295               2 : make_buffer(
     296                 :     std::vector<T, Allocator> const& data,
     297                 :     std::size_t max_size) noexcept
     298                 : {
     299               6 :     return const_buffer(
     300               4 :         data.size() ? data.data() : nullptr,
     301               2 :         data.size() * sizeof(T) < max_size
     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
     312             168 : make_buffer(
     313                 :     std::basic_string<CharT, Traits, Allocator>& data) noexcept
     314                 : {
     315             502 :     return mutable_buffer(
     316             335 :         data.size() ? &data[0] : nullptr,
     317             169 :         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
     325               2 : make_buffer(
     326                 :     std::basic_string<CharT, Traits, Allocator>& data,
     327                 :     std::size_t max_size) noexcept
     328                 : {
     329               6 :     return mutable_buffer(
     330               4 :         data.size() ? &data[0] : nullptr,
     331               2 :         data.size() * sizeof(CharT) < max_size
     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
     340             163 : make_buffer(
     341                 :     std::basic_string<CharT, Traits, Allocator> const& data) noexcept
     342                 : {
     343             326 :     return const_buffer(
     344             163 :         data.data(),
     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
     353               2 : make_buffer(
     354                 :     std::basic_string<CharT, Traits, Allocator> const& data,
     355                 :     std::size_t max_size) noexcept
     356                 : {
     357               6 :     return const_buffer(
     358               2 :         data.data(),
     359               2 :         data.size() * sizeof(CharT) < max_size
     360               3 :             ? data.size() * sizeof(CharT) : max_size);
     361                 : }
     362                 : 
     363                 : // std::basic_string_view
     364                 : 
     365                 : /** Return a buffer from a std::basic_string_view.
     366                 : */
     367                 : template<class CharT, class Traits>
     368                 : [[nodiscard]]
     369                 : const_buffer
     370              49 : make_buffer(
     371                 :     std::basic_string_view<CharT, Traits> data) noexcept
     372                 : {
     373             145 :     return const_buffer(
     374              97 :         data.size() ? data.data() : nullptr,
     375              50 :         data.size() * sizeof(CharT));
     376                 : }
     377                 : 
     378                 : /** Return a buffer from a std::basic_string_view with a maximum size.
     379                 : */
     380                 : template<class CharT, class Traits>
     381                 : [[nodiscard]]
     382                 : const_buffer
     383               2 : make_buffer(
     384                 :     std::basic_string_view<CharT, Traits> data,
     385                 :     std::size_t max_size) noexcept
     386                 : {
     387               6 :     return const_buffer(
     388               4 :         data.size() ? data.data() : nullptr,
     389               2 :         data.size() * sizeof(CharT) < max_size
     390               3 :             ? data.size() * sizeof(CharT) : max_size);
     391                 : }
     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
     401               2 : make_buffer(
     402                 :     std::span<T, Extent> data) noexcept
     403                 : {
     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
     413               2 : make_buffer(
     414                 :     std::span<T, Extent> data,
     415                 :     std::size_t max_size) noexcept
     416                 : {
     417               6 :     return mutable_buffer(
     418               2 :         data.data(),
     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
     428               1 : make_buffer(
     429                 :     std::span<T const, Extent> data) noexcept
     430                 : {
     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
     440               2 : make_buffer(
     441                 :     std::span<T const, Extent> data,
     442                 :     std::size_t max_size) noexcept
     443                 : {
     444               6 :     return const_buffer(
     445               2 :         data.data(),
     446               5 :         data.size() < max_size ? data.size() : max_size);
     447                 : }
     448                 : 
     449                 : // Contiguous ranges
     450                 : 
     451                 : namespace detail {
     452                 : 
     453                 : template<class T>
     454                 : concept non_buffer_contiguous_range =
     455                 :     std::ranges::contiguous_range<T> &&
     456                 :     std::ranges::sized_range<T> &&
     457                 :     !std::convertible_to<T, const_buffer> &&
     458                 :     !std::convertible_to<T, mutable_buffer> &&
     459                 :     std::is_trivially_copyable_v<std::ranges::range_value_t<T>>;
     460                 : 
     461                 : template<class T>
     462                 : concept mutable_contiguous_range =
     463                 :     non_buffer_contiguous_range<T> &&
     464                 :     !std::is_const_v<std::remove_reference_t<
     465                 :         std::ranges::range_reference_t<T>>>;
     466                 : 
     467                 : template<class T>
     468                 : concept const_contiguous_range =
     469                 :     non_buffer_contiguous_range<T> &&
     470                 :     std::is_const_v<std::remove_reference_t<
     471                 :         std::ranges::range_reference_t<T>>>;
     472                 : 
     473                 : } // detail
     474                 : 
     475                 : /** Return a buffer from a mutable contiguous range.
     476                 : */
     477                 : template<detail::mutable_contiguous_range T>
     478                 : [[nodiscard]]
     479                 : mutable_buffer
     480                 : make_buffer(T& data) noexcept
     481                 : {
     482                 :     return mutable_buffer(
     483                 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     484                 :         std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
     485                 : }
     486                 : 
     487                 : /** Return a buffer from a mutable contiguous range with a maximum size.
     488                 : */
     489                 : template<detail::mutable_contiguous_range T>
     490                 : [[nodiscard]]
     491                 : mutable_buffer
     492                 : make_buffer(
     493                 :     T& data,
     494                 :     std::size_t max_size) noexcept
     495                 : {
     496                 :     auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
     497                 :     return mutable_buffer(
     498                 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     499                 :         n < max_size ? n : max_size);
     500                 : }
     501                 : 
     502                 : /** Return a buffer from a const contiguous range.
     503                 : */
     504                 : template<detail::non_buffer_contiguous_range T>
     505                 : [[nodiscard]]
     506                 : const_buffer
     507                 : make_buffer(T const& data) noexcept
     508                 : {
     509                 :     return const_buffer(
     510                 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     511                 :         std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
     512                 : }
     513                 : 
     514                 : /** Return a buffer from a const contiguous range with a maximum size.
     515                 : */
     516                 : template<detail::non_buffer_contiguous_range T>
     517                 : [[nodiscard]]
     518                 : const_buffer
     519                 : make_buffer(
     520                 :     T const& data,
     521                 :     std::size_t max_size) noexcept
     522                 : {
     523                 :     auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
     524                 :     return const_buffer(
     525                 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     526                 :         n < max_size ? n : max_size);
     527                 : }
     528                 : 
     529                 : } // capy
     530                 : } // boost
     531                 : 
     532                 : BOOST_CAPY_MSVC_WARNING_POP
     533                 : 
     534                 : #endif
        

Generated by: LCOV version 2.3