Containers

CVector

A growable contiguous sequence with standard vector operations and concise additions.

C++23 mc/CVector.h
#include <mc/CVector.h>

Standard-style names retain their familiar container meaning. The notes below explain lookup results, mutation, ownership, and Catalyst conveniences; only entirely obvious operations are left as declarations.

Exceptions escaping container operations are translated to CError. Direct iterator operations, element references, and calls through .std() follow the underlying type’s contracts.

Jump to a declaration · 105

CVector

template<class T, class Alloc = std::allocator<T>> class CVector

Types, constants & data

using Vector = std::vector<T, Alloc>;
using value_type = T;
using iterator = typename Vector::iterator;
using const_iterator = typename Vector::const_iterator;
using reverse_iterator = typename Vector::reverse_iterator;
using const_reverse_iterator = typename Vector::const_reverse_iterator;
using reference = typename Vector::reference;
using const_reference = typename Vector::const_reference;
using allocator_type = typename Vector::allocator_type;
using pointer = typename Vector::pointer;
using const_pointer = typename Vector::const_pointer;
using size_type = typename Vector::size_type;
using difference_type = typename Vector::difference_type;
using indexed_type = reference;

Methods

CVector

constexpr CVector() noexcept(noexcept(Alloc()));
constexpr explicit CVector(const Alloc& alloc) noexcept;
constexpr explicit CVector(size_type n, const Alloc& alloc = cContainerDefault<Alloc>());
constexpr CVector(size_type n, const T& value, const Alloc& alloc = cContainerDefault<Alloc>());
template<CInputIterator I> constexpr CVector(I first, I last, const Alloc& alloc = cContainerDefault<Alloc>());
template<CContainerRange<T> R> constexpr CVector(std::from_range_t, R&& range, const Alloc& alloc = cContainerDefault<Alloc>());
constexpr CVector(const CVector& x);
constexpr CVector(CVector&& x) noexcept;
constexpr CVector(const CVector& x, const std::type_identity_t<Alloc>& alloc);
constexpr CVector(CVector&& x, const std::type_identity_t<Alloc>& alloc);
constexpr CVector(const Vector& x);
constexpr CVector(Vector&& x) noexcept;
constexpr CVector(const Vector& x, const std::type_identity_t<Alloc>& alloc);
constexpr CVector(Vector&& x, const std::type_identity_t<Alloc>& alloc);
constexpr CVector(std::initializer_list<value_type> il, const Alloc& alloc = cContainerDefault<Alloc>());
CVector(CBuffer& b);
CVector(std::function<CVector()> f);

Creates an empty sequence, copies a range or initializer list, or creates n elements with an optional repeated value. The count constructor changes size rather than merely reserving capacity; the CBuffer overload restores a typed serialized sequence.

fromArgs

template<class... Args> static CVector fromArgs(Args&&... args);

Builds a container with one element per argument, in argument order. Arguments are forwarded so move-only values can be supplied as rvalues.

fromTuple

template<class... Ts> void fromTuple(const std::tuple<Ts...>& t);

Appends each tuple field in order, converting fields to the vector element type. Existing vector elements are retained.

range

static CVector range(int64_t a, int64_t b);
static CVector range(size_t size);

Builds consecutive values in [a, b), or [0, size) for the one-argument form. These overloads require a nonempty range (a < b).

assign

template<CInputIterator InputIterator> constexpr void assign(InputIterator first, InputIterator last);
constexpr void assign(size_type n, const T& u);
constexpr void assign(std::initializer_list<T> values);

Replaces all elements with the supplied count/value, iterator range, or initializer list. Existing element references and iterators may be invalidated.

assign_range

template<CContainerRange<T> R> constexpr void assign_range(R&& range);

Replaces the contents with the elements of a C++ range. Each range element must be convertible to the container element type.

begin

constexpr iterator begin() noexcept;
constexpr const_iterator begin() const noexcept;

cbegin

constexpr const_iterator cbegin() const noexcept;

end

constexpr iterator end() noexcept;
constexpr const_iterator end() const noexcept;

cend

constexpr const_iterator cend() const noexcept;

rbegin

constexpr reverse_iterator rbegin() noexcept;
constexpr const_reverse_iterator rbegin() const noexcept;

crbegin

constexpr const_reverse_iterator crbegin() const noexcept;

rend

constexpr reverse_iterator rend() noexcept;
constexpr const_reverse_iterator rend() const noexcept;

crend

constexpr const_reverse_iterator crend() const noexcept;

span

cspan span() const noexcept;
cspan span(size_t start) const noexcept;
cspan span(size_t start, size_t endOffset) const noexcept;

Returns an index range. start skips initial indices; endOffset excludes that many indices at the end.

empty

constexpr bool empty() const noexcept;

size

constexpr size_type size() const noexcept;

max_size

constexpr size_type max_size() const noexcept;

capacity

constexpr size_type capacity() const noexcept;

reserve

constexpr void reserve(size_type n);

Ensures capacity for at least the requested element count without changing size(). Reallocation invalidates pointers, references, and iterators into the storage.

shrink_to_fit

constexpr void shrink_to_fit() noexcept(noexcept(v_.shrink_to_fit()));

Requests release of unused capacity. The underlying container may retain capacity, and storage relocation can invalidate existing references and iterators.

operator[]

constexpr reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;

Returns the element at a zero-based index. The index must be below size(); this is not a checked, recoverable out-of-range lookup.

at

constexpr const_reference at(size_type n) const;
constexpr reference at(size_type n);

Returns the element at a zero-based index. An invalid index raises COutOfRangeError.

uget

const_reference uget(size_t n, const T& def) const;

Returns the indexed element, or def when the index is outside the container. The reference overload borrows either the element or the supplied fallback; it does not extend either lifetime.

front

constexpr reference front() noexcept(noexcept(v_.front()));
constexpr const_reference front() const noexcept(noexcept(v_.front()));

Returns the first element by reference. The container must be nonempty.

back

constexpr reference back() noexcept(noexcept(v_.back()));
constexpr const_reference back() const noexcept(noexcept(v_.back()));
constexpr reference back(size_t i);
constexpr const_reference back(size_t i) const;

Returns the last element, or the element i positions before it: back(0) is the last element. The container must contain the requested element.

data

constexpr value_type* data() noexcept requires(!std::same_as<T, bool>);
constexpr const value_type* data() const noexcept requires(!std::same_as<T, bool>);

view

std::span<T> view() noexcept requires(!CSame<T, bool>);
std::span<const T> view() const noexcept requires(!CSame<T, bool>);

Returns a borrowed span over the current elements. Keep the container alive and do not use the view after an operation that invalidates its storage.

find

iterator find(const T& v);
const_iterator find(const T& v) const;

Returns an iterator to the first equal element, or end() when absent. The search is linear.

indexOf

size_t indexOf(const T& v) const;

Returns the matching index, or size() if no element matches.

hasIndex

bool hasIndex(size_t i) const;

Tests whether the index is below size(), without accessing or adding an element.

has

bool has(const T& v) const;

Reports whether an equal element occurs in the container.

insert

constexpr iterator insert(size_t index, const T& x);
constexpr iterator insert(size_t index, T&& x);
constexpr iterator insert(const_iterator position, const T& x);
constexpr iterator insert(const_iterator position, T&& x);
constexpr iterator insert(const_iterator position, size_type n, const T& x);
template<CInputIterator InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last);
constexpr iterator insert(const_iterator position, std::initializer_list<T> values);

Inserts before a valid position or index; an index equal to size() appends. Returns the iterator to the inserted element or the first element of an inserted range.

insert_range

template<CContainerRange<T> R> constexpr iterator insert_range(const_iterator position, R&& range);

Inserts the elements of a C++ range before the supplied iterator. Returns an iterator to the first inserted element, or the insertion position for an empty range.

emplace

template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);

Constructs an element before the given position from forwarded constructor arguments. Returns its iterator.

put

void put(size_t i, const T& v);
void put(size_t i, T&& v);

Assigns an element by index, first growing the container to i + 1 when necessary. Any intervening new elements are value-initialized.

operator<<

template<class V> CVector& operator<<(V&& x);

Appends one element and returns this container, allowing chained appends.

push_back

constexpr void push_back(const T& x);
constexpr void push_back(T&& x);

emplace_back

template<class... Args> constexpr reference emplace_back(Args&&... args);

Constructs an element at the end from forwarded constructor arguments and returns a reference to it.

append

template<CItems S> void append(const S& items);
void append(const CVector& v);
void append(CVector&& v);

Appends elements after the existing contents. The rvalue-vector overload moves individual elements but retains the source vector’s size; its elements are left moved from.

append_range

template<CContainerRange<T> R> constexpr void append_range(R&& range);

Adds a C++ range at the end, preserving the order of its elements. Existing contents remain at the beginning.

pushFront

void pushFront(const T& x);
void pushFront(T&& x);

Inserts one value at the beginning, shifting existing elements. References at or after that position are invalidated.

erase

constexpr iterator erase(const_iterator position);
constexpr iterator erase(const_iterator first, const_iterator last);
constexpr iterator erase(size_t index);

Removes the indexed element, the element at an iterator, or the half-open iterator range. Returns the iterator following the removed elements; indices and iterators must identify valid positions.

pop_back

constexpr void pop_back() noexcept(noexcept(v_.back()));

Removes the last element without returning it. The container must be nonempty; use popBack() to retain its value.

popBack

T popBack();

Removes and returns the last element. The container must be nonempty.

pop_front

void pop_front() noexcept(noexcept(v_.front()));

Removes the first element without returning it. The container must be nonempty; use popFront() to retain its value.

popFront

T popFront();

Removes and returns the first element. The container must be nonempty.

clear

constexpr void clear() noexcept;

clearExcept

template<class S> void clearExcept(const S& s);

Removes every element for which s.has(element) is false. The surviving elements retain their relative order.

resize

constexpr void resize(size_type n) requires(!std::same_as<T, bool>);
constexpr void resize(size_type n, const T& value) requires(!std::same_as<T, bool>);
constexpr void resize(size_type n, bool value = false) requires(std::same_as<T, bool>);

Changes the number of elements, removing trailing elements or appending default/value-initialized elements. It changes size(), unlike reserve().

swap

constexpr void swap(CVector& vec) noexcept(noexcept(v_.swap(vec.v_)));
static constexpr void swap(reference first, reference second) noexcept requires(std::same_as<T, bool>);

reverse

void reverse();

Reverses the current elements in place without changing size.

flip

constexpr void flip() noexcept requires(std::same_as<T, bool>);

Inverts every stored bit in a CVector<bool> without changing its size.

operator+=

CVector& operator+=(const CVector& v);
template<CNumeric S> CVector& operator+=(S x);

Adds corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Updates this vector in place.

operator+

CVector operator+(const CVector& v) const;
template<CNumeric S> CVector operator+(S x) const;

Adds corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Returns a new vector.

operator-=

CVector& operator-=(const CVector& v);
template<CNumeric S> CVector& operator-=(S x);

Subtracts corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Updates this vector in place.

operator-

CVector operator-(const CVector& v) const;
template<CNumeric S> CVector operator-(S x) const;

Subtracts corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Returns a new vector.

operator*=

CVector& operator*=(const CVector& v);
template<CNumeric S> CVector& operator*=(S x);

Multiplies corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Updates this vector in place.

operator*

CVector operator*(const CVector& v) const;
template<CNumeric S> CVector operator*(S x) const;

Multiplies corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Returns a new vector.

operator/=

CVector& operator/=(const CVector& v);
template<CNumeric S> CVector& operator/=(S x);

Divides corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Supply valid nonzero divisors for integral components. Updates this vector in place.

operator/

CVector operator/(const CVector& v) const;
template<CNumeric S> CVector operator/(S x) const;

Divides corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Supply valid nonzero divisors for integral components. Returns a new vector.

operator%=

CVector& operator%=(const CVector& v);
template<CNumeric S> CVector& operator%=(S x);

Takes the remainder of corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Element types must support %; floating-point member remainder is not implemented. Supply valid nonzero divisors for integral components. Updates this vector in place.

operator%

CVector operator%(const CVector& v) const;
template<CNumeric S> CVector operator%(S x) const;

Takes the remainder of corresponding components, or applies the scalar to every component. Vector operands must have compatible sizes; no size check is performed. Element types must support %; floating-point member remainder is not implemented. Supply valid nonzero divisors for integral components. Returns a new vector.

std

constexpr const Vector& std() const noexcept;
constexpr Vector& std() noexcept;

Returns a reference to the underlying standard container. Mutations affect this object directly; calls through that reference bypass Catalyst exception translation.

get_allocator

constexpr allocator_type get_allocator() const noexcept;

store

void store(CBuffer& b) const;

Appends the container to a CBuffer; restore it with the buffer-taking constructor.

output

void output(std::ostream& ostr) const;

Writes comma-separated elements to the stream without the surrounding container brackets.

dump

cstr dump() const;

Returns the stream-formatted representation as a cstr; this is display text rather than the binary storage format.

Free functions & types

Functions

operator+

template<class T, class A, CNumeric S> CVector<T, A> operator+(S x, const CVector<T, A>& v);

Returns a new vector by applying scalar-left addition to each element in operand order. The result keeps the vector’s element type.

operator-

template<class T, class A, CNumeric S> CVector<T, A> operator-(S x, const CVector<T, A>& v);

Returns a new vector by applying scalar-left subtraction to each element in operand order. The result keeps the vector’s element type.

operator*

template<class T, class A, CNumeric S> CVector<T, A> operator*(S x, const CVector<T, A>& v);

Returns a new vector by applying scalar-left multiplication to each element in operand order. The result keeps the vector’s element type.

operator/

template<class T, class A, CNumeric S> CVector<T, A> operator/(S x, const CVector<T, A>& v);

Returns a new vector by applying scalar-left division to each element in operand order. The result keeps the vector’s element type.

operator%

template<class T, class A, CNumeric S> CVector<T, A> operator%(S x, const CVector<T, A>& v);

Returns a new vector by applying scalar-left remainder to each element in operand order. The result keeps the vector’s element type. Floating element types use std::fmod.

operator<<

template<class T, class A> inline std::ostream& operator<<(std::ostream& ostr, const CVector<T, A>& v);

swap

template<class T, class A> constexpr void swap(CVector<T, A>& x, CVector<T, A>& y) noexcept(noexcept(x.swap(y)));

erase

template<class T, class A, class U> constexpr typename CVector<T, A>::size_type erase(CVector<T, A>& values, const U& value);

Removes all elements equal to the supplied value and returns the number removed.

erase_if

template<class T, class A, class Predicate> constexpr typename CVector<T, A>::size_type erase_if(CVector<T, A>& values, Predicate predicate);

Removes every element for which the predicate returns true and returns the number removed.

<deduction guide for CVector>

template<CInputIterator I, class Alloc = std::allocator<typename std::iterator_traits<I>::value_type>> CVector(I, I, Alloc = cContainerDefault<Alloc>()) -> CVector<typename std::iterator_traits<I>::value_type, Alloc>;
template<std::ranges::input_range R, class Alloc = std::allocator<std::ranges::range_value_t<R>>> CVector(std::from_range_t, R&&, Alloc = cContainerDefault<Alloc>()) -> CVector<std::ranges::range_value_t<R>, Alloc>;
template<class T, class Alloc = std::allocator<T>> CVector(std::initializer_list<T>, Alloc = cContainerDefault<Alloc>()) -> CVector<T, Alloc>;

pmr

Types, constants & data

template<class T> using CVector = mc::CVector<T, std::pmr::polymorphic_allocator<T>>;

std::hash

template<class Alloc> struct hash<mc::CVector<bool, Alloc>>

Methods

operator()

size_t operator()(const mc::CVector<bool, Alloc>& values) const noexcept(noexcept(hash<vector<bool, Alloc>>{}(values.std())));