Pigweed
C/C++ API Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Protected Types | List of all members
pw::multibuf::BasicMultiBuf< kProperties > Class Template Reference

Public Types

using size_type = typename Deque::size_type
 
using difference_type = typename Deque::difference_type
 
using iterator = internal::ByteIterator< size_type, false >
 
using const_iterator = internal::ByteIterator< size_type, true >
 
using pointer = iterator::pointer
 
using const_pointer = const_iterator::pointer
 
using reference = iterator::reference
 
using const_reference = const_iterator::reference
 
using value_type = std::conditional_t< is_const(), const_iterator::value_type, iterator::value_type >
 

Public Member Functions

 BasicMultiBuf (const BasicMultiBuf &)=delete
 
template<Property... kOtherProperties>
 BasicMultiBuf (const BasicMultiBuf< kOtherProperties... > &)=delete
 
BasicMultiBufoperator= (const BasicMultiBuf &)=delete
 
template<Property... kOtherProperties>
BasicMultiBufoperator= (const BasicMultiBuf< kOtherProperties... > &)=delete
 
 BasicMultiBuf (BasicMultiBuf &&)=delete
 
template<Property... kOtherProperties>
 BasicMultiBuf (BasicMultiBuf< kOtherProperties... > &&)=delete
 
BasicMultiBufoperator= (BasicMultiBuf &&)=delete
 
template<Property... kOtherProperties>
BasicMultiBufoperator= (BasicMultiBuf< kOtherProperties... > &&)=delete
 
template<typename OtherMultiBuf >
OtherMultiBuf & as ()
 
template<typename OtherMultiBuf >
const OtherMultiBuf & as () const
 
template<typename OtherMultiBuf , typename = internal::EnableIfConvertible<BasicMultiBuf, OtherMultiBuf>>
 operator OtherMultiBuf & ()
 
template<typename OtherMultiBuf , typename = internal::EnableIfConvertible<BasicMultiBuf, OtherMultiBuf>>
 operator const OtherMultiBuf & () const
 
constexpr bool empty () const
 
constexpr size_t size () const
 
bool IsCompatible (const BasicMultiBuf &mb) const
 
bool TryReserveChunks (size_type num_chunks)
 
template<Property... kOtherProperties>
bool TryReserveForInsert (const_iterator pos, const BasicMultiBuf< kOtherProperties... > &mb)
 
template<int &... kExplicitGuard, typename T , typename = std::enable_if_t<std::is_constructible_v<ConstByteSpan, T>, int>>
bool TryReserveForInsert (const_iterator pos, const T &bytes)
 
template<Property... kOtherProperties>
void Insert (const_iterator pos, BasicMultiBuf< kOtherProperties... > &&mb)
 
template<int &... kExplicitGuard, typename T , typename = std::enable_if_t<std::is_constructible_v<ConstByteSpan, T>, int>>
void Insert (const_iterator pos, const T &bytes)
 
template<Property... kOtherProperties>
bool TryReserveForPushBack (const BasicMultiBuf< kOtherProperties... > &mb)
 
template<int &... kExplicitGuard, typename T , typename = std::enable_if_t<std::is_constructible_v<ConstByteSpan, T>, int>>
bool TryReserveForPushBack (const T &bytes)
 
template<Property... kOtherProperties>
void PushBack (BasicMultiBuf< kOtherProperties... > &&mb)
 
template<int &... kExplicitGuard, typename T , typename = std::enable_if_t<std::is_constructible_v<ConstByteSpan, T>, int>>
void PushBack (const T &bytes)
 
bool IsRemovable (const_iterator pos, size_t size) const
 
Result< Instance< BasicMultiBuf > > Remove (const_iterator pos, size_t size)
 
Result< Instance< BasicMultiBuf > > PopFrontFragment ()
 
Result< const_iterator > Discard (const_iterator pos, size_t size)
 
bool IsReleasable (const_iterator pos) const
 
UniquePtr< value_type[]> Release (const_iterator pos)
 
bool IsShareable (const_iterator pos) const
 
SharedPtr< value_type[]> Share (const_iterator pos)
 
size_t CopyTo (ByteSpan dst, size_t offset=0) const
 
size_t CopyFrom (ConstByteSpan src, size_t offset=0)
 
ConstByteSpan Get (ByteSpan copy, size_t offset=0) const
 
template<int &... kExplicitGuard, typename Visitor >
auto Visit (Visitor visitor, ByteSpan copy, size_t offset)
 
void Clear ()
 
constexpr Observerobserver () const
 
void set_observer (Observer *observer)
 
size_type NumFragments () const
 
constexpr size_type NumLayers () const
 
bool AddLayer (size_t offset, size_t length=dynamic_extent)
 
void SealTopLayer ()
 
void UnsealTopLayer ()
 
bool ResizeTopLayer (size_t offset, size_t length=dynamic_extent)
 
bool PopLayer ()
 
at

Returns a reference to the byte at specified index.

Warning
Do not use addresses of returned references for ranges! The underlying memory is not guaranteed to be contiguous, so statements such as std::memcpy(data.bytes(), &multibuf[0], data.size()) may corrupt memory.

Use CopyTo or Get to read ranges of bytes.

template<bool kMutable = !is_const()>
std::enable_if_t< kMutable, reference > at (size_t index)
 
const_reference at (size_t index) const
 
template<bool kMutable = !is_const()>
std::enable_if_t< kMutable, reference > operator[] (size_t index)
 
const_reference operator[] (size_t index) const
 
Chunks

Returns a chunk-iterable view of the MultiBuf.

This can be used in a range-based for-loop, e.g.

for (ConstByteSpan chunk : multibuf.ConstChunks()) {
Read(chunk);
}
template<bool kMutable = !is_const()>
constexpr std::enable_if_t< kMutable, ChunksType > Chunks ()
 
ConstChunksType Chunks () const
 
ConstChunksType ConstChunks () const
 
begin

Returns an iterator to the start of the MultiBuf's bytes.

Warning
Iterator-based algorithms such as std::copy may perform worse than expected due to overhead of advancing iterators across multiple, potentially noncontiguous memory regions.

Use CopyTo or Get, or Visit to read ranges of bytes.

template<bool kMutable = !is_const()>
constexpr std::enable_if_t< kMutable, iterator > begin ()
 
constexpr const_iterator begin () const
 
constexpr const_iterator cbegin () const
 
end

Returns an iterator past the end of the MultiBuf's bytes.

Warning
Iterator-based algorithms such as std::copy may perform worse than expected due to overhead of advancing iterators across multiple, potentially noncontiguous memory regions.

Use CopyTo or Get to read ranges of bytes.

template<bool kMutable = !is_const()>
constexpr std::enable_if_t< kMutable, iterator > end ()
 
constexpr const_iterator end () const
 
constexpr const_iterator cend () const
 
IsCompatible

Returns whether the shared memory can be added to this object.

To be compatible, the shared pointer must be the first shared pointer added to the object, or match the shared pointer previously added.

Parameters
bytesShared memory to check for compatibility.
bool IsCompatible (const UniquePtr< std::byte[]> &bytes) const
 
bool IsCompatible (const UniquePtr< const std::byte[]> &bytes) const
 
bool IsCompatible (const SharedPtr< std::byte[]> &bytes) const
 
bool IsCompatible (const SharedPtr< const std::byte[]> &bytes) const
 
TryReserveForInsert

Attempts to modify this object to be able to accept the given shared memory, and returns whether successful.

It is an error to call this method with an invalid iterator or incompatible MultiBuf, if applicable.

If unable to allocate space for the metadata, returns false and leaves the object unchanged. Otherwise, returns true.

Parameters
posLocation to insert memory within the MultiBuf.
bytesShared memory to be inserted.
bool TryReserveForInsert (const_iterator pos, const UniquePtr< std::byte[]> &bytes)
 
bool TryReserveForInsert (const_iterator pos, const UniquePtr< const std::byte[]> &bytes)
 
bool TryReserveForInsert (const_iterator pos, const SharedPtr< std::byte[]> &bytes)
 
bool TryReserveForInsert (const_iterator pos, const SharedPtr< const std::byte[]> &bytes)
 
Insert

Insert memory before the given iterator.

It is a fatal error if this method cannot allocate space for necessary metadata. See also TryReserveForInsert, which can be used to try to pre-allocate the needed space without crashing.

Parameters
posLocation to insert memory within the MultiBuf.
bytesShared memory to be inserted.
offsetUsed to denote a subspan of bytes.
lengthUsed to denote a subspan of bytes.
void Insert (const_iterator pos, UniquePtr< std::byte[]> &&bytes)
 
void Insert (const_iterator pos, UniquePtr< const std::byte[]> &&bytes)
 
void Insert (const_iterator pos, UniquePtr< std::byte[]> &&bytes, size_t offset, size_t length=dynamic_extent)
 
void Insert (const_iterator pos, UniquePtr< const std::byte[]> &&bytes, size_t offset, size_t length=dynamic_extent)
 
void Insert (const_iterator pos, const SharedPtr< std::byte[]> &bytes)
 
void Insert (const_iterator pos, const SharedPtr< const std::byte[]> &bytes)
 
void Insert (const_iterator pos, const SharedPtr< std::byte[]> &bytes, size_t offset, size_t length=dynamic_extent)
 
void Insert (const_iterator pos, const SharedPtr< const std::byte[]> &bytes, size_t offset, size_t length=dynamic_extent)
 
TryReserveForPushBack

Attempts to modify this object to be able to move the given shared memory to the end of this object.

If unable to allocate space for the metadata, returns false and leaves the object unchanged. Otherwise, returns true.

Parameters
bytesShared memory to be inserted.
bool TryReserveForPushBack (const UniquePtr< std::byte[]> &bytes)
 
bool TryReserveForPushBack (const UniquePtr< const std::byte[]> &bytes)
 
bool TryReserveForPushBack (const SharedPtr< std::byte[]> &bytes)
 
bool TryReserveForPushBack (const SharedPtr< const std::byte[]> &bytes)
 
PushBack

Moves memory to the end of this object.

It is a fatal error if this method cannot allocate space for necessary metadata. See also TryReserveForPushBack, which can be used to try to pre-allocate the needed space without crashing.

Parameters
bytesShared memory to be inserted.
offsetUsed to denote a subspan of bytes.
lengthUsed to denote a subspan of bytes.
void PushBack (UniquePtr< std::byte[]> &&bytes)
 
void PushBack (UniquePtr< const std::byte[]> &&bytes)
 
void PushBack (UniquePtr< std::byte[]> &&bytes, size_t offset, size_t length=dynamic_extent)
 
void PushBack (UniquePtr< const std::byte[]> &&bytes, size_t offset, size_t length=dynamic_extent)
 
void PushBack (const SharedPtr< std::byte[]> &bytes)
 
void PushBack (const SharedPtr< const std::byte[]> &bytes)
 
void PushBack (const SharedPtr< std::byte[]> &bytes, size_t offset, size_t length=dynamic_extent)
 
void PushBack (const SharedPtr< const std::byte[]> &bytes, size_t offset, size_t length=dynamic_extent)
 

Static Public Member Functions

static constexpr bool is_const ()
 Returns whether the MultiBuf data is immutable.
 
static constexpr bool is_layerable ()
 Returns whether additional views can be layered on the MultiBuf.
 
static constexpr bool is_observable ()
 Returns whether an observer can be registered on the MultiBuf.
 

Protected Types

using Deque = DynamicDeque< internal::Entry >
 
using ChunksType = internal::Chunks< typename Deque::size_type >
 
using ConstChunksType = internal::ConstChunks< typename Deque::size_type >
 
using GenericMultiBuf = internal::GenericMultiBuf
 

Detailed Description

template<Property... kProperties>
class pw::multibuf::BasicMultiBuf< kProperties >

Logical byte sequence representing a sequence of memory buffers.

MultiBufs have been designed with network data processing in mind. They facilitate assembling and disassembling multiple buffers to and from a single sequence. This class refers to these individual spans of bytes as Chunks.

Small amounts of this data, such as protocol headers, can be accessed using methods such as Get, Visit, and the byte iterators. These methods avoid copying unless strictly necessary, such as when operating over chunks that are not contiguous in memory.

Larger amounts of data, such as application data, can be accessed using methods such as CopyFrom, CopyTo, and the chunk iterators.

MultiBufs are defined with zero or more properties which add or constrain additional behavior:

Type aliases are provided for standard combinations of these properties.

A MultiBuf may be converted to another with different properties using the as method, provided those properties are compatible. This allows writing method and function signatures that only specify the necessary behavior. For example:

extern void AdjustLayers(LayerableMultiBuf& mb);
MyMultiBufInstance mb = InitMyMultiBufInstance();
AdjustLayers(mb.as<LayerableMultiBuf>());

In order to provide for such conversions, this class only represents the interface of a particular MultiBuf type, and not its instantiation. To create a concrete instantiation of BasicMultiBuf<kProperties>, use Instance<BasicMultiBuf<kProperties>, as described below.

MultiBufs are designed to be built either "bottom-up" or "top-down":

The "bottom-up" approach also provides the concept of message "fragments". Whenever a layer is added, a MultiBuf considers the new top layer to be a "fragment". These boundaries are preserved when appending additional data, and can be used to break the MultiBuf back up into lower-level messages when writing data to the network.

For example, consider a TCP/IP example. You could use a "bottom-up", layerable MultiBuf to access and manipulate TCP data. In the following:

Layer 3: +----+ TCP 0 +----+ TCP 0 +----+ TCP 0 +----+ TCP 1 +----+ TCP 1 +
Layer 2: +--+ IP 0.0 +--+ IP 0.1 +--+ IP 0.2 +--+ IP 1.0 +--+ IP 1.1 +
Layer 1: + Ethernet 0 + Ethernet 1 + Ethernet 2 + Ethernet 3 + Ethernet 4 +
+ 0x5CAFE000 + 0x5CAFE400 + 0x5CAFE800 + 0x5CAFEC00 + 0x5CAFF000 +

Alterantively, you could use a "top-down", unlayered MultiBuf to represent same. The following might be the result of adding statically owned headers and footers to a portion of the application data:

No layer: + Eth header + IP header + TCP header + App data + Eth footer +
+ 0x5AAA0000 + 0x5AAA0020 + 0x5AAA0050 + 0x5CAFEC00 + 0x5AAA0040 +
Template Parameters
kPropertiesZero or more Property values. These must not be duplicated, and must appear in the order specified by that type.

Member Function Documentation

◆ AddLayer()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::AddLayer ( size_t  offset,
size_t  length = dynamic_extent 
)
inline

Adds a layer.

Each layer provides a span-like view of memory. An empty MultiBuf has no layers, while a non-empty MultiBuf has at least one. Additional layers provide a subspan-like view of the layer beneath it. This is useful in representing nested protocols, where the payloads of one level make up the messages of the next level.

This will modify the apparent byte sequence to be a view of the previous top layer.

The range given by offset and length MUST fall within this MultiBuf.

If unable to allocate space for the metadata, returns false and leaves the object unchanged. Otherwise, returns true.

Parameters
[in]offsetOffset from the start of the previous top layer for the new top layer.
[in]lengthLength of the new top layer.

◆ Clear()

template<Property... kProperties>
void pw::multibuf::BasicMultiBuf< kProperties >::Clear ( )
inline

Releases all memory from this object.

If this object has a deallocator, it will be used to free the memory owned by this object. When this method returns, the MultiBuf will be restored to an initial, empty state.

◆ CopyFrom()

template<Property... kProperties>
size_t pw::multibuf::BasicMultiBuf< kProperties >::CopyFrom ( ConstByteSpan  src,
size_t  offset = 0 
)
inline

Writes data from src to the MultiBuf at the given offset.

Parameters
srcSpan to copy data from. Its length determines the maximum number of bytes that may be copied.
offsetOffset from the start of the MultiBuf to start copying to.
Returns
The number of bytes copied.

◆ CopyTo()

template<Property... kProperties>
size_t pw::multibuf::BasicMultiBuf< kProperties >::CopyTo ( ByteSpan  dst,
size_t  offset = 0 
) const
inline

Writes data from the MultiBuf at the given offset to dst.

Parameters
dstSpan to copy data to. Its length determines the maximum number of bytes that may be copied.
offsetOffset from the start of the MultiBuf to start copying from.
Returns
The number of bytes copied.

◆ Discard()

template<Property... kProperties>
Result< const_iterator > pw::multibuf::BasicMultiBuf< kProperties >::Discard ( const_iterator  pos,
size_t  size 
)
inline

Removes if a range of bytes from this object.

The range given by pos and size MUST fall within this MultiBuf.

This method may fail if space for additional metadata is needed but cannot be allocated.

On successful completion, this method will return a valid iterator pointing to the memory following that which was discarded.

On failure, the original MultiBuf is unmodified.

"Owned" chunks, i.e. those added using a UniquePtr, which are fully discarded as a result of this call will be deallocated.

Parameters
posLocation from which to discard memory from the MultiBuf.
sizeAmount of memory to discard.
Returns
embed:rst:leading-asterisk
 
* 
*  .. pw-status-codes::
* 
*     OK:                  The memory range has been discarded.
* 
*     RESOURCE_EXHAUSTED:  Failed to allocate memory for the new MultiBuf's
*                          metadata.
*  

◆ empty()

template<Property... kProperties>
constexpr bool pw::multibuf::BasicMultiBuf< kProperties >::empty ( ) const
inlineconstexpr

Returns whether the MultiBuf is empty, i.e. whether it has no chunks or fragments.

◆ Get()

template<Property... kProperties>
ConstByteSpan pw::multibuf::BasicMultiBuf< kProperties >::Get ( ByteSpan  copy,
size_t  offset = 0 
) const
inline

Returns a byte span containing data at the given offset.

If the data is contiguous, a view to it is returned directly. Otherwise, it is copied from the non-contiguous buffers into the provided span, which is then returned.

As a result, this method should only be used on small regions of data, e.g. packet headers.

Parameters
copyA buffer that may be used to hold data if the requested region is non-contiguous. Its length determines the maximum number of bytes that may be copied.
offsetOffset from the start of the MultiBuf to start copying from.
Returns
A span of bytes for the requested range.

◆ Insert() [1/2]

template<Property... kProperties>
template<Property... kOtherProperties>
void pw::multibuf::BasicMultiBuf< kProperties >::Insert ( const_iterator  pos,
BasicMultiBuf< kOtherProperties... > &&  mb 
)

Insert memory before the given iterator.

It is a fatal error if this method cannot allocate space for necessary metadata. See also TryReserveForInsert, which can be used to try to pre-allocate the needed space without crashing.

Parameters
posLocation to insert memory within the MultiBuf.
mbMultiBuf to be inserted.

◆ Insert() [2/2]

template<Property... kProperties>
template<int &... kExplicitGuard, typename T , typename >
void pw::multibuf::BasicMultiBuf< kProperties >::Insert ( const_iterator  pos,
const T &  bytes 
)

Insert memory before the given iterator.

It is a fatal error if this method cannot allocate space for necessary metadata. See also TryReserveForInsert, which can be used to try to pre-allocate the needed space without crashing.

Parameters
posLocation to insert memory within the MultiBuf.
bytesUnowned memory to be inserted.

◆ IsCompatible()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::IsCompatible ( const BasicMultiBuf< kProperties > &  mb) const
inline

Returns whether the MultiBuf can be added to this object.

To be compatible, the memory for each of incoming MultiBuf's chunks must be one of the following:

  • Externally managed, i.e. "unowned".
  • Deallocatable by the same deallocator as other chunks, if any.
  • Part of the same shared memory allocation as any other shared chunks.
Parameters
mbMultiBuf to check for compatibility.

◆ IsReleasable()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::IsReleasable ( const_iterator  pos) const
inline

Returns whether the given iterator refers to a location within an "owned" chunk, that is, memory that was added as a UniquePtr.

Parameters
posLocation within the MultiBuf of the memory to release.

◆ IsRemovable()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::IsRemovable ( const_iterator  pos,
size_t  size 
) const
inline

Returns whether the given range can be removed.

A range may not be valid to Remove if it does not fall within the MultiBuf, or if it splits "owned" chunks. Owned chunks are those added using a UniquePtr. Splitting them between different MultiBufs would result in conflicting ownership, and is therefore disallowed.

Parameters
posLocation from which to remove memory from the MultiBuf.
sizeAmount of memory to remove.

◆ IsShareable()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::IsShareable ( const_iterator  pos) const
inline

Returns whether the given iterator refers to a location within a "shared" chunk, that is, memory that was added as a SharedPtr.

Parameters
posLocation within the MultiBuf of the memory to share.

◆ NumFragments()

template<Property... kProperties>
size_type pw::multibuf::BasicMultiBuf< kProperties >::NumFragments ( ) const
inline

Returns the number of fragments in the top layer.

Whenever a new layer is added, its boundary is marked and it is treated as a single fragment of a larger message or packet. These boundaries markers are preserved by Insert and PushBack. They can be used to delineate how much memory to return when PopFront is called.

◆ NumLayers()

template<Property... kProperties>
constexpr size_type pw::multibuf::BasicMultiBuf< kProperties >::NumLayers ( ) const
inlineconstexpr

Returns the number layers in the MultiBuf.

This will always be at least 1.

◆ observer()

template<Property... kProperties>
constexpr Observer * pw::multibuf::BasicMultiBuf< kProperties >::observer ( ) const
inlineconstexpr

Returns the observer for this MultiBuf, or null if none has been set.

Observers are notified whenever fragments or layers are added or removed from the MultiBuf.

◆ PopFrontFragment()

template<Property... kProperties>
Result< Instance< BasicMultiBuf< kProperties... > > > pw::multibuf::BasicMultiBuf< kProperties >::PopFrontFragment

Removes the first fragment from this object and returns it.

Without any layers, each chunk is a fragment. Layered MultiBufs may group multiple chunks into a single fragment.

It is an error to call this method when the MultiBuf is empty.

Returns
embed:rst:leading-asterisk
 
* 
*  .. pw-status-codes::
* 
*     OK:                  Returns the fragment in a new MultiBuf.
* 
*     RESOURCE_EXHAUSTED:  Attempting to reserve space for the new MultiBuf
*                          failed.
* 
*  

◆ PopLayer()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::PopLayer ( )
inline

Removes the top layer.

After this call, the layer beneath the top layer will be the new top layer.

It is an error to call this method when NumLayers() < 2.

Returns false and leaves the object unmodified if the top layer is sealed; otherwise returns true.

◆ PushBack() [1/2]

template<Property... kProperties>
template<Property... kOtherProperties>
void pw::multibuf::BasicMultiBuf< kProperties >::PushBack ( BasicMultiBuf< kOtherProperties... > &&  mb)

Moves bytes to the end of this object.

It is a fatal error if this method cannot allocate space for necessary metadata. See also TryReserveForPushBack, which can be used to try to pre-allocate the needed space without crashing.

Parameters
mbMultiBuf to be inserted.

◆ PushBack() [2/2]

template<Property... kProperties>
template<int &... kExplicitGuard, typename T , typename >
void pw::multibuf::BasicMultiBuf< kProperties >::PushBack ( const T &  bytes)

Moves memory to the end of this object.

It is a fatal error if this method cannot allocate space for necessary metadata. See also TryReserveForPushBack, which can be used to try to pre-allocate the needed space without crashing.

Parameters
bytesUnowned memory to be inserted.

◆ Release()

template<Property... kProperties>
UniquePtr< typename BasicMultiBuf< kProperties... >::value_type[]> pw::multibuf::BasicMultiBuf< kProperties >::Release ( const_iterator  pos)

Removes a memory allocation from this object and releases ownership of it.

The location given by pos and MUST be releasable, as described by IsReleasable: It MUST fall within an "owned" chunk.

This method returns a UniquePtr which owns the removed memory.

The entire owned chunk containing the location indicated by the iterator will be removed and returned. An iterator to the middle of an owned chunk will result in some bytes before the iterator being removed.

Parameters
posLocation within the MultiBuf of the memory to release.

◆ Remove()

template<Property... kProperties>
Result< Instance< BasicMultiBuf< kProperties... > > > pw::multibuf::BasicMultiBuf< kProperties >::Remove ( const_iterator  pos,
size_t  size 
)

Removes if a range of bytes from this object.

The range given by pos and size MUST be removable, as described by IsRemovable: It MUST fall within this MultiBuf, and not split "owned" chunks.

This method may fail if unable to allocate metadata for a new MultiBuf.

On successful completion, this method will return a MultiBuf populated with entries corresponding to the removed memory range.

On failure, the original MultiBuf is unmodified.

Parameters
posLocation from which to remove memory from the MultiBuf.
sizeAmount of memory to remove.
Returns
embed:rst:leading-asterisk
 
* 
*  .. pw-status-codes::
* 
*     OK:                  The returned MultiBuf contains the removed chunks.
* 
*     RESOURCE_EXHAUSTED:  Failed to allocate memory for the new MultiBuf's
*                          metadata.
*  

◆ ResizeTopLayer()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::ResizeTopLayer ( size_t  offset,
size_t  length = dynamic_extent 
)
inline

Resizes the current top layer.

The range given by offset and length MUST fall within this MultiBuf. It is an error to call this method when NumLayers() < 2.

Returns false and leaves the object unmodified if the top layer is sealed; otherwise returns true.

Parameters
[in]offsetNew offset from the start of layer beneath the top layer.
[in]lengthNew length of the top layer.

◆ SealTopLayer()

template<Property... kProperties>
void pw::multibuf::BasicMultiBuf< kProperties >::SealTopLayer ( )
inline

Marks the top layer as "sealed", preventing it from being resized or popped.

◆ set_observer()

template<Property... kProperties>
void pw::multibuf::BasicMultiBuf< kProperties >::set_observer ( Observer observer)
inline

Sets the observer for this MultiBuf.

Passing null effectively clears the observer from the MultiBuf.

Observers are notified whenever fragments or layers are added or removed from the MultiBuf.

◆ Share()

template<Property... kProperties>
SharedPtr< typename BasicMultiBuf< kProperties... >::value_type[]> pw::multibuf::BasicMultiBuf< kProperties >::Share ( const_iterator  pos)

Returns the shared memory at the given location.

The location given by pos and MUST be shareable, as described by IsShareable: It MUST fall within a "shared" chunk.

This method returns a SharedPtr which shares ownership of the indicated memory. the memory will not be freed until all shared pointers to it go out of scope.

The returned pointer will reference the entire shared chunk containing the location indicated by the iterator. The shared pointer for an iterator to the middle of a shared chunk will include some bytes before the iterator.

Parameters
posLocation within the MultiBuf of the memory to share.

◆ size()

template<Property... kProperties>
constexpr size_t pw::multibuf::BasicMultiBuf< kProperties >::size ( ) const
inlineconstexpr

Returns the size of a MultiBuf in bytes, which is the sum of the lengths of the views that make up its topmost layer.

◆ TryReserveChunks()

template<Property... kProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::TryReserveChunks ( size_type  num_chunks)
inline

Attempts to reserves memory to hold metadata for the given number of total chunks.

Returns
embed:rst:leading-asterisk
 
* 
*  .. pw-status-codes::
* 
*     OK:                  The object has space for the chunks.
* 
*     RESOURCE_EXHAUSTED:  Out of memory; cannot add the chunks.
* 
*  

◆ TryReserveForInsert() [1/2]

template<Property... kProperties>
template<Property... kOtherProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::TryReserveForInsert ( const_iterator  pos,
const BasicMultiBuf< kOtherProperties... > &  mb 
)

Attempts to modify this object to be able to insert the given MultiBuf, and returns whether successful.

It is an error to call this method with an invalid iterator or incompatible MultiBuf, if applicable.

If unable to allocate space for the metadata, returns false and leaves the object unchanged. Otherwise, returns true.

Parameters
posLocation to insert memory within the MultiBuf.
mbMultiBuf to be inserted.

◆ TryReserveForInsert() [2/2]

template<Property... kProperties>
template<int &... kExplicitGuard, typename T , typename >
bool pw::multibuf::BasicMultiBuf< kProperties >::TryReserveForInsert ( const_iterator  pos,
const T &  bytes 
)

Attempts to modify this object to be able to accept the given unowned memory, and returns whether successful.

It is an error to call this method with an invalid iterator or incompatible MultiBuf, if applicable.

If unable to allocate space for the metadata, returns false and leaves the object unchanged. Otherwise, returns true.

Parameters
posLocation to insert memory within the MultiBuf.
bytesUnowned memory to be inserted.

◆ TryReserveForPushBack() [1/2]

template<Property... kProperties>
template<Property... kOtherProperties>
bool pw::multibuf::BasicMultiBuf< kProperties >::TryReserveForPushBack ( const BasicMultiBuf< kOtherProperties... > &  mb)

Attempts to modify this object to be able to move the given MultiBuf to the end of this object.

If unable to allocate space for the metadata, returns false and leaves the object unchanged. Otherwise, returns true.

Parameters
mbMultiBuf to be inserted.

◆ TryReserveForPushBack() [2/2]

template<Property... kProperties>
template<int &... kExplicitGuard, typename T , typename >
bool pw::multibuf::BasicMultiBuf< kProperties >::TryReserveForPushBack ( const T &  bytes)

Attempts to modify this object to be able to move the given unowned memory to the end of this object.

If unable to allocate space for the metadata, returns false and leaves the object unchanged. Otherwise, returns true.

Parameters
bytesUnowned memory to be inserted.

◆ UnsealTopLayer()

template<Property... kProperties>
void pw::multibuf::BasicMultiBuf< kProperties >::UnsealTopLayer ( )
inline

Clears the "sealed" flag from the top layer, allowing it to be resized or popped.

◆ Visit()

template<Property... kProperties>
template<int &... kExplicitGuard, typename Visitor >
auto pw::multibuf::BasicMultiBuf< kProperties >::Visit ( Visitor  visitor,
ByteSpan  copy,
size_t  offset 
)
inline

Passes a byte span containing data at the given offset to a visitor.

If the data is contiguous, the visitor is called on it directly. Otherwise, data is copied from the non-contiguous buffers into the provided span, which is then passed to visitor.

Parameters
visitorA callable object, such as a function pointer or lambda, that can be called on a ConstByteSpan.
copyA buffer that may be used to hold data if the requested region is non-contiguous. Its length determines the maximum number of bytes that may be copied.
offsetOffset from the start of the MultiBuf to start copying from.
Returns
The result of calling visitor on the requested range.

The documentation for this class was generated from the following files: