libhatchet
Loading...
Searching...
No Matches
hxvector.hpp
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2017-2026 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
10
11#include "libhatchet.h"
12
13// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
14#if HX_USE_MACROS_WITH_MODULE
15#error Header does not provide macros alone.
16#endif
17
18#include "hxallocator.hpp"
19#include "hxrange.hpp"
21#include "hxsort.hpp"
22
23HX_NS_BEGIN_
24
25#if HX_CPLUSPLUS >= 202002L
27template<typename T_>
28concept hxvector_concept_ = requires(T_& x_) {
29 sizeof(T_);
30 x_.~T_();
31};
33#else
34#define hxvector_concept_ typename
35#endif
36
38// Internal. Extends the array using placement new when assigned to.
39template<typename array_t_>
40class hxarray_back_inserter_ {
41public:
42 // Internal. Extends the array using placement new when assigned to.
43 template<typename arg_t_>
44 typename array_t_::value_t& operator=(arg_t_&& arg_) {
45 return m_x_.push_back(hxforward<arg_t_>(arg_));
46 }
47private:
48 friend array_t_;
49 hxarray_back_inserter_(array_t_& x_) : m_x_(x_) { }
50#if HX_CPLUSPLUS >= 201703L
51 // Copy elision is C++17.
52 hxarray_back_inserter_(const hxarray_back_inserter_& x_) = delete;
53#endif
54 // No address-of operator. It wouldn't be what was expected.
55 void operator&(void) const = delete;
56 array_t_& m_x_;
57};
59
80template<hxvector_concept_ T_, hxsize_t capacity_=hxallocator_dynamic_capacity>
81class hxvector : private hxallocator<T_, capacity_> {
82public:
84 using iterator = T_*;
85
87 using const_iterator = const T_*;
88
90 using value_t = T_;
91
94 explicit hxvector(void);
95
98 explicit hxvector(hxsize_t size_) noexcept;
99
103 explicit hxvector(hxsize_t size_, const T_& x_) noexcept;
104
107 hxvector(const hxvector& x_) noexcept;
108
111 template <hxsize_t capacity_x_>
113
118 hxvector(hxvector&& x_) noexcept;
119
127 template<typename other_value_t_, hxsize_t array_length_>
128 hxvector(const other_value_t_(&array_)[array_length_]) noexcept;
129
136 template <typename other_value_t_>
137 hxvector(std::initializer_list<other_value_t_> x_) noexcept;
138
139#if HX_CPLUSPLUS >= 202002L
142 template<hxrange_concept_ range_t_>
144 explicit hxvector(range_t_& range_) noexcept;
145
150 template<hxrange_concept_ range_t_>
153 explicit hxvector(range_t_&& range_) noexcept;
154#endif
155
157 ~hxvector(void) noexcept;
158
159#if HX_CPLUSPLUS >= 202302L
165 template<typename self_t_, typename callable_t_>
167 this self_t_&& self_, hxsize_t index_, callable_t_&& callable_)
168 -> hxremove_cvref_t<decltype(
169 hxforward<callable_t_>(callable_)(
171
175 template<typename self_t_, typename callable_t_>
177 this self_t_&& self_, const T_* it_, callable_t_&& callable_)
178 -> hxremove_cvref_t<decltype(
181#endif // HX_CPLUSPLUS >= 202302L
182
186 void operator=(const hxvector& x_) noexcept;
187
188 template <hxsize_t capacity_x_>
189 void operator=(const hxvector<T_, capacity_x_>& x_) noexcept;
190
195 void operator=(hxvector&& x_) noexcept;
196
204 template<typename other_value_t_, hxsize_t array_length_>
205 void operator=(const other_value_t_(&array_)[array_length_]) noexcept;
206
209 const T_& operator[](hxsize_t index_) const;
210
211 T_& operator[](hxsize_t index_);
212
217 void operator+=(const T_& x_) noexcept;
218
223 void operator+=(T_&& x_) noexcept;
224
228 template <hxsize_t capacity_x_>
229 void operator+=(const hxvector<T_, capacity_x_>& x_) noexcept;
230
234 template <hxsize_t capacity_x_>
236
242 hxarray_back_inserter_<hxvector<T_, capacity_>> operator*(void);
243
248 hxvector& operator++(void) { return *this; }
249
251 hxvector& operator++(int) { return *this; }
252
256 template<hxrange_concept_ range_t_>
257 void add_range(range_t_& range_) noexcept;
258
263 template<hxrange_concept_ range_t_,
264 hxenable_if_t<!hxis_lvalue_reference<range_t_>(), int> = 0>
265 void add_range(range_t_&& range_) noexcept;
266
276 template<typename callable_t_>
277 hxattr_nodiscard bool all_of(callable_t_&& callable_) const;
278
279 template<typename callable_t_>
280 bool all_of(callable_t_&& callable_);
281
291 template<typename callable_t_>
292 hxattr_nodiscard bool any_of(callable_t_&& callable_) const;
293
294 template<typename callable_t_>
295 bool any_of(callable_t_&& callable_);
296
301 template <typename iter_t_>
302 void assign(iter_t_ begin_, iter_t_ end_) noexcept;
303
305 const T_& back(void) const;
306
307 T_& back(void);
308
310 const T_* begin(void) const { return this->data(); }
311
312 T_* begin(void) { return this->data(); }
313
317 hxattr_nodiscard const T_* binary_search(const T_& value_) const;
318
319 hxattr_nodiscard T_* binary_search(const T_& value_);
320
323
326 const T_* cbegin(void) const { return this->data(); }
327
329 const T_* cend(void) const { return m_end_; }
330
332 void clear(void) noexcept;
333
335 using hxallocator<T_, capacity_>::data;
336
340 template<typename... args_t_>
341 T_& emplace_back(args_t_&&... args_) noexcept;
342
345 hxattr_nodiscard bool empty(void) const { return m_end_ == this->data(); }
346
348 const T_* end(void) const { return m_end_; }
349
350 T_* end(void) { return m_end_; }
351
355 template<hxsize_t capacity_x_>
357
361 void erase(T_* it_) noexcept hxattr_nonnull(2);
362
366 void erase(hxsize_t index_) noexcept;
367
376 template<typename callable_t_>
377 hxsize_t erase_if_unordered(callable_t_&& callable_) noexcept;
378
390 void erase_unordered(const T_* it_) noexcept hxattr_nonnull(2);
391
395 void erase_unordered(hxsize_t index_) noexcept;
396
400 hxattr_nodiscard const T_* find(const T_& value_) const;
401
402 hxattr_nodiscard T_* find(const T_& value_);
403
413 template<typename callable_t_>
414 hxattr_nodiscard const T_* find_if(callable_t_&& callable_) const;
415
416 template<typename callable_t_>
417 hxattr_nodiscard T_* find_if(callable_t_&& callable_);
418
429 template<typename callable_t_>
430 void for_each(callable_t_&& callable_) const;
431
432 template<typename callable_t_>
433 void for_each(callable_t_&& callable_);
434
436 const T_& front(void) const;
437
438 T_& front(void);
439
443 hxattr_nodiscard bool full(void) const { return m_end_ == this->data() + this->capacity(); }
444
448 template<typename callable_t_>
449 void generate_n(hxsize_t size_, callable_t_&& callable_) noexcept;
450
454
463 template<typename ref_t_>
464 void insert(const T_* it_, ref_t_&& x_) noexcept hxattr_nonnull(2);
465
471 template<typename ref_t_>
472 void insert(hxsize_t index_, ref_t_&& x_) noexcept;
473
475 void insertion_sort(void) noexcept;
476
481 template<hxsize_t capacity_x_>
483
485 void make_heap(void) noexcept;
486
489 hxattr_nodiscard hxsize_t max_size(void) const { return this->capacity(); }
490
493 template <hxsize_t capacity_x_>
495
498 void memset(int byte_=0x00);
499
500#if HX_CPLUSPLUS >= 202302L
506 template<typename self_t_, typename callable_t_>
508 this self_t_&& self_, hxsize_t index_, callable_t_&& callable_)
509 -> decltype(self_.end());
510
514 template<typename self_t_, typename callable_t_>
516 this self_t_&& self_, const T_* it_, callable_t_&& callable_)
517 -> decltype(self_.end());
518#endif // HX_CPLUSPLUS >= 202302L
519
521 void pop_back(void) noexcept;
522
526 void pop_heap(void) noexcept;
527
532 template<typename... args_t_>
533 T_& push_back(args_t_&&... args_) noexcept;
534
539 template<typename ref_t_>
540 T_& push_heap(ref_t_&& arg_) noexcept;
541
547 void reserve(hxsize_t size_,
550
555 void resize(hxsize_t size_) noexcept;
556
561 void resize(hxsize_t size_, const T_& x_) noexcept;
562
564 hxattr_nodiscard hxsize_t size(void) const { return m_end_ - this->data(); }
565
567 hxattr_nodiscard hxsize_t size_bytes(void) const { return hxsizeof<T_>() * this->size(); }
568
570 void sort(void) noexcept;
571
576 void swap(hxvector& x_) noexcept;
577
578#if HX_CPLUSPLUS >= 202302L
583 template<typename self_t_, typename... args_t_>
585 this self_t_&& self_, hxsize_t index_, args_t_&&... args_);
586
590 template<typename self_t_, typename... args_t_>
592 this self_t_&& self_, const T_* it_, args_t_&&... args_);
593#endif // HX_CPLUSPLUS >= 202302L
594
595private:
596 void destruct_(T_* begin_, T_* end_) noexcept;
597 void* push_back_unconstructed_(void);
598
599 T_* m_end_;
600};
601
604template<typename T_, hxsize_t capacity_x_>
605class hxkey_equal_t<hxvector<T_, capacity_x_> > {
606public:
607 template<hxsize_t capacity_y_>
610 const hxvector<T_, capacity_x_>& x_, const hxvector<T_, capacity_y_>& y_) const {
611 return x_.equal(y_);
612 }
613};
614
617template<typename T_, hxsize_t capacity_x_>
618class hxkey_less_t<hxvector<T_, capacity_x_> > {
619public:
620 template<hxsize_t capacity_y_>
623 const hxvector<T_, capacity_x_>& x_, const hxvector<T_, capacity_y_>& y_) const {
624 return x_.less(y_);
625 }
626};
627
630template<typename T_, hxsize_t capacity_x_>
631class hxkey_hash_t<hxvector<T_, capacity_x_> > {
632public:
634 hxhash_t operator()(const hxvector<T_, capacity_x_>& x_) const { return x_.hash(); }
635};
636
637#include "detail/hxvector.inl"
638HX_NS_END_
const T * data(void) const
Returns a pointer to a const and potentially uninitialized array of T.
Definition hxallocator.hpp:96
hxallocator(void)
Does not allocate until reserve_storage is called.
Definition hxallocator.hpp:78
bool operator()(const hxvector< T, capacity_x_ > &x_, const hxvector< T, capacity_y_ > &y_) const
Definition hxvector.hpp:609
hxkey_equal_t<T> - A constexpr callable that returns true if two objects are equivalent.
Definition hxkey.hpp:57
hxhash_t operator()(const hxvector< T, capacity_x_ > &x_) const
Definition hxvector.hpp:634
hxkey_hash_t<T> - A callable that returns the xxhash32 of a numeric value cast to 32 bits.
Definition hxkey.hpp:146
bool operator()(const hxvector< T, capacity_x_ > &x_, const hxvector< T, capacity_y_ > &y_) const
Definition hxvector.hpp:622
hxkey_less_t<T> - A constexpr callable that returns true if the first object is less than the second.
Definition hxkey.hpp:91
hxvector - Implements std::vector, std::inplace_vector and std::back_insert_iterator with a few thing...
Definition hxvector.hpp:81
hxvector(range_t_ &&range_) noexcept
Constructs by moving elements from a temporary range.
void insert(const T *it_, ref_t_ &&x_) noexcept
Inserts the element at the offset indicated.
hxvector(hxsize_t size_) noexcept
Constructs an array of a given size using T's default constructor.
hxsize_t max_size(void) const
Returns the capacity of the array or 0 if unallocated.
Definition hxvector.hpp:489
bool any_of(callable_t_ &&callable_)
const T * begin(void) const
Returns a const T* to the beginning of the array.
Definition hxvector.hpp:310
T value_or(this self_t_ &&self_, hxsize_t index_, args_t_ &&... args_)
Returns a copy of the element at index, or a T constructed from args when the index is outside the ar...
void add_range(range_t_ &&range_) noexcept
Appends elements from a temporary range by moving each element with push_back.
const T & front(void) const
Returns a const reference to the first element in the array.
void swap(hxvector &x_) noexcept
Swap contents with a temporary array.
void resize(hxsize_t size_, const T &x_) noexcept
An overload with an initial value for new elements.
void insert(hxsize_t index_, ref_t_ &&x_) noexcept
Inserts the element at the offset indicated.
T & push_back(args_t_ &&... args_) noexcept
Appends an element to the end of the array.
T & emplace_back(args_t_ &&... args_) noexcept
Emplaces an element at the end of the array using forwarded arguments.
hxsize_t capacity(void) const
Returns the capacity of the array or 0 if unallocated.
void add_range(range_t_ &range_) noexcept
Appends elements from a range referenced by an lvalue by copying each element with push_back.
void pop_back(void) noexcept
Removes the end element from the array.
void memset(int byte_=0x00)
Calls memset on the array.
void insertion_sort(void) noexcept
Sorts the array with insertion sort using hxkey_less. (Non-standard.).
bool any_of(callable_t_ &&callable_) const
Returns true if the predicate returns true for any element and false otherwise.
T * binary_search(const T &value_)
const T * find(const T &value_) const
Finds the first occurrence of value using hxkey_equal.
void generate_n(hxsize_t size_, callable_t_ &&callable_) noexcept
Appends size elements generated by invoking callable repeatedly.
void sort(void) noexcept
Sorts the array using hxkey_less. (Non-standard.).
void operator=(const other_value_t_(&array_)[array_length_]) noexcept
Assign from a C-style array.
T & push_heap(ref_t_ &&arg_) noexcept
Inserts an element into a max-heap.
~hxvector(void) noexcept
Destructs the array and destroys all elements.
T & operator[](hxsize_t index_)
void erase(T *it_) noexcept
Erases the element indicated.
const T * end(void) const
Returns a const T* to the end of the array.
Definition hxvector.hpp:348
auto and_then(this self_t_ &&self_, const T *it_, callable_t_ &&callable_) -> hxremove_cvref_t< decltype(hxforward< callable_t_ >(callable_)(hxforward_like< self_t_ >(hxdeclval< const T & >())))>
Iterator overload of and_then.
bool less(const hxvector< T, capacity_x_ > &x_) const
Returns true if this array compares less than x using hxkey_equal and hxkey_less.
const T * find_if(callable_t_ &&callable_) const
Finds the first element for which the predicate returns true.
void for_each(callable_t_ &&callable_)
void make_heap(void) noexcept
Converts the array into a max-heap using hxkey_less. (Non-standard.).
auto or_else(this self_t_ &&self_, hxsize_t index_, callable_t_ &&callable_) -> decltype(self_.end())
Returns an iterator to the element at index, or the result of calling callable when the index is outs...
void resize(hxsize_t size_) noexcept
Resizes the array to the specified size, constructing or destroying elements as needed.
bool all_of(callable_t_ &&callable_) const
Returns true if the predicate returns true for every element and false otherwise.
const T * binary_search(const T &value_) const
Performs a binary search using hxkey_less.
void erase(hxsize_t index_) noexcept
Erases the element indicated.
void assign(iter_t_ begin_, iter_t_ end_) noexcept
Assigns elements from a range defined by random access iterators.
const T * cend(void) const
Returns a const T* to the end of the array.
Definition hxvector.hpp:329
void operator+=(const T &x_) noexcept
Appends an element.
hxvector(hxvector &&x_) noexcept
Copy construct from a temporary.
T * find_if(callable_t_ &&callable_)
void reserve(hxsize_t size_, hxsystem_allocator_t allocator_=hxsystem_allocator_current, hxalignment_t alignment_=hxalignment)
Reserves storage for at least the specified number of elements.
void clear(void) noexcept
Clears the array, destroying all elements.
bool full(void) const
Returns true when the array is full (size equals capacity).
Definition hxvector.hpp:443
hxvector(const hxvector< T, capacity_x_ > &x_) noexcept
Copy constructs an array.
void operator+=(const hxvector< T, capacity_x_ > &x_) noexcept
Appends the contents of another array.
bool all_of(callable_t_ &&callable_)
T * find(const T &value_)
void operator=(hxvector &&x_) noexcept
Swap contents with a temporary array using swap.
const T & operator[](hxsize_t index_) const
Returns a const reference to the element at the specified index.
const T & back(void) const
Returns a const reference to the last element in the array.
auto and_then(this self_t_ &&self_, hxsize_t index_, callable_t_ &&callable_) -> hxremove_cvref_t< decltype(hxforward< callable_t_ >(callable_)(hxforward_like< self_t_ >(hxdeclval< T & >())))>
Returns the result of calling callable with the element at index, otherwise returns hxnil.
hxvector(void)
Constructs an empty array with a capacity of capacity.
T * iterator
Random access iterator.
Definition hxvector.hpp:84
const T * const_iterator
Const random access iterator.
Definition hxvector.hpp:87
void erase_unordered(const T *it_) noexcept
Variant of erase that moves the end element down to replace the erased element.
hxvector(const hxvector &x_) noexcept
Copy constructs an array.
void erase_unordered(hxsize_t index_) noexcept
Variant of erase that moves the end element down to replace the erased element.
hxvector(range_t_ &range_) noexcept
Constructs by copying elements from a range referenced by an lvalue.
hxsize_t erase_if_unordered(callable_t_ &&callable_) noexcept
Removes elements for which the predicate returns true.
T value_or(this self_t_ &&self_, const T *it_, args_t_ &&... args_)
Iterator overload of value_or.
const T * cbegin(void) const
Returns a const T* to the beginning of the array (alias for begin).
Definition hxvector.hpp:326
bool empty(void) const
Returns true if the array is empty.
Definition hxvector.hpp:345
hxarray_back_inserter_< hxvector< T, capacity_ > > operator*(void)
Used to write code with pointer semantics that writes to either a pointer or a hxvector.
hxvector(const other_value_t_(&array_)[array_length_]) noexcept
Constructs from a C-style array.
hxhash_t hash(void) const
Returns a hash mixing the hashes of every element in order using hxkey_hash.
hxvector(std::initializer_list< other_value_t_ > x_) noexcept
Pass values of std::initializer_list as initializers to an array of T.
T & back(void)
void operator=(const hxvector< T, capacity_x_ > &x_) noexcept
void operator+=(hxvector< T, capacity_x_ > &&x_) noexcept
Appends the contents of another array.
void for_each(callable_t_ &&callable_) const
Calls a function, lambda, or std::function on each element.
T * end(void)
Definition hxvector.hpp:350
T * begin(void)
Definition hxvector.hpp:312
bool equal(const hxvector< T, capacity_x_ > &x_) const
Returns true if the arrays compare equivalent using hxkey_equal.
hxvector(hxsize_t size_, const T &x_) noexcept
Constructs an array of a given size by making copies of x.
void pop_heap(void) noexcept
Removes the first (maximum) element from a max-heap.
void operator+=(T &&x_) noexcept
Appends an element.
void operator=(const hxvector &x_) noexcept
Assigns the contents of another hxvector to this array.
auto or_else(this self_t_ &&self_, const T *it_, callable_t_ &&callable_) -> decltype(self_.end())
Iterator overload of or_else.
hxvector & operator++(void)
Allows an array to be passed as a reference and then used as an output iterator similar to std::back_...
Definition hxvector.hpp:248
T & front(void)
void memcpy(const hxvector< T, capacity_x_ > &x_)
Copies another hxvector using memcpy.
hxvector & operator++(int)
Postfix version.
Definition hxvector.hpp:251
hxsize_t size(void) const
Returns the number of elements in the array.
Definition hxvector.hpp:564
hxsize_t size_bytes(void) const
Returns the number of bytes in the array. (Non-standard.).
Definition hxvector.hpp:567
T value_t
Publishes the value type.
Definition hxvector.hpp:90
Similar to std::allocator.
Implements or includes std::initializer_list depending on HX_USE_LIBCXX.
@ hxsystem_allocator_current
hxsystem_allocator_current - Use current allocation scope.
Definition hxmemory_manager.h:80
HX_C_BEGIN_ typedef unsigned int hxalignment_t
hxalignment_t - A positive integer power of 2 for aligning allocations.
Definition hxmemory_manager.h:62
int hxsystem_allocator_t
hxsystem_allocator_t - This is extendable by the application.
Definition hxmemory_manager.h:75
hxattr_noexcept hxsystem_allocator_t allocator_
Definition hxmemory_manager.h:120
hxattr_noexcept hxsystem_allocator_t hxalignment_t alignment_
Definition hxmemory_manager.h:121
constexpr hxalignment_t hxalignment
hxalignment - The default alignment.
Definition hxmemory_manager.h:67
Read-only range utilities for libhatchet.
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:125
#define hxattr_nonnull(...)
hxattr_nonnull - Indicates that a function has args that should not be null.
Definition hxsettings.h:106
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:98
#define hxattr_flatten
hxattr_flatten - Inline every call inside a function's body into it, recursively, regardless of the c...
Definition hxsettings.h:90
Standard sorting utilities.
constexpr bool hxis_same(void)
hxis_same<A, B> - Implements std::is_same.
Definition hxutility.h:246
constexpr T && hxforward(hxremove_reference_t< T > &&x_)
hxforward - Implements std::forward.
Definition hxutility.h:353
hxremove_cv_t< hxremove_reference_t< T > > hxremove_cvref_t
hxremove_cvref_t<T> - Returns T with const, volatile, and references removed.
Definition hxutility.h:103
constexpr bool hxis_lvalue_reference(void)
hxis_lvalue_reference<T> - Implements std::is_lvalue_reference.
Definition hxutility.h:207
T && hxdeclval(void) noexcept
hxdeclval - Implements std::declval.
constexpr hxforward_like_t_< like_t_, value_t_ > hxforward_like(value_t_ &value_)
hxforward_like<T> - Returns value with the constness and value category of T.
Definition hxutility.h:387
Provides core macros, memory management and feature detection.
constexpr hxsize_t hxsizeof(void)
hxsizeof - Returns the size of a type or expression as hxsize_t.
Definition libhatchet.h:294
uint32_t hxhash_t
hxhash_t - Unsigned 32-bit hash value. Expect collisions.
Definition libhatchet.h:210
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:207