![]() |
Pixie
|
CRTP contract for exclusively owned sequences with immutable reads. More...
#include <permutable_sequence.h>
Public Types | |
| using | value_type = T |
| Stored element type. | |
| using | const_reference = ConstReference |
| Immutable result type. | |
| using | size_type = std::size_t |
| Count and position type. | |
Public Member Functions | |
| size_type | size () const noexcept |
| Return the logical element count. | |
| bool | empty () const noexcept |
| Test emptiness. | |
| const_reference | operator[] (size_type position) const |
| Read a checked zero-based element without exposing mutation. | |
| void | insert_at (size_type position, T value) |
| Insert one value at a zero-based position. | |
| void | rotate_left (size_type left, size_type right, size_type distance) |
| Rotate [left,right) left while preserving outside values. | |
| void | merge (Impl &donor) |
| Append unchanged donor values and consume donor ownership. | |
| size_type | memory_usage_bytes () const noexcept |
| Explicitly account for requested live storage. | |
Static Public Member Functions | |
| template<std::ranges::input_range Range> requires std:: constructible_from<T, std::ranges::range_rvalue_reference_t<Range>> | |
| static Impl | from_range (Range &&range) |
| Consume a possibly single-pass input range into an owning sequence. | |
CRTP contract for exclusively owned sequences with immutable reads.
Merge appends unchanged values, unlike permutation rebasing. Implementations provide constrained from_range_impl(range), size_impl(), value_at_impl(i), insert_at_impl(position,value), rotate_left_impl(left,right,distance), merge_impl(donor), and memory_usage_bytes_impl() with the facade semantics documented below. size_impl() and memory_usage_bytes_impl() must be noexcept. Other extension points propagate the documented exceptions. Validation belongs to the implementation; the facade does not repeat it. No virtual dispatch. Required signatures are size_type size_impl() const noexcept, ConstReference value_at_impl(size_type) const, void insert_at_impl(size_type, T), void rotate_left_impl(size_type,size_type,size_type), void merge_impl(Impl&), and size_type memory_usage_bytes_impl() const noexcept. The static factory returns Impl and accepts Range&& with the same input-range and iterator-move constructibility constraints as from_range(). Private extension points grant friendship to this base. Concrete owners default-construct canonical empty and are move-only with nonthrowing move and destruction; moves leave the source canonical empty and self-move is a no-op.
| Impl | Concrete owning implementation. |
| T | Stored object type. |
| ConstReference | Explicit result type: T or const T&, avoiding lookup in the incomplete CRTP implementation and preventing reference copies. |
| using pixie::PermutableSequenceBase< Impl, T, ConstReference >::const_reference = ConstReference |
Immutable result type.
T by value or stable const T&.
| using pixie::PermutableSequenceBase< Impl, T, ConstReference >::size_type = std::size_t |
Count and position type.
Full unsigned size_t range.
| using pixie::PermutableSequenceBase< Impl, T, ConstReference >::value_type = T |
Stored element type.
Independent of representation.
|
inlinenoexcept |
Test emptiness.
Equivalent to size()==0; canonical empty owns no heap storage.
|
inlinestatic |
Consume a possibly single-pass input range into an owning sequence.
from_range_impl consumes through ranges::iter_move, preserving order and supporting non-common, unsized ranges. On allocation, iteration, or element-construction failure all acquired ownership is reclaimed, but visited inputs may already be consumed. Input references are not retained. This is not the strong mutation guarantee for existing containers.
| Range | Input range whose iterator-move results construct T. |
| range | Source consumed in iteration order. |
| std::length_error | If count or configured chunk capacity is too large. |
| std::bad_alloc | If storage allocation fails. |
| Any | Exception from input iteration or element construction. |
|
inline |
Insert one value at a zero-based position.
insert_at_impl(position,value) inserts value at position, shifting existing elements at or after position one to the right. Indirect storage constructs the value in a payload chunk before the tree insert; on tree failure the chunk is rolled back and the exception propagates. For move-only T the value is consumed even on tree failure.
| position | Insertion position in [0,size()]. |
| value | Element to own and insert. |
| std::out_of_range | If position > size(). |
| std::bad_alloc | If allocation fails. |
| Any | Exception from element construction. |
|
inlinenoexcept |
Explicitly account for requested live storage.
memory_usage_bytes_impl() traverses allocations and chunks in linear time without allocating or throwing. Includes facade, metadata, padding, and payload capacity including slack; saturates at SIZE_MAX. Excludes allocations inside T, allocator overhead, RSS, stack scratch and temporary peaks. Concrete memory_usage() has subset fields that must not be added again to its disjoint total categories.
|
inline |
Append unchanged donor values and consume donor ownership.
merge_impl accepts only identical configurations. Self merge and empty donor are no-ops; success leaves donor canonical empty. Count or allocation or element-copy failure leaves both containers unchanged. Indirect objects never move and references from either participant retain their addresses.
| donor | Owner whose unchanged values follow this sequence's values. |
| std::length_error | If the combined count exceeds SIZE_MAX. |
| std::bad_alloc | If preflight allocation fails. |
| Any | Exception from copying elements in a by-value implementation. |
|
inline |
Read a checked zero-based element without exposing mutation.
value_at_impl(position) returns exactly const_reference. Indirect references survive rotation, merge (including consumed donor references), and ownership moves. They expire when the eventual owner destroys or replaces their payload. No contiguous buffer or sentinel is promised.
| position | Position in [0,size()). |
| std::out_of_range | If position >= size(). |
| Any | Exception from constructing a by-value result. |
|
inline |
Rotate [left,right) left while preserving outside values.
rotate_left_impl validates even at zero distance; empty intervals are no-ops, otherwise distance is reduced modulo right-left. Allocation or element-copy failure leaves contents and indirect addresses unchanged.
| left | Inclusive start. |
| right | Exclusive end, at most size(). |
| distance | Left rotation distance in elements. |
| std::out_of_range | If left > right or right > size(). |
| std::bad_alloc | If preflight allocation fails. |
| Any | Exception from copying elements in a by-value implementation. |
|
inlinenoexcept |
Return the logical element count.
size_impl() reads the count without allocation or mutation.