VectorPro
High-performance, header-only dynamic array with configurable growth policy, custom allocator support, and optional modification-event notifications.
Loading...
Searching...
No Matches
Vector.h
Go to the documentation of this file.
1
17#pragma once
18
19#include "Iterator.h"
20
21// clang-format off
22#include <algorithm> // std::copy, std::move, std::equal, std::lexicographical_compare_three_way
23#include <compare> // std::strong_ordering / operator<=>
24#include <concepts> // std::invocable, std::input_iterator (Listener concept, iterator-pair ctor)
25#include <cstddef> // std::size_t, std::ptrdiff_t
26#include <cstdint> // std::uint8_t (EventType underlying type)
27#include <cstring> // std::memcpy (trivial-type fast path in insert/erase/push_back)
28#include <functional> // std::function (ListenerFn storage)
29#include <initializer_list> // std::initializer_list ctor/assign
30#include <iterator> // std::reverse_iterator, iterator tag dispatch
31#include <limits> // std::numeric_limits (overflow checks in growCapacity)
32#include <memory> // std::allocator, std::allocator_traits
33#include <optional> // (reserved: nullable return values)
34#include <span> // std::span (as_span())
35#include <stdexcept> // std::out_of_range, std::length_error
36#include <type_traits> // std::is_trivially_copyable, etc.
37#include <utility> // std::move, std::forward, std::exchange
38// clang-format on
39
40// A std::vector-like dynamic array with configurable growth policy,
41// custom allocator support, and optional modification-event notifications.
42// Requires C++20 (concepts, <=>, std::span, [[no_unique_address]]).
43
44namespace VectorPro {
45
53template <typename F, typename VectorType>
54concept Listener = std::invocable<F, const VectorType&, typename VectorType::EventData>;
55
56namespace detail {
57
68template <typename ListenerFn, bool Enabled> struct ListenerStore {
69 ListenerFn* listeners_ = nullptr;
70 std::size_t lsize_ = 0;
71 std::size_t lcap_ = 0;
72};
73
75template <typename ListenerFn> struct ListenerStore<ListenerFn, false> {};
76
77} // namespace detail
78
94template <typename T, typename Allocator = std::allocator<T>, std::size_t GrowthNum = 2,
95 std::size_t GrowthDen = 1, bool EnableEvents = false>
96 requires std::destructible<T>
97class Vector {
98 public:
99 // Standard container type aliases
100 using allocator_type = Allocator;
101 using value_type = T;
102 using pointer = typename std::allocator_traits<Allocator>::pointer;
103 using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
104 using reference = T&;
105 using const_reference = const T&;
106 using size_type = std::size_t;
107 using difference_type = std::ptrdiff_t;
108
109 // Validates the compile-time growth policy.
110 static_assert(GrowthNum != 0, "VectorPro::Vector: GrowthNum must not be zero");
111 static_assert(GrowthDen != 0, "VectorPro::Vector: GrowthDen must not be zero");
112 static_assert(GrowthNum > GrowthDen,
113 "VectorPro::Vector: GrowthNum must be greater than GrowthDen to ensure growth");
114
116 enum class EventType : std::uint8_t {
117 PUSHBACK,
119 POPBACK,
120 INSERT,
121 REMOVE,
122 ERASE,
123 CLEAR,
124 SHRINK,
125 RESERVE
126 };
127
135 struct EventData {
137 std::size_t index;
138 std::size_t oldSize;
139 std::size_t newSize;
140 };
141
143 using ListenerFn = std::function<void(const Vector&, EventData)>;
145 using ListenerHandle = std::size_t;
146
147 // Iterator type aliases.
150 using reverse_iterator = std::reverse_iterator<iterator>;
151 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
152
153 private:
154 // Core storage state.
155 [[no_unique_address]] Allocator alloc_;
156 pointer data_ = nullptr;
157 std::size_t vsize_ = 0;
158 std::size_t vcap_ = 0;
159
160 // Registered event listeners. Empty (zero size) when EnableEvents is false.
162
163 // Default capacity used for the first allocation.
164 static constexpr std::size_t INITIAL_CAP = 8;
165
166 public:
172 explicit Vector(std::size_t count, const T& value = {});
173
178 Vector(std::initializer_list<T> init);
179
186 template <std::input_iterator It> Vector(It first, It last);
187
192 explicit Vector(const Allocator& alloc = Allocator{});
193
196
202
211
217
224
230
236
245
253
261
271
282
293
295 void pop_back();
296
303
311
314
319 void reserve(std::size_t newCap);
320
323
337
345
353
361
366
371
378 [[nodiscard]] reference at(std::size_t index);
379
387
392
397
404
411
419
426 std::declval<const T&>()));
427
435
441
448
473
474 private:
476 void release() noexcept;
477
487 void copyBufferFrom(const Vector& other);
488
494 [[nodiscard]] std::size_t growCapacity() const noexcept;
495
502 void reallocate(std::size_t newCap);
503
511 void grow_and_push_back(const T& value);
512
517 void grow_and_push_back(T&& value);
518
523 void notify(EventData data);
524};
525
532 bool EnableEvents>
535
543 std::size_t GrowthDen = 1>
545
546} // namespace VectorPro
547
558using namespace VectorPro;
559}
560
561#include "Vector.tpp"
Iterator implementation for VectorPro.
A raw-pointer-backed contiguous random-access iterator.
Definition Iterator.h:40
A dynamically resizable contiguous array.
Definition Vector.h:97
Vector(std::size_t count, const T &value={})
Constructs a vector with count copies of value.
void unsubscribe(ListenerHandle handle)
Removes a previously registered listener.
void pop_back()
Removes the last element. No-op if the vector is empty.
reverse_iterator rend() noexcept
Returns a reverse iterator one before the first element.
reference back()
Returns a reference to the last element. Undefined behavior if empty.
bool contains(const T &value) const noexcept(noexcept(std::declval< const T & >()==std::declval< const T & >()))
Checks whether value is present in the vector.
std::size_t capacity() const noexcept
Returns the number of elements the vector can hold without reallocating.
void shrink_to_fit()
Reduces capacity to match the current size, reallocating if needed.
T & reference
Definition Vector.h:104
std::span< T > as_span() noexcept
Returns a mutable span over the vector's current elements.
iterator find(const T &value) noexcept(noexcept(std::declval< const T & >()==std::declval< const T & >()))
Finds the first element equal to value.
T value_type
Definition Vector.h:101
void push_back(const T &value)
Appends a copy of value to the end, growing capacity if needed.
void swap(Vector &other) noexcept
Exchanges the contents of two vectors, including allocators.
typename std::allocator_traits< Allocator >::pointer pointer
Definition Vector.h:102
iterator insert(const_iterator pos, const T &value)
Inserts a copy of value before pos.
reference at(std::size_t index)
Returns a reference to the element at index, with bounds checking.
std::size_t size_type
Definition Vector.h:106
Allocator allocator_type
Definition Vector.h:100
const_iterator cbegin() const noexcept
Returns a const iterator to the first element.
void emplace_back(Args &&... args)
Constructs a new element in place at the end of the vector.
std::function< void(const Vector &, EventData)> ListenerFn
Callback type invoked with the vector and the event that occurred.
Definition Vector.h:143
std::size_t remove_if(Predicate pred)
Removes all elements for which pred returns true.
bool empty() const noexcept
Returns whether the vector has no elements.
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition Vector.h:151
pointer data_ptr() noexcept
Returns a pointer to the underlying contiguous storage.
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the last element.
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator one before the first element.
EventType
Event types emitted when the vector is modified.
Definition Vector.h:116
@ RESERVE
Emitted by reserve().
@ INSERT
Emitted by insert() and emplace().
@ SHRINK
Emitted by shrink_to_fit().
@ REMOVE
Emitted by remove_if().
@ CLEAR
Emitted by clear().
@ PUSHBACK
Emitted by push_back().
@ ERASE
Emitted by erase().
@ POPBACK
Emitted by pop_back().
@ EMPLACEBACK
Emitted by emplace_back().
typename std::allocator_traits< Allocator >::const_pointer const_pointer
Definition Vector.h:103
std::ptrdiff_t difference_type
Definition Vector.h:107
Vector(It first, It last)
Constructs a vector from an iterator range via repeated push_back().
Vector(const Allocator &alloc=Allocator{})
Constructs an empty vector with no allocated storage.
void clear() noexcept
Destroys all elements, leaving the vector empty. Capacity is unchanged.
&&Listener< F, Vector< T, Allocator, GrowthNum, GrowthDen, EnableEvents > > ListenerHandle subscribe(F &&listeners)
Registers a listener to be notified of modification events.
iterator begin() noexcept
Returns an iterator to the first element.
std::size_t ListenerHandle
Opaque handle returned by subscribe(), used to unsubscribe() later.
Definition Vector.h:145
reference front()
Returns a reference to the first element. Undefined behavior if empty.
Vector(std::initializer_list< T > init)
Constructs a vector from an initializer list.
iterator emplace(const_iterator pos, Args &&... args)
Constructs a new element in place before pos.
std::size_t size() const noexcept
Returns the number of elements currently stored.
iterator erase(const_iterator pos)
Erases the element at pos.
void reserve(std::size_t newCap)
Ensures capacity is at least newCap, reallocating if needed.
const T & const_reference
Definition Vector.h:105
std::reverse_iterator< iterator > reverse_iterator
Definition Vector.h:150
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the last element.
iterator end() noexcept
Returns an iterator one past the last element.
~Vector() noexcept
Destroys all elements and releases storage.
const_iterator cend() const noexcept
Returns a const iterator one past the last element.
Constrains listener callbacks usable with Vector:subscribe().
Definition Vector.h:54
Definition Iterator.h:32
Umbrella alias so this library's types are reachable as rain::Vector, alongside every other project l...
Definition Vector.h:557
Describes a vector modification event.
Definition Vector.h:135
std::size_t index
The index associated with the event, if any.
Definition Vector.h:137
std::size_t newSize
Vector size after the operation.
Definition Vector.h:139
EventType type
The kind of modification that occurred.
Definition Vector.h:136
std::size_t oldSize
Vector size before the operation.
Definition Vector.h:138
Listener bookkeeping storage, conditionally present.
Definition Vector.h:68
ListenerFn * listeners_
Definition Vector.h:69
std::size_t lsize_
Definition Vector.h:70
std::size_t lcap_
Definition Vector.h:71