20namespace swoc {
inline namespace SWOC_VERSION_NS {
36template <
typename T,
size_t N,
class A = std::allocator<T>>
class Vectray {
38 using vector_type = std::vector<T, A>;
44 using pointer = std::remove_reference<T> *;
55 std::array<std::byte,
sizeof(T) * N>
_raw;
76 T
const *
data()
const;
101 explicit Vectray(size_type n, allocator_type
const &alloc = allocator_type{});
104 template <
size_t M> Vectray(Vectray<T, M, A> &&that);
116 T
const *
data()
const;
131 T &operator[](size_type idx);
138 T
const &operator[](size_type idx)
const;
155 return (*
this)[this->
size() - 1];
161 return (*
this)[this->
size() - 1];
168 self_type &push_back(T
const &t);
175 self_type &push_back(T &&t);
183 template <
typename... Args> self_type &emplace_back(Args &&...args);
189 self_type &pop_back();
192 const_iterator begin()
const;
195 const_iterator end()
const;
204 void reserve(size_type n);
209 std::variant<FixedStore, DynamicStore>
_store;
244 if (
DYNAMIC == that._store.index()) {
245 _store = std::move(std::get<DYNAMIC>(that._store));
247 auto span = std::get<FIXED>(that._store).span();
248 if (
span.size() > N) {
250 for (
auto &&item :
span) {
257template <
typename T,
size_t N,
class A> Vectray<T, N, A>::FixedStore::~FixedStore() {
258 for (
auto &item : this->
span()) {
259 std::destroy_at(std::addressof(item));
263template <
typename T,
size_t N,
class A>
269template <
typename T,
size_t N,
class A>
272 return reinterpret_cast<T *
>(
_raw.data());
275template <
typename T,
size_t N,
class A>
278 return reinterpret_cast<T *
>(
_raw.data());
281template <
typename T,
size_t N,
typename A>
284 return this->
items()[idx];
287template <
typename T,
size_t N,
typename A>
290 return this->
items()[idx];
293template <
typename T,
size_t N,
typename A>
298 new (
reinterpret_cast<T *
>(fs._raw.data()) + fs._count++) T(t);
301 std::get<DYNAMIC>(
_store).push_back(t);
309template <
typename T,
size_t N,
typename A>
314 new (
reinterpret_cast<T *
>(fs._raw.data()) + fs._count++) T(std::move(t));
317 std::get<DYNAMIC>(
_store).push_back(std::move(t));
320 [&](
DynamicStore &ds) ->
void { ds.push_back(std::move(t)); }},
325template <
typename T,
size_t N,
class A>
326template <
typename... Args>
327typename Vectray<T, N, A>::self_type &
330 auto &fs{std::get<FIXED>(
_store)};
332 new (
reinterpret_cast<T *
>(fs._raw.data()) + fs._count++) T(std::forward<Args>(args)...);
341template <
typename T,
size_t N,
class A>
350template <
typename T,
size_t N,
typename A>
357template <
typename T,
size_t N,
typename A>
366template <
typename T,
size_t N,
typename A>
372template <
typename T,
size_t N,
typename A>
378template <
typename T,
size_t N,
typename A>
384template <
typename T,
size_t N,
typename A>
391template <
typename T,
size_t N,
class A>
397 for (
auto &&item : this->
items()) {
398 tmp.emplace_back(std::move(item));
404template <
typename T,
size_t N,
class A>
412template <
typename T,
size_t N,
class A>
419template <
typename T,
size_t N,
class A>
426template <
typename T,
size_t N,
class A>
434template <
typename T,
size_t N,
class A>
438 std::get<DYNAMIC>(
_store).reserve(n);
constexpr T * begin() const
Pointer to the first element in the span.
constexpr T * end() const
Pointer to first element not in the span.
span items()
Get the span of the valid items.
static constexpr auto DYNAMIC
Variant index for dynamic storage.
typename swoc::MemSpan< const T >::iterator const_iterator
Constant element iteration.
void reserve(size_type n)
Force at internal storage to hold at least n items.
std::remove_reference< T > const * const_pointer
Pointer to constant element.
std::remove_reference< T > & reference
Reference to element.
Vectray(self_type &&that, allocator_type const &a)
Move constructor.
typename swoc::MemSpan< T >::iterator iterator
Element iteration.
constexpr Vectray(allocator_type const &a)
Construct empty instance with allocator.
std::remove_reference< T > * pointer
Pointer to element.
const_iterator end() const
Iterator past last element.
static constexpr auto FIXED
Variant index for fixed storage.
Vectray()
Default constructor, construct an empty container.
self_type & emplace_back(Args &&...args)
std::variant< FixedStore, DynamicStore > _store
void transfer(size_type rN=BASE_DYNAMIC_SIZE)
A allocator_type
Dynamic storage allocator.
self_type & push_back(T const &t)
typename vector_type::size_type size_type
Type for element count.
static constexpr size_type BASE_DYNAMIC_SIZE
Default size to reserve in the vector when switching to dynamic.
swoc::MemSpan< T > span
Element access.
T & operator[](size_type idx)
const_iterator begin() const
Iterator for first element.
T value_type
Element type for container.
vector_type DynamicStore
Dynamic (heap) storage.
std::remove_reference< T > const & const_reference
Reference to constant element.
typename vector_type::difference_type difference_type
Iterator difference.
swoc::MemSpan< T const > const_span
Constant element access.
For template deduction guides.
MemSpan(std::array< T, N > &) -> MemSpan< T >
Deduction guides.
Internal (fixed) storage.
size_t _count
Number of valid elements.
allocator_type _a
Allocator instance - used for construction.
FixedStore(allocator_type const &a)
FixedStore()=default
Default construct - empty.
std::array< std::byte, sizeof(T) *N > _raw
Raw memory for element storage.