crow

Utility library


Project maintained by CaptainCrowbar Hosted on GitHub Pages — Theme by mattgraham

Compact array optimized for small size

Crow Library by Ross Smith

#include "crow/compact-array.hpp"
namespace Crow;

Compact array class

template <typename T, size_t N> class CompactArray

CompactArray is a vector-like container optimized for small numbers of objects. An extra template parameter specifies a size threshold beyond which the array is seldom or never expected to grow. As long as the actual element count stays less than or equal to the threshold, the entire array will be held on the stack, and no dynamic allocation will be done (unless the element type itself does any internally). If the size grows beyond the threshold, the CompactArray will transparently switch to dynamic allocation. The user does not need to pay attention to when the switch to dynamic allocation takes place, but can check if desired.

The element type T must be a complete, concrete type that is at least destructible and either move or copy constructible and assignable. Some operations place additional requirements on T. Copy construction and assignment are required by any operation that may copy an object; default construction is only required by operations that may create new elements without being supplied with a value to give them. CompactArray’s equality comparison calls T’s equality operator; the ordered comparisons call T’s less-than operator. CompactArray’s hash function calls std::hash<T>. Comparison, swap, move, and hash operations on T are assumed not to throw.

The threshold size (N) should not be too large; the CompactArray allocates N*sizeof(T) bytes on the stack, plus a few bytes for housekeeping. Setting N to zero effectively turns CompactArray into a std::vector.

Most of the CompactArray interface is the same as std::vector. Operations that are new to CompactArray or differ in some significant way from the corresponding operations on a vector are described in more detail.

class CompactArray::const_iterator;
using CompactArray::const_reference = const T&;
using CompactArray::difference_type = ptrdiff_t;
class CompactArray::iterator;
using CompactArray::reference = T&;
using CompactArray::size_type = size_t;
using CompactArray::value_type = T;

Member types.

static constexpr size_t CompactArray::threshold = N;

Member constant.

CompactArray::CompactArray() noexcept;
explicit CompactArray::CompactArray(size_t n, const T& t = {});
template <std::input_iterator I> CompactArray::CompactArray(I i, I j);
CompactArray::CompactArray(std::initializer_list<T> list);
CompactArray::~CompactArray() noexcept;
CompactArray::CompactArray(const CompactArray& ca);
CompactArray::CompactArray(CompactArray&& ca) noexcept;
CompactArray& CompactArray::operator=(const CompactArray& ca);
CompactArray& CompactArray::operator=(CompactArray&& ca) noexcept;
CompactArray& CompactArray::operator=(std::initializer_list<T> list);

Life cycle functions.

T& CompactArray::operator[](size_t i) noexcept;
const T& CompactArray::operator[](size_t i) const noexcept;
T& CompactArray::at(size_t i);
const T& CompactArray::at(size_t i) const;
CompactArray::iterator CompactArray::begin() noexcept;
CompactArray::const_iterator CompactArray::begin() const noexcept;
CompactArray::const_iterator CompactArray::cbegin() const noexcept;
CompactArray::iterator CompactArray::end() noexcept;
CompactArray::const_iterator CompactArray::end() const noexcept;
CompactArray::const_iterator CompactArray::cend() const noexcept;
T* CompactArray::data() noexcept;
const T* CompactArray::data() const noexcept;
const T* CompactArray::cdata() const noexcept;
T& BoundedArray::front() noexcept;
const T& BoundedArray::front() const noexcept;
T& BoundedArray::back() noexcept;
const T& BoundedArray::back() const noexcept;

Element access functions.

size_t CompactArray::capacity() const noexcept;
void CompactArray::clear() noexcept;
bool CompactArray::empty() const noexcept;
bool CompactArray::is_compact() const noexcept;
void CompactArray::reserve(size_t n);
void CompactArray::resize(size_t n, const T& t = {});
void CompactArray::shrink_to_fit();
size_t CompactArray::size() const noexcept;

Capacity functions. The capacity will never be less than N; if it grows above N, the dynamically allocated capacity grows by factors of 2, in the same way as most std::vector implementations. The is_compact() function can be used to check whether the elements are currently statically or dynamically allocated. Once allocation has switched to dynamic memory, the capacity will not be reduced by operations that remove elements (except clear(), which resets the container to static allocation). The user can reduce the current allocation overhead by calling shrink_to_fit(), which forces the container back to static allocation if the current element count is small enough, or if not, reallocates the dynamic array to set the capacity exactly equal to the current size.

template <std::input_iterator I>
    CompactArray::iterator CompactArray::append(I i, I j);
template <typename InputRange>
    CompactArray::iterator CompactArray::append(const InputRange& r);
template <typename InputRange>
    CompactArray::iterator CompactArray::append(InputRange&& r);
template <typename... Args>
    void CompactArray::emplace_back(Args&&... args);
template <typename... Args>
    CompactArray::iterator CompactArray::emplace(const_iterator i,
        Args&&... args);
CompactArray::iterator
    CompactArray::insert(const_iterator i, const T& t);
CompactArray::iterator
    CompactArray::insert(const_iterator i, T&& t);
template <std::input_iterator I>
    CompactArray::iterator CompactArray::insert(const_iterator i, I j, I k);
void CompactArray::push_back(const T& t);
void CompactArray::push_back(T&& t);

Insertion functions. The append() function is a convenience shorthand for insertion at the end, which is usually more efficient than insertion anywhere else. Like insert(), it returns an iterator pointing to the first inserted element.

void CompactArray::erase(const_iterator i) noexcept;
void CompactArray::erase(const_iterator i, const_iterator j) noexcept;
void CompactArray::pop_back() noexcept;

Erasure functions.

size_t CompactArray::hash() const noexcept;
struct std::hash<CompactArray<T, N>>;

Hash functions.

void CompactArray::swap(CompactArray& ca) noexcept;
void swap(CompactArray& a, CompactArray& b) noexcept;

Swap functions.

std::strong_ordering operator<=>(const CompactArray& a, const CompactArray& b) noexcept;
bool operator==(const CompactArray& a, const CompactArray& b) noexcept;
bool operator!=(const CompactArray& a, const CompactArray& b) noexcept;
bool operator<(const CompactArray& a, const CompactArray& b) noexcept;
bool operator>(const CompactArray& a, const CompactArray& b) noexcept;
bool operator<=(const CompactArray& a, const CompactArray& b) noexcept;
bool operator>=(const CompactArray& a, const CompactArray& b) noexcept;

Comparison operators.