#include <stlsoft/memory/auto_buffer.hpp>
T | The type of the elements in the array | |
SPACE | The number of elements in the array. For translators that support default template arguments, this is defaulted to 256 | |
A | The allocator type. Defaults to allocator_selector<T>::allocator_type for translators that support default template arguments. |
Using auto_buffer
means one can avoid use of heap memory in circumstances where stack memory is unsuitable, i.e. where there is no maximum size to a memory requirement, or the maximum size is potentially very large (and considerably larger than the median size). Consider the following code extract from the core of the Pantheios logging library:
int pantheios_log_n( pan_sev_t severity , size_t numSlices , pan_slice_t const* slices) { typedef stlsoft::auto_buffer<char, 2048> buffer_t; // Calculate the total size of the log statement, by summation of the slice array const size_t n = std::accumulate(stlsoft::member_selector(slices, &pan_slice_t::len) , stlsoft::member_selector(slices + numSlices, &pan_slice_t::len) , size_t(0)); buffer_t buffer(1 + n); . . .
This use of auto_buffer illustrates two important features:
Without auto_buffer, we would have three choices, all bad:
1. We could go to the heap in all cases:
int pantheios_log_n( pan_sev_t severity , size_t numSlices , pan_slice_t const* slices) { typedef stlsoft::vector<char> buffer_t; // Calculate the total size of the log statement, by summation of the slice array const size_t n = std::accumulate(stlsoft::member_selector(slices, &pan_slice_t::len) , stlsoft::member_selector(slices + numSlices, &pan_slice_t::len) , size_t(0)); buffer_t buffer(1 + n); . . .
2. We could use a stack buffer, and truncate any log statement exceeding the limit:
int pantheios_log_n( pan_sev_t severity , size_t numSlices , pan_slice_t const* slices) { // Calculate the total size of the log statement, by summation of the slice array const size_t n = std::accumulate(stlsoft::member_selector(slices, &pan_slice_t::len) , stlsoft::member_selector(slices + numSlices, &pan_slice_t::len) , size_t(0)); char buffer[2048]; . . . // make sure to truncate the statement to a max 2047 characters
3. Finally, we could synthesise the functionality of auto_buffer manually, as in:
int pantheios_log_n( pan_sev_t severity , size_t numSlices , pan_slice_t const* slices) { // Calculate the total size of the log statement, by summation of the slice array const size_t n = std::accumulate(stlsoft::member_selector(slices, &pan_slice_t::len) , stlsoft::member_selector(slices + numSlices, &pan_slice_t::len) , size_t(0)); char buff[2048]; char *buffer = (n < 2048) ? &buff[0] : new char[1 + n]; . . . if(buffer != &buff[0]) { delete [] buffer; }
As a consequence of its blending of the best features of stack and heap memory, auto_buffer is an invaluable component in the implementation of many components within the STLSoft libraries, and in several other open-source projects, including: b64, Open-RJ, Pantheios, recls, and shwild.
NULL
. In the latter case, construction failure to allocate is reflected by the size() method returning 0.The design of auto_buffer is described in Chapter 32 of Imperfect C++, and its interface is discussed in detail in Section 16.2 of Extended STL, volume 1.
std::allocator
for translators that support the standard library. If you need the old characteristics, you can #define
the symbol STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS. by_library/memory/auto_buffer/auto_buffer.cpp, and by_library/windows_registry/registry_functions/registry_functions.cpp.
Implementation | |
static void | block_copy (pointer dest, const_pointer src, size_type cItems) |
static void | block_set (pointer dest, size_type cItems, const_reference value) |
Operations | |
bool | resize (size_type cItems) |
Expands or contracts the number of items in the buffer. | |
void | swap (class_type &rhs) throw () |
Swaps contents with the given buffer. | |
Attributes | |
size_type | size () const |
Returns the number of elements in the auto_buffer. | |
bool | empty () const |
Indicates whether the buffer has any contents. | |
allocator_type | get_allocator () const |
Returns an instance of the allocator used to specialise the instance. | |
static size_type | internal_size () |
Returns the number of elements in the auto_buffer's internal buffer. | |
Public Types | |
Member Types | |
enum | { space = int(SPACE) } |
typedef T | value_type |
The value type. | |
typedef A | allocator_type |
The allocator type. | |
typedef auto_buffer< T, space, A > | class_type |
The type of the current parameterisation. | |
typedef allocator_type::reference | reference |
The reference type. | |
typedef allocator_type::const_reference | const_reference |
The non-mutable (const) reference type. | |
typedef allocator_type::pointer | pointer |
The pointer type. | |
typedef allocator_type::const_pointer | const_pointer |
The non-mutable (const) pointer type. | |
typedef size_t | size_type |
The size type. | |
typedef ss_ptrdiff_t | difference_type |
The difference type. | |
typedef value_type * | iterator |
The iterator type. | |
typedef value_type const * | const_iterator |
The non-mutable (const) iterator type. | |
Public Member Functions | |
Construction | |
auto_buffer (size_type cItems) | |
Constructs an auto_buffer with the given number of elements. | |
~auto_buffer () | |
Releases the allocated element array. | |
Operators | |
reference | operator[] (size_type index) |
Subscript operator. | |
const_reference | operator[] (size_type index) const |
Subscript operator. | |
Accessors | |
pointer | data () |
Returns a pointer to the element array. | |
const_pointer | data () const |
Returns a pointer-to-const to the element array. | |
reference | front () |
Returns a reference to the last element in the buffer. | |
reference | back () |
Returns a reference to the last element in the buffer. | |
const_reference | front () const |
Returns a non-mutating (const) reference to the last element in the buffer. | |
const_reference | back () const |
Returns a non-mutating (const) reference to the last element in the buffer. | |
Iteration | |
const_iterator | begin () const |
Returns a non-mutating iterator representing the start of the sequence. | |
const_iterator | end () const |
Returns a non-mutating iterator representing the end of the sequence. | |
iterator | begin () |
Returns a mutable iterator representing the start of the sequence. | |
iterator | end () |
Returns a mutable iterator representing the end of the sequence. |
typedef T value_type |
The value type.
typedef A allocator_type |
The allocator type.
typedef auto_buffer<T, space, A> class_type |
The type of the current parameterisation.
typedef allocator_type::reference reference |
The reference type.
typedef allocator_type::const_reference const_reference |
The non-mutable (const) reference type.
typedef allocator_type::pointer pointer |
typedef allocator_type::const_pointer const_pointer |
The non-mutable (const) pointer type.
typedef ss_ptrdiff_t difference_type |
The difference type.
typedef value_type* iterator |
The iterator type.
typedef value_type const* const_iterator |
The non-mutable (const) iterator type.
auto_buffer | ( | size_type | cItems | ) | [inline, explicit] |
Constructs an auto_buffer with the given number of elements.
Constructs an auto_buffer with the given number of elements. If the allocation fails by throwing an exception, that exception is passed through to the caller. If allocation fails by returning a null pointer the auto_buffer instance is correctly constructed, and the size() method returns 0.
cItems | The number of items in the constructed instance |
~auto_buffer | ( | ) | [inline] |
Releases the allocated element array.
Releases any allocated memory. If the internal memory buffer was used, then nothing is done, otherwise the allocated memory is returned to the allocator.
Expands or contracts the number of items in the buffer.
cItems | The number of items to change in the buffer. If 0, the external array (if allocated) will be deallocated. |
true
if successful. Function failure occurs when sufficient storage for the requested items cannot be allocated. In that case, std::bad_alloc will be throw for allocators that support it, otherwise the function will return false
. In either case, the original storage and contents of the buffer will remain unchanged.internal_size()
) then the heap allocated block will not be changed (i.e. it will not be exchanged for a smaller block).
As from STLSoft version 1.9, the external array is not discarded in favour of the internal array when 0 < cItems < internal_size()
. Only resize(0)
will deallocate the external array.
void swap | ( | class_type & | rhs | ) | throw () [inline] |
Swaps contents with the given buffer.
Exception-safety: Provides the no-throw guarantee
const_reference operator[] | ( | size_type | index | ) | const [inline] |
Subscript operator.
pointer data | ( | ) | [inline] |
Returns a pointer to the element array.
const_pointer data | ( | ) | const [inline] |
Returns a pointer-to-const to the element array.
reference front | ( | ) | [inline] |
Returns a reference to the last element in the buffer.
reference back | ( | ) | [inline] |
Returns a reference to the last element in the buffer.
const_reference front | ( | ) | const [inline] |
Returns a non-mutating (const) reference to the last element in the buffer.
const_reference back | ( | ) | const [inline] |
Returns a non-mutating (const) reference to the last element in the buffer.
const_iterator begin | ( | ) | const [inline] |
Returns a non-mutating iterator representing the start of the sequence.
Referenced by basic_commandline_parser::basic_commandline_parser(), and basic_commandline_parser::begin().
const_iterator end | ( | ) | const [inline] |
Returns a non-mutating iterator representing the end of the sequence.
Referenced by basic_commandline_parser::basic_commandline_parser(), basic_commandline_parser::end(), and stlsoft::translate_thousands().
iterator begin | ( | ) | [inline] |
Returns a mutable iterator representing the start of the sequence.
iterator end | ( | ) | [inline] |
Returns a mutable iterator representing the end of the sequence.
size_type size | ( | ) | const [inline] |
Returns the number of elements in the auto_buffer.
Referenced by basic_commandline_parser::basic_commandline_parser(), and basic_commandline_parser::size().
static size_type internal_size | ( | ) | [inline, static] |
Returns the number of elements in the auto_buffer's internal buffer.
bool empty | ( | ) | const [inline] |
Indicates whether the buffer has any contents.
allocator_type get_allocator | ( | ) | const [inline] |
Returns an instance of the allocator used to specialise the instance.