5 #ifndef BITCOIN_PREVECTOR_H 6 #define BITCOIN_PREVECTOR_H 15 #include <type_traits> 36 template<
unsigned int N,
typename T,
typename Size = u
int32_t,
typename Diff =
int32_t>
38 static_assert(std::is_trivially_copyable_v<T>);
107 #pragma pack(push, 1) 116 alignas(
char*) direct_or_indirect
_union = {};
119 static_assert(
alignof(
char*) %
alignof(
size_type) == 0 &&
sizeof(
char*) %
alignof(
size_type) == 0,
"size_type cannot have more restrictive alignment requirement than pointer");
120 static_assert(
alignof(
char*) %
alignof(
T) == 0,
"value_type T cannot have more restrictive alignment requirement than pointer");
129 if (new_capacity <= N) {
147 char* new_indirect =
static_cast<char*
>(malloc(((
size_t)
sizeof(
T)) * new_capacity));
150 T* dst =
reinterpret_cast<T*
>(new_indirect);
163 std::fill_n(dst,
count, value);
166 template <std::input_iterator InputIterator>
167 void fill(
T* dst, InputIterator first, InputIterator last) {
168 while (first != last) {
169 new(
static_cast<void*
>(dst))
T(*first);
185 template <std::input_iterator InputIterator>
186 void assign(InputIterator first, InputIterator last) {
208 template <std::input_iterator InputIterator>
224 :
_union(std::move(other._union)),
_size(other._size)
230 if (&other ==
this) {
241 _union = std::move(other._union);
278 if (cur_size == new_size) {
281 if (cur_size > new_size) {
288 ptrdiff_t increase = new_size - cur_size;
307 iterator
insert(iterator pos,
const T& value) {
315 memmove(dst, ptr, (
size() - p) *
sizeof(
T));
317 new(
static_cast<void*
>(ptr))
T(value);
318 return iterator(ptr);
329 memmove(dst, ptr, (
size() - p) *
sizeof(
T));
334 template <std::input_iterator InputIterator>
335 void insert(iterator pos, InputIterator first, InputIterator last) {
344 memmove(dst, ptr, (
size() - p) *
sizeof(
T));
346 fill(ptr, first, last);
357 if (new_size <
size()) {
365 return erase(pos, pos + 1);
368 iterator
erase(iterator first, iterator last) {
376 char* endp = (
char*)&(*
end());
378 memmove(&(*first), &(*last), endp - ((
char*)(&(*last))));
382 template<
typename... Args>
418 std::swap(
_union, other._union);
419 std::swap(
_size, other._size);
433 const_iterator b1 =
begin();
434 const_iterator b2 = other.
begin();
435 const_iterator e1 =
end();
437 if ((*b1) != (*b2)) {
446 bool operator<(const prevector<N, T, Size, Diff>& other)
const {
447 if (
size() < other.size()) {
450 if (
size() > other.size()) {
453 const_iterator b1 =
begin();
454 const_iterator b2 = other.begin();
455 const_iterator e1 =
end();
486 #endif // BITCOIN_PREVECTOR_H T * direct_ptr(difference_type pos)
struct prevector::direct_or_indirect::@2 indirect_contents
prevector & operator=(const prevector< N, T, Size, Diff > &other)
const value_type & const_reference
const_iterator operator--(int)
void resize(size_type new_size)
const value_type * const_pointer
void assign(size_type n, const T &val)
T * indirect_ptr(difference_type pos)
prevector & operator=(prevector< N, T, Size, Diff > &&other) noexcept
void assign(InputIterator first, InputIterator last)
iterator insert(iterator pos, const T &value)
const T & operator[](size_type pos) const
const_iterator & operator-=(size_type n)
const_iterator & operator++()
void insert(iterator pos, InputIterator first, InputIterator last)
void fill(T *dst, InputIterator first, InputIterator last)
const value_type * data() const
const T * direct_ptr(difference_type pos) const
size_t allocated_memory() const
prevector(prevector< N, T, Size, Diff > &&other) noexcept
void swap(prevector< N, T, Size, Diff > &other) noexcept
memcpy(result.begin(), stream.data(), stream.size())
bool operator==(const prevector< N, T, Size, Diff > &other) const
void resize_uninitialized(size_type new_size)
const_iterator friend operator+(size_type n, const_iterator x)
prevector(const prevector< N, T, Size, Diff > &other)
direct_or_indirect _union
void fill(T *dst, ptrdiff_t count, const T &value=T{})
const T * item_ptr(difference_type pos) const
static constexpr unsigned int STATIC_SIZE
void push_back(const T &value)
const T & operator*() const
T & operator[](size_type pos)
void insert(iterator pos, size_type count, const T &value)
iterator friend operator+(size_type n, iterator x)
bool operator==(iterator x) const
char direct[sizeof(T) *N]
iterator & operator+=(size_type n)
iterator erase(iterator pos)
T & operator[](size_type pos) const
std::contiguous_iterator_tag iterator_category
const T & operator[](size_type pos) const
const_iterator operator+(size_type n) const
const_iterator(iterator x)
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
iterator operator+(size_type n) const
const_iterator & operator--()
void reserve(size_type new_capacity)
const T * operator->() const
iterator operator-(size_type n) const
void change_capacity(size_type new_capacity)
prevector(InputIterator first, InputIterator last)
T * item_ptr(difference_type pos)
const_iterator operator++(int)
iterator erase(iterator first, iterator last)
difference_type friend operator-(iterator a, iterator b)
const T * indirect_ptr(difference_type pos) const
prevector(size_type n, const T &val)
const_iterator end() const
iterator & operator-=(size_type n)
const_iterator begin() const
bool operator==(const_iterator x) const
const_iterator & operator+=(size_type n)
const_iterator(const T *ptr_)
std::contiguous_iterator_tag iterator_category
const_iterator operator-(size_type n) const
void emplace_back(Args &&... args)
difference_type friend operator-(const_iterator a, const_iterator b)