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 % 47 47
Test Date: 2026-08-14 20:51:18 Functions: 100.0 % 64 64

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
       3                 : // Copyright (c) 2026 Michael Vandeberg
       4                 : //
       5                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7                 : //
       8                 : // Official repository: https://github.com/cppalliance/capy
       9                 : //
      10                 : 
      11                 : #ifndef BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP
      12                 : #define BOOST_CAPY_BUFFERS_MAKE_BUFFER_HPP
      13                 : 
      14                 : #include <boost/capy/detail/config.hpp>
      15                 : #include <boost/capy/buffers.hpp>
      16                 : #include <array>
      17                 : #include <cstdlib>
      18                 : #include <iterator>
      19                 : #include <ranges>
      20                 : #include <span>
      21                 : #include <string>
      22                 : #include <string_view>
      23                 : #include <type_traits>
      24                 : #include <vector>
      25                 : 
      26                 : BOOST_CAPY_MSVC_WARNING_PUSH
      27                 : BOOST_CAPY_MSVC_WARNING_DISABLE(4459)
      28                 : 
      29                 : namespace boost {
      30                 : namespace capy {
      31                 : 
      32                 : /** Return the buffer unchanged.
      33                 : 
      34                 :     @param b The buffer to return.
      35                 :     @return A copy of `b`, referring to the same storage.
      36                 : */
      37                 : [[nodiscard]] inline
      38                 : mutable_buffer
      39 HIT           1 : make_buffer(
      40                 :     mutable_buffer const& b) noexcept
      41                 : {
      42               1 :     return b;
      43                 : }
      44                 : 
      45                 : /** Return the buffer, clamped to a maximum size.
      46                 : 
      47                 :     @param b The buffer to return.
      48                 :     @param max_size The maximum size, in bytes, of the result.
      49                 :     @return A buffer referring to the storage of `b` whose size
      50                 :         is the smaller of `b.size()` and `max_size`.
      51                 : */
      52                 : [[nodiscard]] inline
      53                 : mutable_buffer
      54               2 : make_buffer(
      55                 :     mutable_buffer const& b,
      56                 :     std::size_t max_size) noexcept
      57                 : {
      58               5 :     return mutable_buffer(
      59                 :         b.data(),
      60               5 :         b.size() < max_size ? b.size() : max_size);
      61                 : }
      62                 : 
      63                 : /** Return a buffer referring to a region of memory.
      64                 : 
      65                 :     @param data A pointer to the start of the region. The region
      66                 :         must outlive the returned buffer.
      67                 :     @param size The size of the region, in bytes.
      68                 :     @return A buffer referring to `[data, data + size)`.
      69                 : */
      70                 : [[nodiscard]] inline
      71                 : mutable_buffer
      72             717 : make_buffer(
      73                 :     void* data,
      74                 :     std::size_t size) noexcept
      75                 : {
      76             717 :     return mutable_buffer(data, size);
      77                 : }
      78                 : 
      79                 : /** Return a buffer referring to a region of memory, clamped to a maximum size.
      80                 : 
      81                 :     @param data A pointer to the start of the region. The region
      82                 :         must outlive the returned buffer.
      83                 :     @param size The size of the region, in bytes.
      84                 :     @param max_size The maximum size, in bytes, of the result.
      85                 :     @return A buffer referring to `data` whose size is the smaller
      86                 :         of `size` and `max_size`.
      87                 : */
      88                 : [[nodiscard]] inline
      89                 : mutable_buffer
      90               2 : make_buffer(
      91                 :     void* data,
      92                 :     std::size_t size,
      93                 :     std::size_t max_size) noexcept
      94                 : {
      95               2 :     return mutable_buffer(
      96                 :         data,
      97               2 :         size < max_size ? size : max_size);
      98                 : }
      99                 : 
     100                 : /** Return the buffer unchanged.
     101                 : 
     102                 :     @param b The buffer to return.
     103                 :     @return A copy of `b`, referring to the same storage.
     104                 : */
     105                 : [[nodiscard]] inline
     106                 : const_buffer
     107               1 : make_buffer(
     108                 :     const_buffer const& b) noexcept
     109                 : {
     110               1 :     return b;
     111                 : }
     112                 : 
     113                 : /** Return the buffer, clamped to a maximum size.
     114                 : 
     115                 :     @param b The buffer to return.
     116                 :     @param max_size The maximum size, in bytes, of the result.
     117                 :     @return A buffer referring to the storage of `b` whose size
     118                 :         is the smaller of `b.size()` and `max_size`.
     119                 : */
     120                 : [[nodiscard]] inline
     121                 : const_buffer
     122               2 : make_buffer(
     123                 :     const_buffer const& b,
     124                 :     std::size_t max_size) noexcept
     125                 : {
     126               5 :     return const_buffer(
     127                 :         b.data(),
     128               5 :         b.size() < max_size ? b.size() : max_size);
     129                 : }
     130                 : 
     131                 : /** Return a buffer referring to a region of memory.
     132                 : 
     133                 :     @param data A pointer to the start of the region. The region
     134                 :         must outlive the returned buffer.
     135                 :     @param size The size of the region, in bytes.
     136                 :     @return A buffer referring to `[data, data + size)`.
     137                 : */
     138                 : [[nodiscard]] inline
     139                 : const_buffer
     140               1 : make_buffer(
     141                 :     void const* data,
     142                 :     std::size_t size) noexcept
     143                 : {
     144               1 :     return const_buffer(data, size);
     145                 : }
     146                 : 
     147                 : /** Return a buffer referring to a region of memory, clamped to a maximum size.
     148                 : 
     149                 :     @param data A pointer to the start of the region. The region
     150                 :         must outlive the returned buffer.
     151                 :     @param size The size of the region, in bytes.
     152                 :     @param max_size The maximum size, in bytes, of the result.
     153                 :     @return A buffer referring to `data` whose size is the smaller
     154                 :         of `size` and `max_size`.
     155                 : */
     156                 : [[nodiscard]] inline
     157                 : const_buffer
     158               2 : make_buffer(
     159                 :     void const* data,
     160                 :     std::size_t size,
     161                 :     std::size_t max_size) noexcept
     162                 : {
     163               2 :     return const_buffer(
     164                 :         data,
     165               2 :         size < max_size ? size : max_size);
     166                 : }
     167                 : 
     168                 : // std::basic_string_view
     169                 : 
     170                 : /** Return a buffer from a `std::basic_string_view`.
     171                 : 
     172                 :     @param data The view whose characters are referenced. The
     173                 :         underlying storage must outlive the returned buffer.
     174                 :     @return A buffer referring to the view's storage. The size,
     175                 :         in bytes, is `data.size() * sizeof(CharT)`.
     176                 : */
     177                 : template<class CharT, class Traits>
     178                 : [[nodiscard]]
     179                 : const_buffer
     180              58 : make_buffer(
     181                 :     std::basic_string_view<CharT, Traits> data) noexcept
     182                 : {
     183             171 :     return const_buffer(
     184             114 :         data.size() ? data.data() : nullptr,
     185              59 :         data.size() * sizeof(CharT));
     186                 : }
     187                 : 
     188                 : /** Return a buffer from a `std::basic_string_view`, clamped to a maximum size.
     189                 : 
     190                 :     @param data The view whose characters are referenced. The
     191                 :         underlying storage must outlive the returned buffer.
     192                 :     @param max_size The maximum size, in bytes, of the result.
     193                 :     @return A buffer referring to the view's storage whose size is
     194                 :         the smaller of `data.size() * sizeof(CharT)` and `max_size`.
     195                 : */
     196                 : template<class CharT, class Traits>
     197                 : [[nodiscard]]
     198                 : const_buffer
     199               2 : make_buffer(
     200                 :     std::basic_string_view<CharT, Traits> data,
     201                 :     std::size_t max_size) noexcept
     202                 : {
     203               6 :     return const_buffer(
     204               4 :         data.size() ? data.data() : nullptr,
     205               2 :         data.size() * sizeof(CharT) < max_size
     206               3 :             ? data.size() * sizeof(CharT) : max_size);
     207                 : }
     208                 : 
     209                 : // Contiguous ranges
     210                 : 
     211                 : namespace detail {
     212                 : 
     213                 : template<class T>
     214                 : concept non_buffer_contiguous_range =
     215                 :     std::ranges::contiguous_range<T> &&
     216                 :     std::ranges::sized_range<T> &&
     217                 :     !std::convertible_to<T, const_buffer> &&
     218                 :     !std::convertible_to<T, mutable_buffer> &&
     219                 :     std::is_trivially_copyable_v<std::ranges::range_value_t<T>>;
     220                 : 
     221                 : template<class T>
     222                 : concept mutable_contiguous_range =
     223                 :     non_buffer_contiguous_range<T> &&
     224                 :     !std::is_const_v<std::remove_reference_t<
     225                 :         std::ranges::range_reference_t<T>>>;
     226                 : 
     227                 : template<class T>
     228                 : concept const_contiguous_range =
     229                 :     non_buffer_contiguous_range<T> &&
     230                 :     std::is_const_v<std::remove_reference_t<
     231                 :         std::ranges::range_reference_t<T>>>;
     232                 : 
     233                 : } // detail
     234                 : 
     235                 : /** Return a buffer from a mutable contiguous range.
     236                 : 
     237                 :     Accepts any sized, contiguous range of trivially-copyable,
     238                 :     non-const elements, whether passed as an lvalue or a temporary.
     239                 :     That includes `std::vector`, `std::array`, `std::string`,
     240                 :     `std::span`, `boost::span`, and built-in arrays. The returned buffer
     241                 :     refers to the range's storage, which must outlive the buffer.
     242                 :     Its size, in bytes, is `size() * sizeof(element)`.
     243                 : 
     244                 :     @param data The range whose storage is referenced. It must
     245                 :         outlive the returned buffer.
     246                 : 
     247                 :     @return A buffer of size `size() * sizeof(element)` referring to
     248                 :         the range's storage.
     249                 : */
     250                 : template<detail::mutable_contiguous_range T>
     251                 : [[nodiscard]]
     252                 : mutable_buffer
     253             649 : make_buffer(T&& data) noexcept
     254                 : {
     255            1940 :     return mutable_buffer(
     256            1295 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     257             653 :         std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
     258                 : }
     259                 : 
     260                 : /** Return a buffer from a mutable contiguous range, clamped to a maximum size.
     261                 : 
     262                 :     Like the unclamped overload, but the result is no larger than
     263                 :     `max_size` bytes.
     264                 : 
     265                 :     @param data The range whose storage is referenced. It must
     266                 :         outlive the returned buffer.
     267                 :     @param max_size The maximum size, in bytes, of the result.
     268                 :     @return A buffer whose size is the smaller of
     269                 :         `size() * sizeof(element)` and `max_size`.
     270                 : */
     271                 : template<detail::mutable_contiguous_range T>
     272                 : [[nodiscard]]
     273                 : mutable_buffer
     274              42 : make_buffer(
     275                 :     T&& data,
     276                 :     std::size_t max_size) noexcept
     277                 : {
     278              42 :     auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
     279              89 :     return mutable_buffer(
     280              84 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     281              84 :         n < max_size ? n : max_size);
     282                 : }
     283                 : 
     284                 : /** Return a buffer from a const contiguous range.
     285                 : 
     286                 :     Accepts any sized, contiguous range of trivially-copyable
     287                 :     elements with const access, including const `std::vector`,
     288                 :     `std::array`, `std::string`, `std::span`, `boost::span`, and
     289                 :     string literals. The returned buffer refers to the range's
     290                 :     storage, which must outlive the buffer. Its size, in bytes,
     291                 :     is `size() * sizeof(element)`.
     292                 : 
     293                 :     @param data The range whose storage is referenced. It must
     294                 :         outlive the returned buffer.
     295                 : 
     296                 :     @return A buffer of size `size() * sizeof(element)` referring to
     297                 :         the range's storage.
     298                 : */
     299                 : template<detail::non_buffer_contiguous_range T>
     300                 : [[nodiscard]]
     301                 : const_buffer
     302              65 : make_buffer(T const& data) noexcept
     303                 : {
     304             195 :     return const_buffer(
     305             130 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     306              65 :         std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>));
     307                 : }
     308                 : 
     309                 : /** Return a buffer from a const contiguous range, clamped to a maximum size.
     310                 : 
     311                 :     Like the unclamped overload, but the result is no larger than
     312                 :     `max_size` bytes.
     313                 : 
     314                 :     @param data The range whose storage is referenced. It must
     315                 :         outlive the returned buffer.
     316                 :     @param max_size The maximum size, in bytes, of the result.
     317                 :     @return A buffer whose size is the smaller of
     318                 :         `size() * sizeof(element)` and `max_size`.
     319                 : */
     320                 : template<detail::non_buffer_contiguous_range T>
     321                 : [[nodiscard]]
     322                 : const_buffer
     323             366 : make_buffer(
     324                 :     T const& data,
     325                 :     std::size_t max_size) noexcept
     326                 : {
     327             366 :     auto const n = std::ranges::size(data) * sizeof(std::ranges::range_value_t<T>);
     328             737 :     return const_buffer(
     329             732 :         std::ranges::size(data) ? std::ranges::data(data) : nullptr,
     330             732 :         n < max_size ? n : max_size);
     331                 : }
     332                 : 
     333                 : } // capy
     334                 : } // boost
     335                 : 
     336                 : BOOST_CAPY_MSVC_WARNING_POP
     337                 : 
     338                 : #endif
        

Generated by: LCOV version 2.3