1 #ifndef CONTAINER_SEGMENTED_VECTOR_H_
2 #define CONTAINER_SEGMENTED_VECTOR_H_
29 #include <type_traits>
50 template <
typename T,
size_t N = 512>
58 using size_type = std::size_t;
74 m_blocks.reserve(other.m_blocks.size());
75 for (
const auto& elem : other) {
78 assert(m_size == other.m_size);
79 assert(m_blocks.size() == other.m_blocks.size());
84 : m_blocks(
std::move(other.m_blocks)), m_size(other.m_size)
94 m_blocks.reserve(other.m_blocks.size());
95 for (
const auto& elem : other) {
98 assert(m_size == other.m_size);
99 assert(m_blocks.size() == other.m_blocks.size());
107 if (
this != &other) {
109 m_blocks = std::move(other.m_blocks);
110 std::swap(m_size, other.m_size);
127 T&
at(std::size_t pos)
130 throw std::out_of_range(
"CompactStorage: index out of range.");
132 const size_t b = pos / N;
133 const size_t i = pos % N;
134 return *
static_cast<T*
>(
static_cast<void*
>(&(m_blocks[b][i])));
138 const T&
at(std::size_t pos)
const
141 throw std::out_of_range(
"CompactStorage: index out of range.");
143 const size_t b = pos / N;
144 const size_t i = pos % N;
145 return *
static_cast<const T*
>(
static_cast<const void*
>(&(m_blocks[b][i])));
151 return *
static_cast<T*
>(
static_cast<void*
>(&m_blocks[(m_size-1)/N][(m_size-1)%N]));
157 return *
static_cast<const T*
>(
static_cast<const void*
>(&m_blocks[(m_size-1)/N][(m_size-1)%N]));
163 return *
static_cast<T*
>(
static_cast<void*
>(&(m_blocks[pos/N][pos%N])));
169 return *
static_cast<const T*
>(
static_cast<const void*
>(&(m_blocks[pos/N][pos%N])));
197 return iterator(iterator::m_end,
this);
225 return m_blocks.size();
247 for (
auto& i : *
this) {
250 for (
auto p : m_blocks) {
258 template <
class... Args>
261 T* memory = this->get_chunk();
262 return new (memory) T(args...);
270 throw std::logic_error(
"CompactStorage::pop_back called on empty object.");
278 const size_t last_block_index = m_blocks.size() - 1;
279 if (m_size <= last_block_index * N) {
280 delete[] m_blocks[last_block_index];
288 T* memory = get_chunk();
289 return new (memory) T(obj);
295 T* memory = get_chunk();
296 return new (memory) T(std::move(obj));
301 using Chunk =
typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
311 const size_t b = m_size / N;
312 const size_t i = m_size % N;
314 if (b == m_blocks.size()) {
315 Chunk* chunk =
new Chunk[N];
316 m_blocks.push_back(chunk);
319 return static_cast<T*
>(
static_cast<void*
>(&((m_blocks[b])[i])));
323 std::vector<Chunk*> m_blocks;
330 #endif // end_of_include_guard
T * emplace_back(Args &&...args)
Constructs element in-place at the end.
const_iterator begin() const
Returns a const_iterator to the beginning of the container.
~SegmentedVector()
Destructor.
iterator end()
Returns an iterator to the end of the container.
SegmentedVector(self_type &&other)
Move constructor.
bool empty() const
Checks whether container is empty.
T & operator[](size_t pos)
Access specified element (no bounds checking).
const_iterator end() const
Returns a const_iterator to the end of the container.
std::size_t get_block_count() const
Returns number of currently allocated blocks.
SegmentedVector(const self_type &other)
Copy constructor.
void clear()
Clears the content.
Namespace for the core simulator.
T & back()
Access the last element.
const T & back() const
Access the last element.
T * push_back(T &&obj)
Adds element to end.
const_iterator cbegin() const
Returns a const_iterator to the beginning of the container.
std::size_t size() const
Returns the number of elements.
std::size_t get_elements_per_block() const
Returns number of elements block (template parameter 'N').
T * push_back(const T &obj)
Adds element to end.
self_type & operator=(const self_type &other)
Copy assignment.
iterator begin()
Returns an iterator to the beginning of the container.
void pop_back()
Removes the last element.
const_iterator cend() const
Returns a const_iterator to the end.
Interface/Implementation for SVIterator.
T & at(std::size_t pos)
Access specified element with bounds checking.
Implementation of iterator for SegmentedVector.
SegmentedVector()
Construct.
const T & at(std::size_t pos) const
Access specified element with bounds checking.
Container that stores objects "almost contiguously" and guarantees that pointers/iterators are not in...