omni::extras::ScratchBuffer

Defined in omni/extras/ScratchBuffer.h

template<typename T, size_t BaseSize_ = 16, size_t ShrinkThreshold_ = 100>
class ScratchBuffer

A templated helper class to provide a simple resizable scratch buffer.

The buffer will only perform a dynamic allocation if the requested size requires it. If only a small size is needed, a stack buffer will be used instead. The intended usage pattern is to create the object, set its required size, then write to each item in the array as needed. The buffer will not be initialized unless the contained type is a class that constructs itself. It is left up to the caller to initialize the buffer’s contents in all other cases.

The buffer will always occupy enough stack space to hold the larger of 512 bytes worth of the contained type, or 16 items of the contained type. If the size is set beyond that limit, a new buffer will be allocated from the heap. There is no tracking of how many items have been written to the buffer - that is left as an exercise for the caller.

Thread Safety

There are no thread safety protections on this class. This is intended to be used as a local scratch buffer. If potential concurrent access is required, it is the caller’s responsibility to protect access to this object.

Template Parameters
  • T – The data type that will be contained in the scratch buffer. This can be any primitive, struct, or class type.

  • BaseSize_ – The number of items of type T that can be held in the scratch buffer’s stack array without needing to allocate from the heap. By default, this is guaranteed to be at least 16 items.

  • ShrinkThreshold_ – The threshold expressed as a percentage of the buffer’s previous size below which the buffer itself will be shrunken on a resize operation that makes it smaller. If the new size of the buffer expressed as a percentage of the old size is larger than this number, the previous buffer will be kept instead of allocating and copying a new one. This is done as a performance optimization for callers that need to grow and shrink their buffer frequently, but don’t necessarily want to incur the overhead of an allocation and copy each time. For example, if the threshold is 25% and the buffer is resized from 20 items to 6, a reallocation will not occur since the new size is 30% of the previous. By contrast, if it is resized to 4 items from 20, a reallocation will occur since the new size is 20% of the previous. By default the buffer will only grow and never shrink regardless of the size and number of resize requests.

Public Types

using DataType = T

The data type contained in this scratch buffer.

This can be any primitive, struct, or class type. This is present here so that external callers can inspect the contained type if needed.

Public Functions

inline ScratchBuffer()

Constructor: initializes a new empty scratch buffer.

Returns

no return value.

inline ScratchBuffer(const ScratchBuffer &right)

Copy constructor: copies a scratch buffer from another one.

Parameters

right[in] The other scratch buffer to copy. The contents of the buffer will be copied into this object and this object will be resized to match the size of right. The other object will not be modified.

Returns

no return value.

inline ScratchBuffer(ScratchBuffer &&right)

Move constructor: moves another scratch buffer into this one.

Parameters

right[in] The other scratch buffer to move from. The contents of the buffer will be copied into this object and this object will be resized to match the size of right. The other object will be reset back to an empty state after the data is moved.

Returns

no return value.

inline ~ScratchBuffer()
inline ScratchBuffer &operator=(const ScratchBuffer &right)

Assignment operator (copy).

Parameters

right[in] The other scratch buffer to copy from.

Returns

A reference to this object. All items in the right buffer will be copied into this object by the most efficient means possible.

inline ScratchBuffer &operator=(ScratchBuffer &&right)

Assignment operator (move).

Parameters

right[in] The other scratch buffer to move from.

Returns

A reference to this object. All items in the right buffer will be moved into this object by the most efficient means possible. The right buffer will be cleared out upon return (this only really has a meaning if the contained type is a movable class).

inline T &operator[](size_t index)

Array access operator.

Parameters

index[in] The index to access the array at. It is the caller’s responsibility to ensure this index is within the bounds of the array.

Returns

A reference to the requested entry in the array as an lvalue.

inline T *data()

Array accessor.

Returns

The base address of the buffer. This address will be valid until the next call to resize(). It is the caller’s responsibility to protect access to this buffer as needed.

inline const T *data() const

Array accessor.

Returns

The base address of the buffer. This address will be valid until the next call to resize(). It is the caller’s responsibility to protect access to this buffer as needed.

inline size_t size() const

Retrieves the current size of the buffer in items.

Returns

The current size of this buffer in items. This value is valid until the next call to resize(). The size in bytes can be calculated by multiplying this value by sizeof(DataType).

inline bool resize(size_t count)

Attempts to resize this buffer.

Parameters

count[in] The new requested size of the buffer in items. This may not be zero.

Returns

true if the buffer was successfully resized. If the requested count is smaller than or equal to the BaseSize value for this object, resizing will always succeed.

Returns

false if the buffer could not be resized. On failure, the previous contents and size of the array will be left unchanged.

Public Static Attributes

static constexpr size_t BaseSize = BaseSize_

The guaranteed base size of this scratch buffer in items.

This is present here so that external callers can inspect the guaranteed size of the buffer object.