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

Generated by: LCOV version 2.3