Sane C++ Libraries
C++ Platform Abstraction Libraries
SC::Buffer Struct Reference

An heap allocated byte buffer that can optionally use an inline buffer. More...

#include <Buffer.h>

Inheritance diagram for SC::Buffer:
SC::Segment< SegmentBuffer > SC::SmallBuffer< N >

Public Member Functions

 Segment ()
 
 Segment (Segment &&other)
 
 Segment (const Segment &other)
 
template<typename U >
 Segment (Span< const U > span)
 
 Segment (Span< const T > span)
 
 Segment (std::initializer_list< T > list)
 
 Segment (SegmentHeader &inlineHeader, uint32_t capacityInBytes)
 Builds a Segment with an inlineHeader of given capacity in bytes. More...
 
- Public Member Functions inherited from SC::Segment< SegmentBuffer >
 Segment (Segment &&other)
 
 Segment (const Segment &other)
 
 Segment (Span< const U > span)
 
 Segment (Span< const T > span)
 
 Segment (std::initializer_list< T > list)
 
 Segment (SegmentHeader &inlineHeader, uint32_t capacityInBytes)
 Builds a Segment with an inlineHeader of given capacity in bytes. More...
 
Segmentoperator= (Segment &&other)
 
Segmentoperator= (const Segment &other)
 
bool resizeWithoutInitializing (size_t newSize)
 Re-allocates to the requested new size, preserving its contents. More...
 
bool resize (size_t newSize, const T &value=T())
 Re-allocates to the requested new size, preserving its contents and setting new items to value. More...
 
bool reserve (size_t newCapacity)
 Reserves capacity to avoid heap-allocation during a future append, assign or resize. More...
 
bool append (Span< const T > span)
 Appends a Span to the end of the segment. More...
 
bool append (Span< const U > span)
 Appends a Span of items convertible to T to the end of the segment. More...
 
bool appendMove (Segment &&other)
 Moves contents of another segment to the end of this segment. More...
 
bool shrink_to_fit ()
 Ensures capacity == size re-allocating (if capacity>size) or freeing ( if size==0) memory. More...
 
void clear ()
 Sets size to zero without freeing any memory (use shrink_to_fit() to free memory) More...
 
bool assign (Span< const T > span)
 Replaces contents with contents of the span. More...
 
bool assignMove (Segment &&other)
 Replaces content moving (possibly "stealing") content of another segment. More...
 
bool push_back (const T &value)
 Appends a single element to the end of the segment. More...
 
bool push_back (T &&value)
 Moves a single element to the end of the segment. More...
 
bool push_front (const T &value)
 Appends a single element to the start of the segment. More...
 
bool pop_back (T *removedValue=nullptr)
 Removes the last element of the segment. More...
 
bool pop_front (T *removedValue=nullptr)
 Removes the first element of the segment. More...
 
const T * data () const SC_LANGUAGE_LIFETIME_BOUND
 Access data owned by the segment or nullptr if segment is empty. More...
 
T * data () SC_LANGUAGE_LIFETIME_BOUND
 Access data owned by the segment or nullptr if segment is empty. More...
 
T * begin () SC_LANGUAGE_LIFETIME_BOUND
 
const T * begin () const SC_LANGUAGE_LIFETIME_BOUND
 
T * end () SC_LANGUAGE_LIFETIME_BOUND
 
const T * end () const SC_LANGUAGE_LIFETIME_BOUND
 
T & back () SC_LANGUAGE_LIFETIME_BOUND
 
const T & back () const SC_LANGUAGE_LIFETIME_BOUND
 
T & front () SC_LANGUAGE_LIFETIME_BOUND
 
const T & front () const SC_LANGUAGE_LIFETIME_BOUND
 
T & operator[] (size_t idx) SC_LANGUAGE_LIFETIME_BOUND
 
const T & operator[] (size_t idx) const SC_LANGUAGE_LIFETIME_BOUND
 
bool isInlineBuffer () const
 Returns true if an inline buffer is in use (false if segment is heap allocated). More...
 
bool isEmpty () const
 Check if is empty (size() == 0) More...
 
Span< T > toSpan () SC_LANGUAGE_LIFETIME_BOUND
 Obtains a Span of internal contents. More...
 
Span< const T > toSpanConst () const SC_LANGUAGE_LIFETIME_BOUND
 Obtains a Span of internal contents. More...
 
size_t size () const
 Returns current size. More...
 
size_t capacity ()
 Returns current capacity (always >= of size()) More...
 
bool removeRange (size_t start, size_t length)
 Removes the range [start, start + length] from the segment. More...
 
bool removeAt (size_t index)
 Removes the element at index. More...
 
bool insert (size_t index, Span< const T > data)
 Insert a span at the given index. More...
 
void unsafeSetHeader (SegmentHeader *newHeader)
 Sets the internal header handled by this class. More...
 
SegmentHeaderunsafeGetHeader () const
 Get the internal header handled by this class. More...
 

Additional Inherited Members

- Public Types inherited from SC::Segment< SegmentBuffer >
using T = typename VTable::Type
 
- Protected Attributes inherited from SC::Segment< SegmentBuffer >
SegmentHeaderheader
 

Detailed Description

An heap allocated byte buffer that can optionally use an inline buffer.

See also
SC::SmallBuffer to use an inline buffer that can optionally become heap allocated as needed.
Note
This class (and SC::SmallBuffer) reduces needs for the header-only SC::Vector (from Containers). SC::Buffer avoids some compile time / executable size bloat because it's not header only.

Example:

bool funcRequiringBuffer(Buffer& buffer)
{
for (size_t idx = 0; idx < buffer.size(); ++idx)
{
if (buffer[idx] != 123)
return false;
}
return true;
}
void BufferTest::basic()
{
Buffer buffer;
// Allocate 16 bytes
SC_TEST_EXPECT(buffer.resizeWithoutInitializing(16));
// Buffer is not inline (it's heap allocated)
SC_TEST_EXPECT(not buffer.isInlineBuffer());
// Fill buffer with a value
buffer.clear();
SC_TEST_EXPECT(buffer.resize(buffer.capacity(), 123));
funcRequiringBuffer(buffer);
// Declare a buffer with inline capacity of 128 bytes
SmallBuffer<128> smallBuffer;
// copy buffer (will not allocate)
smallBuffer = buffer;
// smallBuffer is using inline buffer (no heap allocation)
SC_TEST_EXPECT(smallBuffer.isInlineBuffer());
SC_TEST_EXPECT(smallBuffer.size() == 16);
SC_TEST_EXPECT(smallBuffer.capacity() == 128);
// SmallBuffer can be passed in place of regular Buffer
funcRequiringBuffer(smallBuffer);
SC_TEST_EXPECT(buffer.resizeWithoutInitializing(1024));
// SmallBuffer now will allocate 1024 bytes
// by using assignCopy instead of assignment operator
// caller can check for allocation failure
SC_TEST_EXPECT(smallBuffer.assign(buffer.toSpanConst()));
SC_TEST_EXPECT(not smallBuffer.isInlineBuffer());
SC_TEST_EXPECT(smallBuffer.size() == 1024);
SC_TEST_EXPECT(smallBuffer.capacity() == 1024);
// Allocate 2kb on another buffer
Buffer buffer2;
SC_TEST_EXPECT(buffer2.resizeWithoutInitializing(2048));
// SmallBuffer will "steal" the 2Kb buffer
smallBuffer = move(buffer2);
SC_TEST_EXPECT(smallBuffer.size() == 2048);
SC_TEST_EXPECT(smallBuffer.capacity() == 2048);
SC_TEST_EXPECT(buffer2.isEmpty());
// Resize small buffer to its original capacity
SC_TEST_EXPECT(smallBuffer.resizeWithoutInitializing(128));
// The heap block is still in use
SC_TEST_EXPECT(not smallBuffer.isInlineBuffer());
SC_TEST_EXPECT(smallBuffer.capacity() == 2048);
// Shrinking it will restore its original inline buffer
SC_TEST_EXPECT(smallBuffer.shrink_to_fit());
// And verify that that's actually true
SC_TEST_EXPECT(smallBuffer.isInlineBuffer());
SC_TEST_EXPECT(smallBuffer.capacity() == 128);
}
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition: Compiler.h:269
#define SC_TEST_EXPECT(e)
Records a test expectation (eventually aborting or breaking o n failed test)
Definition: Testing.h:113

Member Function Documentation

◆ Segment()

SC::Segment< VTable >::Segment ( SegmentHeader inlineHeader,
uint32_t  capacityInBytes 
)

Builds a Segment with an inlineHeader of given capacity in bytes.


The documentation for this struct was generated from the following file: