Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 66 additions & 18 deletions include/boost/capy/buffers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,24 +200,41 @@ concept MutableBufferSequence =

/** Return an iterator to the first buffer in a sequence.

Handles single buffers and ranges uniformly. For a single buffer,
returns a pointer to it (forming a one-element range).
@functionobject
*/
constexpr struct begin_mrdocs_workaround_t
constexpr struct
{
/** Return a pointer to a single buffer, forming a one-element range.

@param b A single buffer.

@return A pointer to `b`.
*/
template<std::convertible_to<const_buffer> ConvertibleToBuffer>
auto operator()(ConvertibleToBuffer const& b) const noexcept -> ConvertibleToBuffer const*
{
return std::addressof(b);
}

/** Return an iterator to the first buffer of a sequence.

@param bs The buffer sequence.

@return An iterator to the first buffer of `bs`.
*/
template<ConstBufferSequence BS>
requires (!std::convertible_to<BS, const_buffer>)
auto operator()(BS const& bs) const noexcept
{
return std::ranges::begin(bs);
}

/** Return an iterator to the first buffer of a sequence.

@param bs The buffer sequence.

@return An iterator to the first buffer of `bs`.
*/
template<ConstBufferSequence BS>
requires (!std::convertible_to<BS, const_buffer>)
auto operator()(BS& bs) const noexcept
Expand All @@ -228,24 +245,41 @@ constexpr struct begin_mrdocs_workaround_t

/** Return an iterator past the last buffer in a sequence.

Handles single buffers and ranges uniformly. For a single buffer,
returns a pointer one past it.
@functionobject
*/
constexpr struct end_mrdocs_workaround_t
constexpr struct
{
/** Return a pointer one past a single buffer, forming a one-element range.

@param b A single buffer.

@return A pointer one past `b`.
*/
template<std::convertible_to<const_buffer> ConvertibleToBuffer>
auto operator()(ConvertibleToBuffer const& b) const noexcept -> ConvertibleToBuffer const*
{
return std::addressof(b) + 1;
}

/** Return an iterator past the last buffer of a sequence.

@param bs The buffer sequence.

@return An iterator one past the last buffer of `bs`.
*/
template<ConstBufferSequence BS>
requires (!std::convertible_to<BS, const_buffer>)
auto operator()(BS const& bs) const noexcept
{
return std::ranges::end(bs);
}

/** Return an iterator past the last buffer of a sequence.

@param bs The buffer sequence.

@return An iterator one past the last buffer of `bs`.
*/
template<ConstBufferSequence BS>
requires (!std::convertible_to<BS, const_buffer>)
auto operator()(BS& bs) const noexcept
Expand All @@ -256,16 +290,9 @@ constexpr struct end_mrdocs_workaround_t

/** Return the total byte count across all buffers in a sequence.

Sums the `size()` of each buffer in the sequence. This differs
from `buffer_length` which counts the number of buffer elements.

@par Example
@code
std::array<mutable_buffer, 2> bufs = { ... };
std::size_t total = buffer_size( bufs ); // sum of both sizes
@endcode
@functionobject
*/
constexpr struct buffer_size_mrdocs_workaround_t
constexpr struct
{
// GCC 13 falsely flags reads of arr_[i].n_ in detail::buffer_array
// when iterating here. The class uses union storage with placement
Expand All @@ -277,6 +304,21 @@ constexpr struct buffer_size_mrdocs_workaround_t
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
/** Return the total byte count across all buffers in a sequence.

Sums the `size()` of each buffer in the sequence. This differs
from `buffer_length` which counts the number of buffer elements.

@param bs The buffer sequence.

@return The sum of the sizes of all buffers in `bs`.

@par Example
@code
std::array<mutable_buffer, 2> bufs = { ... };
std::size_t total = buffer_size( bufs ); // sum of both sizes
@endcode
*/
template<ConstBufferSequence CB>
constexpr std::size_t operator()(
CB const& bs) const noexcept
Expand All @@ -294,16 +336,22 @@ constexpr struct buffer_size_mrdocs_workaround_t

/** Check if a buffer sequence contains no data.

@return `true` if all buffers have size zero or the sequence
is empty.
@functionobject
*/
constexpr struct buffer_empty_mrdocs_workaround_t
constexpr struct
{
// See note on buffer_size above — same union-storage false positive.
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
/** Check if a buffer sequence contains no data.

@param bs The buffer sequence.

@return `true` if all buffers have size zero or the sequence
is empty.
*/
template<ConstBufferSequence CB>
constexpr bool operator()(
CB const& bs) const noexcept
Expand Down
32 changes: 17 additions & 15 deletions include/boost/capy/buffers/buffer_copy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,26 @@ namespace capy {

/** Copy the contents of a buffer sequence into another buffer sequence.

This function copies bytes from the constant buffer sequence `src` into
the mutable buffer sequence `dest`, stopping when any limit is reached.
@functionobject
*/
constexpr struct
{
/** Copy the contents of a buffer sequence into another buffer sequence.

@par Constraints
@code
MutableBufferSequence<decltype(dest)> &&
ConstBufferSequence<decltype(src)>
@endcode
Copies bytes from the constant buffer sequence `src` into the
mutable buffer sequence `dest`, stopping when any limit is
reached.

@return The number of bytes copied, equal to
`std::min(size(dest), size(src), at_most)`.
@param dest The destination buffer sequence.

@param dest The destination buffer sequence.
@param src The source buffer sequence.
@param at_most The maximum bytes to copy. Default copies all available.
*/
constexpr struct buffer_copy_mrdocs_workaround_t
{
@param src The source buffer sequence.

@param at_most The maximum bytes to copy. Default copies all
available.

@return The number of bytes copied, equal to
`std::min(size(dest), size(src), at_most)`.
*/
template<
MutableBufferSequence MB,
ConstBufferSequence CB>
Expand Down
18 changes: 14 additions & 4 deletions include/boost/capy/buffers/buffer_slice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ namespace capy {
Iterators and buffer descriptors obtained through `data()`
follow the same invalidation rules as those of `seq`.

@par Parameters
@li `seq` The underlying buffer sequence. Must outlive the
@param seq The underlying buffer sequence. Must outlive the
returned slice and any `data()` view obtained from it.
@li `offset` Number of bytes to skip from the start of `seq`.

@param offset Number of bytes to skip from the start of `seq`.
Clamped to `buffer_size(seq)`.
@li `length` Maximum number of bytes the slice will expose,

@param length Maximum number of bytes the slice will expose,
starting at `offset`. Clamped to `buffer_size(seq) - offset`.
Defaults to the maximum value of `std::size_t`, i.e. "to end".

Expand Down Expand Up @@ -108,6 +109,15 @@ buffer_slice(
auto bufs = some_dynamic_buffer.data(); // named, lives in scope
auto s = buffer_slice( bufs ); // OK
@endcode

@param seq An rvalue buffer sequence (`const&&`). Binding the
slice to a temporary would dangle, so this overload is
deleted to reject such calls at compile time.

@param offset Number of bytes to skip from the start of `seq`.

@param length Maximum number of bytes the slice would expose,
starting at `offset`.
*/
template<class BufferSequence>
requires MutableBufferSequence<BufferSequence>
Expand Down
20 changes: 17 additions & 3 deletions include/boost/capy/buffers/front.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@ namespace boost {
namespace capy {

/** Return the first buffer in a sequence.

@functionobject
*/
constexpr struct front_mrdocs_workaround_t
constexpr struct
{
/// Return the first mutable buffer, or an empty buffer.
/** Return the first mutable buffer, or an empty buffer.

@param bs The buffer sequence to inspect.

@return The first buffer in `bs`, or an empty buffer if `bs`
contains no buffers.
*/
template<MutableBufferSequence MutableBufferSequence>
mutable_buffer
operator()(
Expand All @@ -32,7 +40,13 @@ constexpr struct front_mrdocs_workaround_t
return {};
}

/// Return the first const buffer, or an empty buffer.
/** Return the first const buffer, or an empty buffer.

@param bs The buffer sequence to inspect.

@return The first buffer in `bs`, or an empty buffer if `bs`
contains no buffers.
*/
template<ConstBufferSequence ConstBufferSequence>
requires (!MutableBufferSequence<ConstBufferSequence>)
const_buffer
Expand Down
4 changes: 4 additions & 0 deletions include/boost/capy/when_any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,10 @@ template<IoAwaitableRange R>
Only a child returning !ec can win. Errors and exceptions do
not claim winner status.

@param as The awaitables to race. Each must satisfy @ref
IoAwaitable and is consumed (moved-from) when `when_any`
is awaited.

@return A task yielding variant<error_code, R1, ..., Rn> where
index 0 is the failure/no-winner case and index i+1
identifies the winning child.
Expand Down
Loading