This library provides data buffer types based on C++ concepts and ranges:
- Fixed-size buffer.
- Circular buffer.
- Dynamically-expanding buffer.
- Range adapters to allow ranges to be treated as buffers.
- Adapters to allow buffers to be runtime-polymorphic.
The buffers are intended to be suitable for efficient zero-copy I/O.
WARNING: This library is a work-in-progress and almost certainly contains many bugs.
Copy header files into your source tree. If your project uses CMake, you can add the entire project as a subdirectory (e.g., with Git submodules) and link with the sk-buffer library.
Tested with:
- MSVC 19.28 (VS 16.9) on Windows
- Clang 11.0.0 on Windows
Known not to work (patches welcome):
- Clang 10.0.0 on Linux
- GCC 10.2.0 on Linux
-
sk::basic_buffer<T>
:- A base type for all buffers.
- Type
value_type
: type of object stored in the buffer. - Type
const_value_type
:std::add_const_t<value_type>
- Type
size_type
: integral type that can represent the size of the buffer. - Fn
clear()
: Reset the buffer to its default, empty state, discarding any data it contains.
-
sk::readable_buffer<T>
:- A buffer that can be read from.
- Fn
readable_ranges() -> std::vector<std::span<const_value_type>>
: Return a list of contiguous ranges which contain data in the buffer. Data in the ranges can be copied or passed to data-consuming functions. - Fn
discard(size_type n) -> size_type
: Discard up ton
objects from the start of the buffer. Returns the number of objects discarded. - Fn
read(std::ranges::contiguous_range &r) -> size_type
: Copy data from the buffer intor
, then discard the copied objects. Returns the number of objects copied.
-
sk::writable_buffer<T>
:- A buffer that can be written to.
- Fn
writable_ranges() -> std::vector<std::span<value_type>>
: Return a list of contiguous ranges which refer to empty space in the buffer. Data can be written to the empty space. - Fn
commit(size_type n)
: Mark up ton
objects at the start of the buffer's empty space as readable data. Returns the number of objects committed. - Fn
write(std::ranges::contiguous_range const &r) -> size_type
: Copy objects fromr
into the buffer, then commit the number of objects copied. Returns the number of objects copied.
-
buffer<T>
:readable_buffer<T> && writable_buffer<T>
-
sk::fixed_buffer<T, std::size_t N>
: A fixed-size buffer that can containN
objects of typeT
. Writing data to the buffer fills it up; once the entire buffer has been written to, the buffer becomes useless until it is reset usingclear()
. -
sk::circular_buffer<T, std::size_t N>
: A fixed-size circular buffer that can containN
objects of typeT
. Unlikefixed_buffer
, the circular buffer can be written to forever. However, it can never contain more thanN
objects at once. -
sk::dynamic_buffer<T, std::size_t N = 4096>
: A dynamic buffer that can contain an unlimited number of objects of typeT
. The buffer can be written to forever without reading from it, subject to available memory. Objects are allocated in blocks ofN
bytes. -
sk::readable_range_buffer<std::ranges::contiguous_range R>
: A buffer adapter that exposes a contiguous range as a readable buffer. To create a readable buffer from a ranger
, usesk::make_readable_range_buffer(r)
. -
sk::writable_range_buffer<std::ranges::contiguous_range R>
: A buffer adapter that exposes a contiguous range as a writable buffer. To create a writable buffer from a ranger
, usesk::make_writable_range_buffer(r)
.
-
sk::pmr_readable_buffer<T>
: An abstract base class that represents a runtime-polymorphic readable buffer. This provides the same interface assk::readable_buffer<T>
except that all ranges arestd::span
. -
sk::pmr_writable_buffer<T>
: An abstract base class that represents a runtime-polymorphic writable buffer. This provides the same interface assk::writable_buffer<T>
except that all ranges arestd::span
. -
sk::pmr_buffer<T>
: An abstract base class that represents a runtime-polymorphic buffer which is both readable and writable. This provides the same interface assk::buffer<T>
except that all ranges arestd::span
.
To create a runtime-polymorphic buffer from an existing buffer b
,
use sk::make_pmr_buffer_adapter(b)
. The return type will be one of
sk::pmr_readable_buffer<T>
, sk::pmr_writable_buffer<T>
or
sk::pmr_buffer<T>
depending on the capabilities of b
.
Note that the returned buffer adapter object holds a reference to b
for its lifetime; therefore b
should not be destroyed before the
adapter is.