Changeset View
Changeset View
Standalone View
Standalone View
src/prevector.h
// Copyright (c) 2015-2016 The Bitcoin Core developers | // Copyright (c) 2015-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#ifndef BITCOIN_PREVECTOR_H | #ifndef BITCOIN_PREVECTOR_H | ||||
#define BITCOIN_PREVECTOR_H | #define BITCOIN_PREVECTOR_H | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cassert> | #include <cassert> | ||||
#include <cstddef> | #include <cstddef> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <cstdlib> | #include <cstdlib> | ||||
#include <cstring> | #include <cstring> | ||||
#include <iterator> | #include <iterator> | ||||
#include <type_traits> | #include <type_traits> | ||||
#pragma pack(push, 1) | |||||
/** | /** | ||||
* Implements a drop-in replacement for std::vector<T> which stores up to N | * Implements a drop-in replacement for std::vector<T> which stores up to N | ||||
* elements directly (without heap allocation). The types Size and Diff are used | * elements directly (without heap allocation). The types Size and Diff are used | ||||
* to store element counts, and can be any unsigned + signed type. | * to store element counts, and can be any unsigned + signed type. | ||||
* | * | ||||
* Storage layout is either: | * Storage layout is either: | ||||
* - Direct allocation: | * - Direct allocation: | ||||
* - Size _size: the number of used elements (between 0 and N) | * - Size _size: the number of used elements (between 0 and N) | ||||
▲ Show 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | public: | ||||
--(*this); | --(*this); | ||||
return copy; | return copy; | ||||
} | } | ||||
bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; } | bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; } | ||||
bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; } | bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; } | ||||
}; | }; | ||||
private: | private: | ||||
size_type _size = 0; | #pragma pack(push, 1) | ||||
union direct_or_indirect { | union direct_or_indirect { | ||||
char direct[sizeof(T) * N]; | char direct[sizeof(T) * N]; | ||||
struct { | struct { | ||||
size_type capacity; | |||||
char *indirect; | char *indirect; | ||||
size_type capacity; | |||||
}; | }; | ||||
} _union = {}; | }; | ||||
#pragma pack(pop) | |||||
alignas(char *) direct_or_indirect _union = {}; | |||||
size_type _size = 0; | |||||
static_assert(alignof(char *) % alignof(size_type) == 0 && | |||||
sizeof(char *) % alignof(size_type) == 0, | |||||
"size_type cannot have more restrictive alignment " | |||||
"requirement than pointer"); | |||||
static_assert(alignof(char *) % alignof(T) == 0, | |||||
"value_type T cannot have more restrictive alignment " | |||||
"requirement than pointer"); | |||||
T *direct_ptr(difference_type pos) { | T *direct_ptr(difference_type pos) { | ||||
return reinterpret_cast<T *>(_union.direct) + pos; | return reinterpret_cast<T *>(_union.direct) + pos; | ||||
} | } | ||||
const T *direct_ptr(difference_type pos) const { | const T *direct_ptr(difference_type pos) const { | ||||
return reinterpret_cast<const T *>(_union.direct) + pos; | return reinterpret_cast<const T *>(_union.direct) + pos; | ||||
} | } | ||||
T *indirect_ptr(difference_type pos) { | T *indirect_ptr(difference_type pos) { | ||||
▲ Show 20 Lines • Show All 325 Lines • ▼ Show 20 Lines | size_t allocated_memory() const { | ||||
return ((size_t)(sizeof(T))) * _union.capacity; | return ((size_t)(sizeof(T))) * _union.capacity; | ||||
} | } | ||||
} | } | ||||
value_type *data() { return item_ptr(0); } | value_type *data() { return item_ptr(0); } | ||||
const value_type *data() const { return item_ptr(0); } | const value_type *data() const { return item_ptr(0); } | ||||
}; | }; | ||||
#pragma pack(pop) | |||||
#endif // BITCOIN_PREVECTOR_H | #endif // BITCOIN_PREVECTOR_H |