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-02-17 18:14:47 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                 : //------------------------------------------------
     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             168 : make_buffer(
     321                 :     std::basic_string<CharT, Traits, Allocator>& data) noexcept
     322                 : {
     323             502 :     return mutable_buffer(
     324             335 :         data.size() ? &data[0] : nullptr,
     325             169 :         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              49 : make_buffer(
     381                 :     std::basic_string_view<CharT, Traits> data) noexcept
     382                 : {
     383             145 :     return const_buffer(
     384              97 :         data.size() ? data.data() : nullptr,
     385              50 :         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