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 #ifndef BINARY_HEAP_H
#define BINARY_HEAP_H #define BINARY_HEAP_H
//Not compatible with non contiguous node ids
#include <boost/unordered_map.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <map> #include <map>
#include <type_traits>
#include <unordered_map>
#include <vector> #include <vector>
template< typename NodeID, typename Key > template <typename NodeID, typename Key> class ArrayStorage
class ArrayStorage { {
public: public:
explicit ArrayStorage(size_t size) : positions(new Key[size])
explicit ArrayStorage( size_t size ) : positions( new Key[size] ) { {
memset(positions, 0, size*sizeof(Key)); memset(positions, 0, size * sizeof(Key));
} }
~ArrayStorage() { ~ArrayStorage() { delete[] positions; }
delete[] positions;
}
Key &operator[]( NodeID node ) { Key &operator[](NodeID node) { return positions[node]; }
return positions[node];
}
void Clear() {} void Clear() {}
private: private:
Key* positions; Key *positions;
}; };
template< typename NodeID, typename Key > template <typename NodeID, typename Key> class MapStorage
class MapStorage { {
public: public:
explicit MapStorage(size_t) {}
explicit MapStorage( size_t ) {} Key &operator[](NodeID node) { return nodes[node]; }
Key &operator[]( NodeID node ) { void Clear() { nodes.clear(); }
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
std::map< NodeID, Key > nodes;
private:
std::map<NodeID, Key> nodes;
}; };
template< typename NodeID, typename Key > template <typename NodeID, typename Key> class UnorderedMapStorage
class UnorderedMapStorage { {
typedef boost::unordered_map<NodeID, Key> UnorderedMapType; public:
typedef typename UnorderedMapType::iterator UnorderedMapIterator; explicit UnorderedMapStorage(size_t) { nodes.rehash(1000); }
typedef typename UnorderedMapType::const_iterator UnorderedMapConstIterator;
public:
explicit UnorderedMapStorage( size_t ) { Key &operator[](const NodeID node) { return nodes[node]; }
//hash table gets 1000 Buckets
nodes.rehash(1000);
}
Key & operator[]( const NodeID node ) { Key const &operator[](const NodeID node) const
return nodes[node]; {
} auto iter = nodes.find(node);
Key const & operator[]( const NodeID node ) const {
UnorderedMapConstIterator iter = nodes.find(node);
return iter->second; return iter->second;
} }
void Clear() { void Clear() { nodes.clear(); }
nodes.clear();
}
private: private:
boost::unordered_map< NodeID, Key > nodes; std::unordered_map<NodeID, Key> nodes;
}; };
template< template <typename NodeID,
typename NodeID,
typename Key, typename Key,
typename Weight, typename Weight,
typename Data, typename Data,
typename IndexStorage = ArrayStorage<NodeID, NodeID> typename IndexStorage = ArrayStorage<NodeID, NodeID>>
> class BinaryHeap
class BinaryHeap { {
private: private:
BinaryHeap( const BinaryHeap& right ); BinaryHeap(const BinaryHeap &right);
void operator=( const BinaryHeap& right ); void operator=(const BinaryHeap &right);
public:
public:
typedef Weight WeightType; typedef Weight WeightType;
typedef Data DataType; typedef Data DataType;
explicit BinaryHeap( size_t maxID ) explicit BinaryHeap(size_t maxID) : node_index(maxID) { Clear(); }
:
nodeIndex( maxID ) void Clear()
{ {
Clear(); heap.resize(1);
inserted_nodes.clear();
heap[0].weight = std::numeric_limits<Weight>::min();
node_index.Clear();
} }
void Clear() { std::size_t Size() const { return (heap.size() - 1); }
heap.resize( 1 );
insertedNodes.clear();
heap[0].weight = std::numeric_limits< Weight >::min();
nodeIndex.Clear();
}
Key Size() const { bool Empty() const { return 0 == Size(); }
return static_cast<Key>( heap.size() - 1 );
}
bool Empty() const { void Insert(NodeID node, Weight weight, const Data &data)
return 0 == Size(); {
}
void Insert( NodeID node, Weight weight, const Data &data ) {
HeapElement element; HeapElement element;
element.index = static_cast<NodeID>(insertedNodes.size()); element.index = static_cast<NodeID>(inserted_nodes.size());
element.weight = weight; element.weight = weight;
const Key key = static_cast<Key>(heap.size()); const Key key = static_cast<Key>(heap.size());
heap.push_back( element ); heap.emplace_back(element);
insertedNodes.push_back( HeapNode( node, key, weight, data ) ); inserted_nodes.emplace_back(node, key, weight, data);
nodeIndex[node] = element.index; node_index[node] = element.index;
Upheap( key ); Upheap(key);
CheckHeap(); CheckHeap();
} }
Data& GetData( NodeID node ) { Data &GetData(NodeID node)
const Key index = nodeIndex[node]; {
return insertedNodes[index].data; const Key index = node_index[node];
return inserted_nodes[index].data;
} }
Data const & GetData( NodeID node ) const { Data const &GetData(NodeID node) const
const Key index = nodeIndex[node]; {
return insertedNodes[index].data; const Key index = node_index[node];
return inserted_nodes[index].data;
} }
Weight& GetKey( NodeID node ) { Weight &GetKey(NodeID node)
const Key index = nodeIndex[node]; {
return insertedNodes[index].weight; const Key index = node_index[node];
return inserted_nodes[index].weight;
} }
bool WasRemoved( const NodeID node ) { bool WasRemoved(const NodeID node)
BOOST_ASSERT( WasInserted( node ) ); {
const Key index = nodeIndex[node]; BOOST_ASSERT(WasInserted(node));
return insertedNodes[index].key == 0; const Key index = node_index[node];
return inserted_nodes[index].key == 0;
} }
bool WasInserted( const NodeID node ) { bool WasInserted(const NodeID node)
const Key index = nodeIndex[node]; {
if ( index >= static_cast<Key> (insertedNodes.size()) ) const Key index = node_index[node];
if (index >= static_cast<Key>(inserted_nodes.size()))
{
return false; return false;
return insertedNodes[index].node == node; }
return inserted_nodes[index].node == node;
} }
NodeID Min() const { NodeID Min() const
BOOST_ASSERT( heap.size() > 1 ); {
return insertedNodes[heap[1].index].node; BOOST_ASSERT(heap.size() > 1);
return inserted_nodes[heap[1].index].node;
} }
NodeID DeleteMin() { NodeID DeleteMin()
BOOST_ASSERT( heap.size() > 1 ); {
BOOST_ASSERT(heap.size() > 1);
const Key removedIndex = heap[1].index; const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1]; heap[1] = heap[heap.size() - 1];
heap.pop_back(); heap.pop_back();
if ( heap.size() > 1 ) if (heap.size() > 1)
Downheap( 1 ); {
insertedNodes[removedIndex].key = 0; Downheap(1);
}
inserted_nodes[removedIndex].key = 0;
CheckHeap(); CheckHeap();
return insertedNodes[removedIndex].node; return inserted_nodes[removedIndex].node;
} }
void DeleteAll() { void DeleteAll()
for ( typename std::vector< HeapElement >::iterator i = heap.begin() + 1, iend = heap.end(); i != iend; ++i ) {
insertedNodes[i->index].key = 0; auto iend = heap.end();
heap.resize( 1 ); for (typename std::vector<HeapElement>::iterator i = heap.begin() + 1; i != iend; ++i)
heap[0].weight = (std::numeric_limits< Weight >::min)(); {
inserted_nodes[i->index].key = 0;
}
heap.resize(1);
heap[0].weight = (std::numeric_limits<Weight>::min)();
} }
void DecreaseKey( NodeID node, Weight weight ) { void DecreaseKey(NodeID node, Weight weight)
BOOST_ASSERT( UINT_MAX != node ); {
const Key & index = nodeIndex[node]; BOOST_ASSERT(UINT_MAX != node);
Key & key = insertedNodes[index].key; const Key &index = node_index[node];
BOOST_ASSERT ( key >= 0 ); Key &key = inserted_nodes[index].key;
BOOST_ASSERT(key >= 0);
insertedNodes[index].weight = weight; inserted_nodes[index].weight = weight;
heap[key].weight = weight; heap[key].weight = weight;
Upheap( key ); Upheap(key);
CheckHeap(); CheckHeap();
} }
private: private:
class HeapNode { class HeapNode
{
public: public:
HeapNode( NodeID n, Key k, Weight w, Data d ) HeapNode(NodeID n, Key k, Weight w, Data d) : node(n), key(k), weight(w), data(d) {}
:
node(n),
key(k),
weight(w),
data(d)
{ }
NodeID node; NodeID node;
Key key; Key key;
Weight weight; Weight weight;
Data data; Data data;
}; };
struct HeapElement { struct HeapElement
{
Key index; Key index;
Weight weight; Weight weight;
}; };
std::vector< HeapNode > insertedNodes; std::vector<HeapNode> inserted_nodes;
std::vector< HeapElement > heap; std::vector<HeapElement> heap;
IndexStorage nodeIndex; IndexStorage node_index;
void Downheap( Key key ) { void Downheap(Key key)
{
const Key droppingIndex = heap[key].index; const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight; const Weight weight = heap[key].weight;
Key nextKey = key << 1; Key nextKey = key << 1;
while( nextKey < static_cast<Key>( heap.size() ) ){ while (nextKey < static_cast<Key>(heap.size()))
{
const Key nextKeyOther = nextKey + 1; const Key nextKeyOther = nextKey + 1;
if ( if ((nextKeyOther < static_cast<Key>(heap.size())) &&
( nextKeyOther < static_cast<Key>( heap.size() ) ) && (heap[nextKey].weight > heap[nextKeyOther].weight))
( heap[nextKey].weight > heap[nextKeyOther].weight ) {
) {
nextKey = nextKeyOther; nextKey = nextKeyOther;
} }
if ( weight <= heap[nextKey].weight ){ if (weight <= heap[nextKey].weight)
{
break; break;
} }
heap[key] = heap[nextKey]; heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key; inserted_nodes[heap[key].index].key = key;
key = nextKey; key = nextKey;
nextKey <<= 1; nextKey <<= 1;
} }
heap[key].index = droppingIndex; heap[key].index = droppingIndex;
heap[key].weight = weight; 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 Key risingIndex = heap[key].index;
const Weight weight = heap[key].weight; const Weight weight = heap[key].weight;
Key nextKey = key >> 1; Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) { while (heap[nextKey].weight > weight)
BOOST_ASSERT( nextKey != 0 ); {
BOOST_ASSERT(nextKey != 0);
heap[key] = heap[nextKey]; heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key; inserted_nodes[heap[key].index].key = key;
key = nextKey; key = nextKey;
nextKey >>= 1; nextKey >>= 1;
} }
heap[key].index = risingIndex; heap[key].index = risingIndex;
heap[key].weight = weight; heap[key].weight = weight;
insertedNodes[risingIndex].key = key; inserted_nodes[risingIndex].key = key;
} }
void CheckHeap() { void CheckHeap()
{
#ifndef NDEBUG #ifndef NDEBUG
for ( Key i = 2; i < (Key) heap.size(); ++i ) { for (Key i = 2; i < (Key)heap.size(); ++i)
BOOST_ASSERT( heap[i].weight >= heap[i >> 1].weight ); {
BOOST_ASSERT(heap[i].weight >= heap[i >> 1].weight);
} }
#endif #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 <cstring>
#include <vector> #include <vector>
#if __cplusplus > 199711L template <typename ElementT,
#define DEALLOCATION_VECTOR_NULL_PTR nullptr std::size_t bucketSizeC = 8388608 / sizeof(ElementT),
#else bool DeallocateC = false>
#define DEALLOCATION_VECTOR_NULL_PTR NULL class DeallocatingVectorIterator : public std::iterator<std::random_access_iterator_tag, ElementT>
#endif {
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: 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(); DeallocatingVectorIteratorState();
public: public:
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : /*mData(r.mData),*/ mIndex(r.mIndex), mBucketList(r.mBucketList) {} explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
explicit DeallocatingVectorIteratorState(const std::size_t idx, std::vector<ElementT *> & input_list) : /*mData(DEALLOCATION_VECTOR_NULL_PTR),*/ mIndex(idx), mBucketList(input_list) { : index(r.index), bucket_list(r.bucket_list)
{
} }
std::size_t mIndex; explicit DeallocatingVectorIteratorState(const std::size_t idx,
std::vector<ElementT *> & mBucketList; 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) { inline bool operator!=(const DeallocatingVectorIteratorState &other)
return mIndex != other.mIndex; {
return index != other.index;
} }
inline bool operator==(const DeallocatingVectorIteratorState &other) { inline bool operator==(const DeallocatingVectorIteratorState &other)
return mIndex == other.mIndex; {
return index == other.index;
} }
bool operator<(const DeallocatingVectorIteratorState &other) const { bool operator<(const DeallocatingVectorIteratorState &other) const
return mIndex < other.mIndex; {
return index < other.index;
} }
bool operator>(const DeallocatingVectorIteratorState &other) const { bool operator>(const DeallocatingVectorIteratorState &other) const
return mIndex > other.mIndex; {
return index > other.index;
} }
bool operator>=(const DeallocatingVectorIteratorState &other) const { bool operator>=(const DeallocatingVectorIteratorState &other) const
return mIndex >= other.mIndex; {
return index >= other.index;
} }
//This is a hack to make assignment operator possible with reference member // This is a hack to make assignment operator possible with reference member
inline DeallocatingVectorIteratorState& operator= (const DeallocatingVectorIteratorState &a) { inline DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &a)
if (this != &a) { {
this->DeallocatingVectorIteratorState::~DeallocatingVectorIteratorState(); // explicit non-virtual destructor if (this != &a)
{
this->DeallocatingVectorIteratorState::
~DeallocatingVectorIteratorState(); // explicit non-virtual destructor
new (this) DeallocatingVectorIteratorState(a); // placement new new (this) DeallocatingVectorIteratorState(a); // placement new
} }
return *this; return *this;
} }
}; };
DeallocatingVectorIteratorState mState; DeallocatingVectorIteratorState current_state;
public: public:
typedef std::random_access_iterator_tag iterator_category; 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>::value_type
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::difference_type difference_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>::reference reference;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::pointer pointer; typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::pointer pointer;
DeallocatingVectorIterator() {} DeallocatingVectorIterator() {}
template<typename T2> template <typename T2>
explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {} explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> &r)
: current_state(r.current_state)
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;
} }
inline DeallocatingVectorIterator& operator++() { //prefix DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> &input_list)
++mState.mIndex; : 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; return *this;
} }
inline DeallocatingVectorIterator& operator--() { //prefix inline DeallocatingVectorIterator &operator++()
if(DeallocateC) BOOST_ASSERT(false); { // prefix
--mState.mIndex; ++current_state.index;
return *this; return *this;
} }
inline DeallocatingVectorIterator operator++(int) { //postfix inline DeallocatingVectorIterator &operator--()
DeallocatingVectorIteratorState _myState(mState); { // prefix
mState.mIndex++; if (DeallocateC)
return DeallocatingVectorIterator(_myState); {
BOOST_ASSERT(false);
} }
inline DeallocatingVectorIterator operator--(int) { //postfix --current_state.index;
if(DeallocateC) BOOST_ASSERT(false); return *this;
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex--;
return DeallocatingVectorIterator(_myState);
} }
inline DeallocatingVectorIterator operator+(const difference_type& n) const { inline DeallocatingVectorIterator operator++(int)
DeallocatingVectorIteratorState _myState(mState); { // postfix
_myState.mIndex+=n; DeallocatingVectorIteratorState my_state(current_state);
return DeallocatingVectorIterator(_myState); 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) { inline DeallocatingVectorIterator operator+(const difference_type &n) const
mState.mIndex+=n; return *this; {
DeallocatingVectorIteratorState my_state(current_state);
my_state.index += n;
return DeallocatingVectorIterator(my_state);
} }
inline DeallocatingVectorIterator operator-(const difference_type& n) const { inline DeallocatingVectorIterator &operator+=(const difference_type &n)
if(DeallocateC) BOOST_ASSERT(false); {
DeallocatingVectorIteratorState _myState(mState); current_state.index += n;
_myState.mIndex-=n; return *this;
return DeallocatingVectorIterator(_myState);
} }
inline DeallocatingVectorIterator& operator-=(const difference_type &n) const { inline DeallocatingVectorIterator operator-(const difference_type &n) const
if(DeallocateC) BOOST_ASSERT(false); {
mState.mIndex-=n; return *this; if (DeallocateC)
{
BOOST_ASSERT(false);
}
DeallocatingVectorIteratorState my_state(current_state);
my_state.index -= n;
return DeallocatingVectorIterator(my_state);
} }
inline reference operator*() const { inline DeallocatingVectorIterator &operator-=(const difference_type &n) const
std::size_t _bucket = mState.mIndex/bucketSizeC; {
std::size_t _index = mState.mIndex%bucketSizeC; if (DeallocateC)
return (mState.mBucketList[_bucket][_index]); {
BOOST_ASSERT(false);
}
current_state.index -= n;
return *this;
} }
inline pointer operator->() const { inline reference operator*() const
std::size_t _bucket = mState.mIndex/bucketSizeC; {
std::size_t _index = mState.mIndex%bucketSizeC; std::size_t current_bucket = current_state.index / bucketSizeC;
return &(mState.mBucketList[_bucket][_index]); std::size_t current_index = current_state.index % bucketSizeC;
return (current_state.bucket_list[current_bucket][current_index]);
} }
inline bool operator!=(const DeallocatingVectorIterator & other) { inline pointer operator->() const
return mState != other.mState; {
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) { inline bool operator!=(const DeallocatingVectorIterator &other)
return mState == other.mState; {
return current_state != other.current_state;
} }
inline bool operator<(const DeallocatingVectorIterator & other) const { inline bool operator==(const DeallocatingVectorIterator &other)
return mState < other.mState; {
return current_state == other.current_state;
} }
inline bool operator>(const DeallocatingVectorIterator & other) const { inline bool operator<(const DeallocatingVectorIterator &other) const
return mState > other.mState; {
return current_state < other.current_state;
} }
inline bool operator>=(const DeallocatingVectorIterator & other) const { inline bool operator>(const DeallocatingVectorIterator &other) const
return mState >= other.mState; {
return current_state > other.current_state;
} }
difference_type operator-(const DeallocatingVectorIterator & other) { inline bool operator>=(const DeallocatingVectorIterator &other) const
if(DeallocateC) BOOST_ASSERT(false); {
return mState.mIndex-other.mState.mIndex; 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) > template <typename ElementT, std::size_t bucketSizeC = 8388608 / sizeof(ElementT)>
class DeallocatingVector { class DeallocatingVector
private: {
std::size_t mCurrentSize; private:
std::vector<ElementT *> mBucketList; std::size_t current_size;
std::vector<ElementT *> bucket_list;
public: public:
typedef ElementT value_type; typedef ElementT value_type;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> iterator; typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> iterator;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> const_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; typedef DeallocatingVectorIterator<ElementT, bucketSizeC, true> deallocation_iterator;
DeallocatingVector() : mCurrentSize(0) { DeallocatingVector() : current_size(0)
//initial bucket {
mBucketList.push_back(new ElementT[bucketSizeC]); // initial bucket
bucket_list.emplace_back(new ElementT[bucketSizeC]);
} }
~DeallocatingVector() { ~DeallocatingVector() { clear(); }
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) { inline void clear()
std::swap(mCurrentSize, other.mCurrentSize); {
mBucketList.swap(other.mBucketList); // 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() { inline void push_back(const ElementT &element)
//Delete[]'ing ptr's to all Buckets {
for(unsigned i = 0; i < mBucketList.size(); ++i) { const std::size_t current_capacity = capacity();
if(DEALLOCATION_VECTOR_NULL_PTR != mBucketList[i]) { if (current_size == current_capacity)
delete[] mBucketList[i]; {
mBucketList[i] = DEALLOCATION_VECTOR_NULL_PTR; bucket_list.push_back(new ElementT[bucketSizeC]);
}
}
//Removing all ptrs from vector
std::vector<ElementT *>().swap(mBucketList);
mCurrentSize = 0;
} }
inline void push_back(const ElementT & element) { std::size_t current_index = size() % bucketSizeC;
std::size_t _capacity = capacity(); bucket_list.back()[current_index] = element;
if(mCurrentSize == _capacity) { ++current_size;
mBucketList.push_back(new ElementT[bucketSizeC]);
} }
std::size_t _index = size()%bucketSizeC; inline void emplace_back(const ElementT &&element)
mBucketList.back()[_index] = element; {
++mCurrentSize; 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 { const std::size_t current_index = size() % bucketSizeC;
//don't do anything bucket_list.back()[current_index] = element;
++current_size;
} }
inline void resize(const std::size_t new_size) { inline void reserve(const std::size_t) const
if(new_size > mCurrentSize) { {
while(capacity() < new_size) { // don't do anything
mBucketList.push_back(new ElementT[bucketSizeC]);
} }
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) { inline void resize(const std::size_t new_size)
delete[] mBucketList[i]; {
if (new_size > current_size)
{
while (capacity() < new_size)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
} }
mBucketList.resize(number_of_necessary_buckets); current_size = new_size;
mCurrentSize = 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 { inline std::size_t size() const { return current_size; }
return mCurrentSize;
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 { inline deallocation_iterator dend() { return deallocation_iterator(size(), bucket_list); }
return mBucketList.size() * bucketSizeC;
inline const_iterator begin() const
{
return const_iterator(static_cast<std::size_t>(0), bucket_list);
} }
inline iterator begin() { inline const_iterator end() const { return const_iterator(size(), bucket_list); }
return iterator(static_cast<std::size_t>(0), mBucketList);
}
inline iterator end() { inline ElementT &operator[](const std::size_t index)
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) {
std::size_t _bucket = index / bucketSizeC; std::size_t _bucket = index / bucketSizeC;
std::size_t _index = 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 _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC; std::size_t _index = index % bucketSizeC;
return (mBucketList[_bucket][_index]); return (bucket_list[_bucket][_index]);
} }
inline ElementT & back() { inline ElementT &back()
std::size_t _bucket = mCurrentSize / bucketSizeC; {
std::size_t _index = mCurrentSize % bucketSizeC; std::size_t _bucket = current_size / bucketSizeC;
return (mBucketList[_bucket][_index]); std::size_t _index = current_size % bucketSizeC;
return (bucket_list[_bucket][_index]);
} }
const inline ElementT & back() const { const inline ElementT &back() const
std::size_t _bucket = mCurrentSize / bucketSizeC; {
std::size_t _index = mCurrentSize % bucketSizeC; std::size_t _bucket = current_size / bucketSizeC;
return (mBucketList[_bucket][_index]); std::size_t _index = current_size % bucketSizeC;
return (bucket_list[_bucket][_index]);
} }
}; };