move BinaryHeap to C++11

This commit is contained in:
Dennis Luxen 2014-05-05 16:21:41 +02:00
parent 3ca9420801
commit 5b22dffa6f
2 changed files with 408 additions and 342 deletions

View File

@ -28,273 +28,262 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BINARY_HEAP_H
#define BINARY_HEAP_H
//Not compatible with non contiguous node ids
#include <boost/unordered_map.hpp>
#include <boost/assert.hpp>
#include <algorithm>
#include <limits>
#include <map>
#include <type_traits>
#include <unordered_map>
#include <vector>
template< typename NodeID, typename Key >
class ArrayStorage {
public:
explicit ArrayStorage( size_t size ) : positions( new Key[size] ) {
memset(positions, 0, size*sizeof(Key));
template <typename NodeID, typename Key> class ArrayStorage
{
public:
explicit ArrayStorage(size_t size) : positions(new Key[size])
{
memset(positions, 0, size * sizeof(Key));
}
~ArrayStorage() {
delete[] positions;
}
~ArrayStorage() { delete[] positions; }
Key &operator[]( NodeID node ) {
return positions[node];
}
Key &operator[](NodeID node) { return positions[node]; }
void Clear() {}
private:
Key* positions;
private:
Key *positions;
};
template< typename NodeID, typename Key >
class MapStorage {
public:
template <typename NodeID, typename Key> class MapStorage
{
public:
explicit MapStorage(size_t) {}
explicit MapStorage( size_t ) {}
Key &operator[](NodeID node) { return nodes[node]; }
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
std::map< NodeID, Key > nodes;
void Clear() { nodes.clear(); }
private:
std::map<NodeID, Key> nodes;
};
template< typename NodeID, typename Key >
class UnorderedMapStorage {
typedef boost::unordered_map<NodeID, Key> UnorderedMapType;
typedef typename UnorderedMapType::iterator UnorderedMapIterator;
typedef typename UnorderedMapType::const_iterator UnorderedMapConstIterator;
public:
template <typename NodeID, typename Key> class UnorderedMapStorage
{
public:
explicit UnorderedMapStorage(size_t) { nodes.rehash(1000); }
explicit UnorderedMapStorage( size_t ) {
//hash table gets 1000 Buckets
nodes.rehash(1000);
}
Key &operator[](const NodeID node) { return nodes[node]; }
Key & operator[]( const NodeID node ) {
return nodes[node];
}
Key const & operator[]( const NodeID node ) const {
UnorderedMapConstIterator iter = nodes.find(node);
Key const &operator[](const NodeID node) const
{
auto iter = nodes.find(node);
return iter->second;
}
void Clear() {
nodes.clear();
}
void Clear() { nodes.clear(); }
private:
boost::unordered_map< NodeID, Key > nodes;
private:
std::unordered_map<NodeID, Key> nodes;
};
template<
typename NodeID,
template <typename NodeID,
typename Key,
typename Weight,
typename Data,
typename IndexStorage = ArrayStorage<NodeID, NodeID>
>
class BinaryHeap {
private:
BinaryHeap( const BinaryHeap& right );
void operator=( const BinaryHeap& right );
public:
typename IndexStorage = ArrayStorage<NodeID, NodeID>>
class BinaryHeap
{
private:
BinaryHeap(const BinaryHeap &right);
void operator=(const BinaryHeap &right);
public:
typedef Weight WeightType;
typedef Data DataType;
explicit BinaryHeap( size_t maxID )
:
nodeIndex( maxID )
explicit BinaryHeap(size_t maxID) : node_index(maxID) { Clear(); }
void Clear()
{
Clear();
heap.resize(1);
inserted_nodes.clear();
heap[0].weight = std::numeric_limits<Weight>::min();
node_index.Clear();
}
void Clear() {
heap.resize( 1 );
insertedNodes.clear();
heap[0].weight = std::numeric_limits< Weight >::min();
nodeIndex.Clear();
}
std::size_t Size() const { return (heap.size() - 1); }
Key Size() const {
return static_cast<Key>( heap.size() - 1 );
}
bool Empty() const { return 0 == Size(); }
bool Empty() const {
return 0 == Size();
}
void Insert( NodeID node, Weight weight, const Data &data ) {
void Insert(NodeID node, Weight weight, const Data &data)
{
HeapElement element;
element.index = static_cast<NodeID>(insertedNodes.size());
element.index = static_cast<NodeID>(inserted_nodes.size());
element.weight = weight;
const Key key = static_cast<Key>(heap.size());
heap.push_back( element );
insertedNodes.push_back( HeapNode( node, key, weight, data ) );
nodeIndex[node] = element.index;
Upheap( key );
heap.emplace_back(element);
inserted_nodes.emplace_back(node, key, weight, data);
node_index[node] = element.index;
Upheap(key);
CheckHeap();
}
Data& GetData( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
Data &GetData(NodeID node)
{
const Key index = node_index[node];
return inserted_nodes[index].data;
}
Data const & GetData( NodeID node ) const {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
Data const &GetData(NodeID node) const
{
const Key index = node_index[node];
return inserted_nodes[index].data;
}
Weight& GetKey( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].weight;
Weight &GetKey(NodeID node)
{
const Key index = node_index[node];
return inserted_nodes[index].weight;
}
bool WasRemoved( const NodeID node ) {
BOOST_ASSERT( WasInserted( node ) );
const Key index = nodeIndex[node];
return insertedNodes[index].key == 0;
bool WasRemoved(const NodeID node)
{
BOOST_ASSERT(WasInserted(node));
const Key index = node_index[node];
return inserted_nodes[index].key == 0;
}
bool WasInserted( const NodeID node ) {
const Key index = nodeIndex[node];
if ( index >= static_cast<Key> (insertedNodes.size()) )
bool WasInserted(const NodeID node)
{
const Key index = node_index[node];
if (index >= static_cast<Key>(inserted_nodes.size()))
{
return false;
return insertedNodes[index].node == node;
}
return inserted_nodes[index].node == node;
}
NodeID Min() const {
BOOST_ASSERT( heap.size() > 1 );
return insertedNodes[heap[1].index].node;
NodeID Min() const
{
BOOST_ASSERT(heap.size() > 1);
return inserted_nodes[heap[1].index].node;
}
NodeID DeleteMin() {
BOOST_ASSERT( heap.size() > 1 );
NodeID DeleteMin()
{
BOOST_ASSERT(heap.size() > 1);
const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1];
heap[1] = heap[heap.size() - 1];
heap.pop_back();
if ( heap.size() > 1 )
Downheap( 1 );
insertedNodes[removedIndex].key = 0;
if (heap.size() > 1)
{
Downheap(1);
}
inserted_nodes[removedIndex].key = 0;
CheckHeap();
return insertedNodes[removedIndex].node;
return inserted_nodes[removedIndex].node;
}
void DeleteAll() {
for ( typename std::vector< HeapElement >::iterator i = heap.begin() + 1, iend = heap.end(); i != iend; ++i )
insertedNodes[i->index].key = 0;
heap.resize( 1 );
heap[0].weight = (std::numeric_limits< Weight >::min)();
void DeleteAll()
{
auto iend = heap.end();
for (typename std::vector<HeapElement>::iterator i = heap.begin() + 1; i != iend; ++i)
{
inserted_nodes[i->index].key = 0;
}
heap.resize(1);
heap[0].weight = (std::numeric_limits<Weight>::min)();
}
void DecreaseKey( NodeID node, Weight weight ) {
BOOST_ASSERT( UINT_MAX != node );
const Key & index = nodeIndex[node];
Key & key = insertedNodes[index].key;
BOOST_ASSERT ( key >= 0 );
void DecreaseKey(NodeID node, Weight weight)
{
BOOST_ASSERT(UINT_MAX != node);
const Key &index = node_index[node];
Key &key = inserted_nodes[index].key;
BOOST_ASSERT(key >= 0);
insertedNodes[index].weight = weight;
inserted_nodes[index].weight = weight;
heap[key].weight = weight;
Upheap( key );
Upheap(key);
CheckHeap();
}
private:
class HeapNode {
private:
class HeapNode
{
public:
HeapNode( NodeID n, Key k, Weight w, Data d )
:
node(n),
key(k),
weight(w),
data(d)
{ }
HeapNode(NodeID n, Key k, Weight w, Data d) : node(n), key(k), weight(w), data(d) {}
NodeID node;
Key key;
Weight weight;
Data data;
};
struct HeapElement {
struct HeapElement
{
Key index;
Weight weight;
};
std::vector< HeapNode > insertedNodes;
std::vector< HeapElement > heap;
IndexStorage nodeIndex;
std::vector<HeapNode> inserted_nodes;
std::vector<HeapElement> heap;
IndexStorage node_index;
void Downheap( Key key ) {
void Downheap(Key key)
{
const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key << 1;
while( nextKey < static_cast<Key>( heap.size() ) ){
while (nextKey < static_cast<Key>(heap.size()))
{
const Key nextKeyOther = nextKey + 1;
if (
( nextKeyOther < static_cast<Key>( heap.size() ) ) &&
( heap[nextKey].weight > heap[nextKeyOther].weight )
) {
if ((nextKeyOther < static_cast<Key>(heap.size())) &&
(heap[nextKey].weight > heap[nextKeyOther].weight))
{
nextKey = nextKeyOther;
}
if ( weight <= heap[nextKey].weight ){
if (weight <= heap[nextKey].weight)
{
break;
}
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
inserted_nodes[heap[key].index].key = key;
key = nextKey;
nextKey <<= 1;
}
heap[key].index = droppingIndex;
heap[key].weight = weight;
insertedNodes[droppingIndex].key = key;
inserted_nodes[droppingIndex].key = key;
}
void Upheap( Key key ) {
void Upheap(Key key)
{
const Key risingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) {
BOOST_ASSERT( nextKey != 0 );
while (heap[nextKey].weight > weight)
{
BOOST_ASSERT(nextKey != 0);
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
inserted_nodes[heap[key].index].key = key;
key = nextKey;
nextKey >>= 1;
}
heap[key].index = risingIndex;
heap[key].weight = weight;
insertedNodes[risingIndex].key = key;
inserted_nodes[risingIndex].key = key;
}
void CheckHeap() {
void CheckHeap()
{
#ifndef NDEBUG
for ( Key i = 2; i < (Key) heap.size(); ++i ) {
BOOST_ASSERT( heap[i].weight >= heap[i >> 1].weight );
for (Key i = 2; i < (Key)heap.size(); ++i)
{
BOOST_ASSERT(heap[i].weight >= heap[i >> 1].weight);
}
#endif
}
};
#endif //BINARY_HEAP_H
#endif // BINARY_HEAP_H

View File

@ -32,292 +32,369 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstring>
#include <vector>
#if __cplusplus > 199711L
#define DEALLOCATION_VECTOR_NULL_PTR nullptr
#else
#define DEALLOCATION_VECTOR_NULL_PTR NULL
#endif
template<typename ElementT, std::size_t bucketSizeC = 8388608/sizeof(ElementT), bool DeallocateC = false>
class DeallocatingVectorIterator : public std::iterator<std::random_access_iterator_tag, ElementT> {
protected:
class DeallocatingVectorIteratorState {
template <typename ElementT,
std::size_t bucketSizeC = 8388608 / sizeof(ElementT),
bool DeallocateC = false>
class DeallocatingVectorIterator : public std::iterator<std::random_access_iterator_tag, ElementT>
{
protected:
class DeallocatingVectorIteratorState
{
private:
//make constructors explicit, so we do not mix random access and deallocation iterators.
// make constructors explicit, so we do not mix random access and deallocation iterators.
DeallocatingVectorIteratorState();
public:
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : /*mData(r.mData),*/ mIndex(r.mIndex), mBucketList(r.mBucketList) {}
explicit DeallocatingVectorIteratorState(const std::size_t idx, std::vector<ElementT *> & input_list) : /*mData(DEALLOCATION_VECTOR_NULL_PTR),*/ mIndex(idx), mBucketList(input_list) {
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
: index(r.index), bucket_list(r.bucket_list)
{
}
std::size_t mIndex;
std::vector<ElementT *> & mBucketList;
explicit DeallocatingVectorIteratorState(const std::size_t idx,
std::vector<ElementT *> &input_list)
: index(idx), bucket_list(input_list)
{
}
std::size_t index;
std::vector<ElementT *> &bucket_list;
inline bool operator!=(const DeallocatingVectorIteratorState &other) {
return mIndex != other.mIndex;
inline bool operator!=(const DeallocatingVectorIteratorState &other)
{
return index != other.index;
}
inline bool operator==(const DeallocatingVectorIteratorState &other) {
return mIndex == other.mIndex;
inline bool operator==(const DeallocatingVectorIteratorState &other)
{
return index == other.index;
}
bool operator<(const DeallocatingVectorIteratorState &other) const {
return mIndex < other.mIndex;
bool operator<(const DeallocatingVectorIteratorState &other) const
{
return index < other.index;
}
bool operator>(const DeallocatingVectorIteratorState &other) const {
return mIndex > other.mIndex;
bool operator>(const DeallocatingVectorIteratorState &other) const
{
return index > other.index;
}
bool operator>=(const DeallocatingVectorIteratorState &other) const {
return mIndex >= other.mIndex;
bool operator>=(const DeallocatingVectorIteratorState &other) const
{
return index >= other.index;
}
//This is a hack to make assignment operator possible with reference member
inline DeallocatingVectorIteratorState& operator= (const DeallocatingVectorIteratorState &a) {
if (this != &a) {
this->DeallocatingVectorIteratorState::~DeallocatingVectorIteratorState(); // explicit non-virtual destructor
// This is a hack to make assignment operator possible with reference member
inline DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &a)
{
if (this != &a)
{
this->DeallocatingVectorIteratorState::
~DeallocatingVectorIteratorState(); // explicit non-virtual destructor
new (this) DeallocatingVectorIteratorState(a); // placement new
}
return *this;
}
};
DeallocatingVectorIteratorState mState;
DeallocatingVectorIteratorState current_state;
public:
public:
typedef std::random_access_iterator_tag iterator_category;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::value_type value_type;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::difference_type difference_type;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::value_type
value_type;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::difference_type
difference_type;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::reference reference;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::pointer pointer;
DeallocatingVectorIterator() {}
template<typename T2>
explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {}
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
explicit DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
template<typename T2>
DeallocatingVectorIterator& operator=(const DeallocatingVectorIterator<T2> &r) {
if(DeallocateC) BOOST_ASSERT(false);
mState = r.mState; return *this;
template <typename T2>
explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> &r)
: current_state(r.current_state)
{
}
inline DeallocatingVectorIterator& operator++() { //prefix
++mState.mIndex;
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> &input_list)
: current_state(idx, input_list)
{
}
explicit DeallocatingVectorIterator(const DeallocatingVectorIteratorState &r) : current_state(r) {}
template <typename T2>
DeallocatingVectorIterator &operator=(const DeallocatingVectorIterator<T2> &r)
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
current_state = r.current_state;
return *this;
}
inline DeallocatingVectorIterator& operator--() { //prefix
if(DeallocateC) BOOST_ASSERT(false);
--mState.mIndex;
inline DeallocatingVectorIterator &operator++()
{ // prefix
++current_state.index;
return *this;
}
inline DeallocatingVectorIterator operator++(int) { //postfix
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex++;
return DeallocatingVectorIterator(_myState);
inline DeallocatingVectorIterator &operator--()
{ // prefix
if (DeallocateC)
{
BOOST_ASSERT(false);
}
inline DeallocatingVectorIterator operator--(int) { //postfix
if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex--;
return DeallocatingVectorIterator(_myState);
--current_state.index;
return *this;
}
inline DeallocatingVectorIterator operator+(const difference_type& n) const {
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex+=n;
return DeallocatingVectorIterator(_myState);
inline DeallocatingVectorIterator operator++(int)
{ // postfix
DeallocatingVectorIteratorState my_state(current_state);
current_state.index++;
return DeallocatingVectorIterator(my_state);
}
inline DeallocatingVectorIterator operator--(int)
{ // postfix
if (DeallocateC)
{
BOOST_ASSERT(false);
}
DeallocatingVectorIteratorState my_state(current_state);
current_state.index--;
return DeallocatingVectorIterator(my_state);
}
inline DeallocatingVectorIterator& operator+=(const difference_type& n) {
mState.mIndex+=n; return *this;
inline DeallocatingVectorIterator operator+(const difference_type &n) const
{
DeallocatingVectorIteratorState my_state(current_state);
my_state.index += n;
return DeallocatingVectorIterator(my_state);
}
inline DeallocatingVectorIterator operator-(const difference_type& n) const {
if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex-=n;
return DeallocatingVectorIterator(_myState);
inline DeallocatingVectorIterator &operator+=(const difference_type &n)
{
current_state.index += n;
return *this;
}
inline DeallocatingVectorIterator& operator-=(const difference_type &n) const {
if(DeallocateC) BOOST_ASSERT(false);
mState.mIndex-=n; return *this;
inline DeallocatingVectorIterator operator-(const difference_type &n) const
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
DeallocatingVectorIteratorState my_state(current_state);
my_state.index -= n;
return DeallocatingVectorIterator(my_state);
}
inline reference operator*() const {
std::size_t _bucket = mState.mIndex/bucketSizeC;
std::size_t _index = mState.mIndex%bucketSizeC;
return (mState.mBucketList[_bucket][_index]);
inline DeallocatingVectorIterator &operator-=(const difference_type &n) const
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
current_state.index -= n;
return *this;
}
inline pointer operator->() const {
std::size_t _bucket = mState.mIndex/bucketSizeC;
std::size_t _index = mState.mIndex%bucketSizeC;
return &(mState.mBucketList[_bucket][_index]);
inline reference operator*() const
{
std::size_t current_bucket = current_state.index / bucketSizeC;
std::size_t current_index = current_state.index % bucketSizeC;
return (current_state.bucket_list[current_bucket][current_index]);
}
inline bool operator!=(const DeallocatingVectorIterator & other) {
return mState != other.mState;
inline pointer operator->() const
{
std::size_t current_bucket = current_state.index / bucketSizeC;
std::size_t current_index = current_state.index % bucketSizeC;
return &(current_state.bucket_list[current_bucket][current_index]);
}
inline bool operator==(const DeallocatingVectorIterator & other) {
return mState == other.mState;
inline bool operator!=(const DeallocatingVectorIterator &other)
{
return current_state != other.current_state;
}
inline bool operator<(const DeallocatingVectorIterator & other) const {
return mState < other.mState;
inline bool operator==(const DeallocatingVectorIterator &other)
{
return current_state == other.current_state;
}
inline bool operator>(const DeallocatingVectorIterator & other) const {
return mState > other.mState;
inline bool operator<(const DeallocatingVectorIterator &other) const
{
return current_state < other.current_state;
}
inline bool operator>=(const DeallocatingVectorIterator & other) const {
return mState >= other.mState;
inline bool operator>(const DeallocatingVectorIterator &other) const
{
return current_state > other.current_state;
}
difference_type operator-(const DeallocatingVectorIterator & other) {
if(DeallocateC) BOOST_ASSERT(false);
return mState.mIndex-other.mState.mIndex;
inline bool operator>=(const DeallocatingVectorIterator &other) const
{
return current_state >= other.current_state;
}
difference_type operator-(const DeallocatingVectorIterator &other)
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
return current_state.index - other.current_state.index;
}
};
template<typename ElementT, std::size_t bucketSizeC = 8388608/sizeof(ElementT) >
class DeallocatingVector {
private:
std::size_t mCurrentSize;
std::vector<ElementT *> mBucketList;
template <typename ElementT, std::size_t bucketSizeC = 8388608 / sizeof(ElementT)>
class DeallocatingVector
{
private:
std::size_t current_size;
std::vector<ElementT *> bucket_list;
public:
public:
typedef ElementT value_type;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> iterator;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> const_iterator;
//this iterator deallocates all buckets that have been visited. Iterators to visited objects become invalid.
// this iterator deallocates all buckets that have been visited. Iterators to visited objects
// become invalid.
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, true> deallocation_iterator;
DeallocatingVector() : mCurrentSize(0) {
//initial bucket
mBucketList.push_back(new ElementT[bucketSizeC]);
DeallocatingVector() : current_size(0)
{
// initial bucket
bucket_list.emplace_back(new ElementT[bucketSizeC]);
}
~DeallocatingVector() {
clear();
~DeallocatingVector() { clear(); }
inline void swap(DeallocatingVector<ElementT, bucketSizeC> &other)
{
std::swap(current_size, other.current_size);
bucket_list.swap(other.bucket_list);
}
inline void swap(DeallocatingVector<ElementT, bucketSizeC> & other) {
std::swap(mCurrentSize, other.mCurrentSize);
mBucketList.swap(other.mBucketList);
inline void clear()
{
// Delete[]'ing ptr's to all Buckets
for (unsigned i = 0; i < bucket_list.size(); ++i)
{
if (nullptr != bucket_list[i])
{
delete[] bucket_list[i];
bucket_list[i] = nullptr;
}
}
// Removing all ptrs from vector
std::vector<ElementT *>().swap(bucket_list);
current_size = 0;
}
inline void clear() {
//Delete[]'ing ptr's to all Buckets
for(unsigned i = 0; i < mBucketList.size(); ++i) {
if(DEALLOCATION_VECTOR_NULL_PTR != mBucketList[i]) {
delete[] mBucketList[i];
mBucketList[i] = DEALLOCATION_VECTOR_NULL_PTR;
}
}
//Removing all ptrs from vector
std::vector<ElementT *>().swap(mBucketList);
mCurrentSize = 0;
inline void push_back(const ElementT &element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
}
inline void push_back(const ElementT & element) {
std::size_t _capacity = capacity();
if(mCurrentSize == _capacity) {
mBucketList.push_back(new ElementT[bucketSizeC]);
std::size_t current_index = size() % bucketSizeC;
bucket_list.back()[current_index] = element;
++current_size;
}
std::size_t _index = size()%bucketSizeC;
mBucketList.back()[_index] = element;
++mCurrentSize;
inline void emplace_back(const ElementT &&element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
}
inline void reserve(const std::size_t) const {
//don't do anything
const std::size_t current_index = size() % bucketSizeC;
bucket_list.back()[current_index] = element;
++current_size;
}
inline void resize(const std::size_t new_size) {
if(new_size > mCurrentSize) {
while(capacity() < new_size) {
mBucketList.push_back(new ElementT[bucketSizeC]);
inline void reserve(const std::size_t) const
{
// don't do anything
}
mCurrentSize = new_size;
}
if(new_size < mCurrentSize) {
std::size_t number_of_necessary_buckets = 1+(new_size / bucketSizeC);
for(unsigned i = number_of_necessary_buckets; i < mBucketList.size(); ++i) {
delete[] mBucketList[i];
inline void resize(const std::size_t new_size)
{
if (new_size > current_size)
{
while (capacity() < new_size)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
}
mBucketList.resize(number_of_necessary_buckets);
mCurrentSize = new_size;
current_size = new_size;
}
if (new_size < current_size)
{
const std::size_t number_of_necessary_buckets = 1 + (new_size / bucketSizeC);
for (unsigned i = number_of_necessary_buckets; i < bucket_list.size(); ++i)
{
delete[] bucket_list[i];
}
bucket_list.resize(number_of_necessary_buckets);
current_size = new_size;
}
}
inline std::size_t size() const {
return mCurrentSize;
inline std::size_t size() const { return current_size; }
inline std::size_t capacity() const { return bucket_list.size() * bucketSizeC; }
inline iterator begin() { return iterator(static_cast<std::size_t>(0), bucket_list); }
inline iterator end() { return iterator(size(), bucket_list); }
inline deallocation_iterator dbegin()
{
return deallocation_iterator(static_cast<std::size_t>(0), bucket_list);
}
inline std::size_t capacity() const {
return mBucketList.size() * bucketSizeC;
inline deallocation_iterator dend() { return deallocation_iterator(size(), bucket_list); }
inline const_iterator begin() const
{
return const_iterator(static_cast<std::size_t>(0), bucket_list);
}
inline iterator begin() {
return iterator(static_cast<std::size_t>(0), mBucketList);
}
inline const_iterator end() const { return const_iterator(size(), bucket_list); }
inline iterator end() {
return iterator(size(), mBucketList);
}
inline deallocation_iterator dbegin() {
return deallocation_iterator(static_cast<std::size_t>(0), mBucketList);
}
inline deallocation_iterator dend() {
return deallocation_iterator(size(), mBucketList);
}
inline const_iterator begin() const {
return const_iterator(static_cast<std::size_t>(0), mBucketList);
}
inline const_iterator end() const {
return const_iterator(size(), mBucketList);
}
inline ElementT & operator[](const std::size_t index) {
inline ElementT &operator[](const std::size_t index)
{
std::size_t _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC;
return (mBucketList[_bucket][_index]);
return (bucket_list[_bucket][_index]);
}
const inline ElementT & operator[](const std::size_t index) const {
const inline ElementT &operator[](const std::size_t index) const
{
std::size_t _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC;
return (mBucketList[_bucket][_index]);
return (bucket_list[_bucket][_index]);
}
inline ElementT & back() {
std::size_t _bucket = mCurrentSize / bucketSizeC;
std::size_t _index = mCurrentSize % bucketSizeC;
return (mBucketList[_bucket][_index]);
inline ElementT &back()
{
std::size_t _bucket = current_size / bucketSizeC;
std::size_t _index = current_size % bucketSizeC;
return (bucket_list[_bucket][_index]);
}
const inline ElementT & back() const {
std::size_t _bucket = mCurrentSize / bucketSizeC;
std::size_t _index = mCurrentSize % bucketSizeC;
return (mBucketList[_bucket][_index]);
const inline ElementT &back() const
{
std::size_t _bucket = current_size / bucketSizeC;
std::size_t _index = current_size % bucketSizeC;
return (bucket_list[_bucket][_index]);
}
};