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 % 2 2
Test Date: 2026-05-14 20:50:55 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_impl.hpp>
      16                 : 
      17                 : #include <cstddef>
      18                 : #include <limits>
      19                 : 
      20                 : namespace boost {
      21                 : namespace capy {
      22                 : 
      23                 : /** Return a byte-range slice of a buffer sequence.
      24                 : 
      25                 :     Constructs a view over a contiguous byte range of `seq`. The
      26                 :     slice exposes its current bytes via `data()` (a buffer sequence)
      27                 :     and supports incremental consumption via `remove_prefix(n)`.
      28                 : 
      29                 :     @par Return Value
      30                 :     An object of unspecified type satisfying the @ref Slice concept.
      31                 :     Bind with `auto` and operate through the concept's members. When
      32                 :     `seq` models @ref MutableBufferSequence, the returned object
      33                 :     additionally models @ref MutableSlice.
      34                 : 
      35                 :     @par Lifetime
      36                 :     The returned slice is associated with `seq` as its underlying
      37                 :     buffer sequence. `seq` — and the memory referenced by its buffer
      38                 :     descriptors — must remain valid for as long as the slice, or
      39                 :     any buffer sequence obtained from its `data()`, is in use.
      40                 :     Passing a temporary buffer sequence to `buffer_slice` produces
      41                 :     a dangling slice.
      42                 : 
      43                 :     The buffer sequence returned by `data()` is independent of the
      44                 :     slice object: subsequent operations on the slice (mutation,
      45                 :     copy, move, destruction) do not invalidate an already-obtained
      46                 :     `data()` view. It remains valid for as long as `seq` is valid.
      47                 : 
      48                 :     Iterators and buffer descriptors obtained through `data()`
      49                 :     follow the same invalidation rules as those of `seq`.
      50                 : 
      51                 :     @par Parameters
      52                 :     @li `seq` The underlying buffer sequence. Must outlive the
      53                 :         returned slice and any `data()` view obtained from it.
      54                 :     @li `offset` Number of bytes to skip from the start of `seq`.
      55                 :         Clamped to `buffer_size(seq)`.
      56                 :     @li `length` Maximum number of bytes the slice will expose,
      57                 :         starting at `offset`. Clamped to `buffer_size(seq) - offset`.
      58                 :         Defaults to the maximum value of `std::size_t`, i.e. "to end".
      59                 : 
      60                 :     @par Example
      61                 :     @code
      62                 :     template< ReadStream Stream, MutableBufferSequence MB >
      63                 :     task< io_result< std::size_t > >
      64                 :     read_all( Stream& stream, MB buffers )
      65                 :     {
      66                 :         auto s = buffer_slice( buffers );
      67                 :         std::size_t const total_size = buffer_size( buffers );
      68                 :         std::size_t total = 0;
      69                 :         while( total < total_size )
      70                 :         {
      71                 :             auto [ec, n] = co_await stream.read_some( s.data() );
      72                 :             s.remove_prefix( n );
      73                 :             total += n;
      74                 :             if( ec )
      75                 :                 co_return {ec, total};
      76                 :         }
      77                 :         co_return {{}, total};
      78                 :     }
      79                 :     @endcode
      80                 : 
      81                 :     @see Slice, MutableSlice
      82                 : */
      83                 : template<class BufferSequence>
      84                 :     requires MutableBufferSequence<BufferSequence>
      85                 :           || ConstBufferSequence<BufferSequence>
      86                 : auto
      87 HIT        4369 : buffer_slice(
      88                 :     BufferSequence const& seq,
      89                 :     std::size_t offset = 0,
      90                 :     std::size_t length =
      91                 :         (std::numeric_limits<std::size_t>::max)()) noexcept
      92                 : {
      93            4369 :     return detail::slice_impl<BufferSequence>(seq, offset, length);
      94                 : }
      95                 : 
      96                 : /** Deleted overload that rejects rvalue arguments at compile time.
      97                 : 
      98                 :     Because the returned slice's validity depends on the underlying
      99                 :     buffer sequence remaining alive, calling `buffer_slice` with a
     100                 :     temporary buffer sequence would produce an immediately dangling
     101                 :     slice. This overload makes such calls ill-formed, surfacing the
     102                 :     lifetime error at compile time rather than as runtime UB.
     103                 : 
     104                 :     To slice a buffer sequence produced as a temporary, hoist it
     105                 :     into a named variable first:
     106                 : 
     107                 :     @code
     108                 :     auto bufs = some_dynamic_buffer.data();   // named, lives in scope
     109                 :     auto s = buffer_slice( bufs );            // OK
     110                 :     @endcode
     111                 : */
     112                 : template<class BufferSequence>
     113                 :     requires MutableBufferSequence<BufferSequence>
     114                 :           || ConstBufferSequence<BufferSequence>
     115                 : auto
     116                 : buffer_slice(
     117                 :     BufferSequence const&& seq,
     118                 :     std::size_t offset = 0,
     119                 :     std::size_t length =
     120                 :         (std::numeric_limits<std::size_t>::max)()) = delete;
     121                 : 
     122                 : } // namespace capy
     123                 : } // namespace boost
     124                 : 
     125                 : #endif
        

Generated by: LCOV version 2.3