LCOV - code coverage report
Current view: top level - capy/buffers - buffer_slice.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 7 7
Test Date: 2026-07-22 18:54:45 Functions: 100.0 % 10 10

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Michael Vandeberg
       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_BUFFER_SLICE_HPP
      11                 : #define BOOST_CAPY_BUFFERS_BUFFER_SLICE_HPP
      12                 : 
      13                 : #include <boost/capy/detail/config.hpp>
      14                 : #include <boost/capy/buffers.hpp>
      15                 : #include <boost/capy/detail/slice_of.hpp>
      16                 : 
      17                 : #include <concepts>
      18                 : #include <cstddef>
      19                 : #include <limits>
      20                 : #include <type_traits>
      21                 : 
      22                 : namespace boost {
      23                 : namespace capy {
      24                 : 
      25                 : /** The type produced by `buffer_slice` for a sequence `BS`.
      26                 : 
      27                 :     A single buffer is closed under sub-ranging, so slicing it yields a
      28                 :     buffer of the same kind. Any other sequence yields the generic
      29                 :     `detail::slice_of<BS>` borrowed view. In both cases the result is itself
      30                 :     a buffer sequence — `slice_type<BS> ∈ { buffer, slice_of<BS> }`.
      31                 : */
      32                 : template<class BS>
      33                 : using slice_type = std::conditional_t<
      34                 :     std::convertible_to<BS, const_buffer>,
      35                 :     buffer_type<BS>,
      36                 :     detail::slice_of<BS>>;
      37                 : 
      38                 : /** Return a byte sub-range of a buffer sequence, as a value.
      39                 : 
      40                 :     The result is itself a buffer sequence (`slice_type<BS>`): pass it
      41                 :     directly to any operation expecting a buffer sequence — there is no
      42                 :     `.data()` and no separate concept to bind. For a single buffer the
      43                 :     result is an adjusted buffer; for any other sequence it is a borrowed
      44                 :     `slice_of<BS>` view.
      45                 : 
      46                 :     @par Lifetime
      47                 :     Except for the single-buffer case, the result borrows `seq`: it stores
      48                 :     iterators into the sequence, not a copy. `seq` must outlive the result.
      49                 :     The rvalue overload is deleted so a temporary cannot be sliced into a
      50                 :     dangling view.
      51                 : 
      52                 :     @par Complexity
      53                 :     Single forward pass to the cut points; never sums the whole sequence.
      54                 : 
      55                 :     @param seq The sequence to slice. Must outlive the result.
      56                 :     @param offset Bytes skipped from the front. Clamped to the total size.
      57                 :     @param length Bytes exposed, starting at `offset`. Defaults to the end.
      58                 : 
      59                 :     @return A `slice_type<BS>` value modeling the same buffer-sequence
      60                 :         concept as `seq` (mutable if `seq` is mutable).
      61                 : 
      62                 :     @par Example
      63                 :     @code
      64                 :     co_await write(sock, buffer_slice(bufs, 0, 16384));  // first 16 KB
      65                 :     auto rest = buffer_slice(bufs, n);                   // drop first n
      66                 :     @endcode
      67                 : 
      68                 :     @see slice_type, consuming_buffers
      69                 : */
      70                 : template<class BufferSequence>
      71                 :     requires MutableBufferSequence<BufferSequence>
      72                 :           || ConstBufferSequence<BufferSequence>
      73                 : slice_type<BufferSequence>
      74 HIT        2576 : buffer_slice(
      75                 :     BufferSequence const& seq,
      76                 :     std::size_t offset = 0,
      77                 :     std::size_t length =
      78                 :         (std::numeric_limits<std::size_t>::max)()) noexcept
      79                 : {
      80                 :     if constexpr (std::convertible_to<BufferSequence, const_buffer>)
      81                 :     {
      82                 :         // A single buffer is its own slice: advance and (maybe) truncate.
      83             292 :         buffer_type<BufferSequence> b = seq;
      84             292 :         b += offset;  // operator+= clamps to size()
      85             292 :         if (length < b.size())
      86             115 :             b = buffer_type<BufferSequence>(b.data(), length);
      87             292 :         return b;
      88                 :     }
      89                 :     else
      90                 :     {
      91            2284 :         return detail::slice_of<BufferSequence>(seq, offset, length);
      92                 :     }
      93                 : }
      94                 : 
      95                 : /** Deleted rvalue overload.
      96                 : 
      97                 :     Slicing a temporary would yield an immediately dangling view (the
      98                 :     result borrows the sequence). Hoist the sequence into a named variable
      99                 :     first.
     100                 : */
     101                 : template<class BufferSequence>
     102                 :     requires MutableBufferSequence<BufferSequence>
     103                 :           || ConstBufferSequence<BufferSequence>
     104                 : slice_type<BufferSequence>
     105                 : buffer_slice(
     106                 :     BufferSequence const&& seq,
     107                 :     std::size_t offset = 0,
     108                 :     std::size_t length =
     109                 :         (std::numeric_limits<std::size_t>::max)()) = delete;
     110                 : 
     111                 : } // namespace capy
     112                 : } // namespace boost
     113                 : 
     114                 : #endif
        

Generated by: LCOV version 2.3