move BinaryHeap to C++11
This commit is contained in:
parent
3ca9420801
commit
5b22dffa6f
@ -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,
|
||||
typename Key,
|
||||
typename Weight,
|
||||
typename Data,
|
||||
typename IndexStorage = ArrayStorage<NodeID, NodeID>
|
||||
>
|
||||
class BinaryHeap {
|
||||
private:
|
||||
BinaryHeap( const BinaryHeap& right );
|
||||
void operator=( const BinaryHeap& right );
|
||||
public:
|
||||
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:
|
||||
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 {
|
||||
public:
|
||||
HeapNode( NodeID n, Key k, Weight w, Data d )
|
||||
:
|
||||
node(n),
|
||||
key(k),
|
||||
weight(w),
|
||||
data(d)
|
||||
{ }
|
||||
private:
|
||||
class HeapNode
|
||||
{
|
||||
public:
|
||||
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
|
||||
|
@ -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 {
|
||||
private:
|
||||
//make constructors explicit, so we do not mix random access and deallocation iterators.
|
||||
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.
|
||||
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) {
|
||||
}
|
||||
std::size_t mIndex;
|
||||
std::vector<ElementT *> & mBucketList;
|
||||
|
||||
inline bool operator!=(const DeallocatingVectorIteratorState &other) {
|
||||
return mIndex != other.mIndex;
|
||||
public:
|
||||
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
|
||||
: index(r.index), bucket_list(r.bucket_list)
|
||||
{
|
||||
}
|
||||
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 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--(int) { //postfix
|
||||
if(DeallocateC) BOOST_ASSERT(false);
|
||||
DeallocatingVectorIteratorState _myState(mState);
|
||||
mState.mIndex--;
|
||||
return DeallocatingVectorIterator(_myState);
|
||||
inline DeallocatingVectorIterator &operator--()
|
||||
{ // prefix
|
||||
if (DeallocateC)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
--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 < mBucketList.size(); ++i) {
|
||||
if(DEALLOCATION_VECTOR_NULL_PTR != mBucketList[i]) {
|
||||
delete[] mBucketList[i];
|
||||
mBucketList[i] = DEALLOCATION_VECTOR_NULL_PTR;
|
||||
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(mBucketList);
|
||||
mCurrentSize = 0;
|
||||
// Removing all ptrs from vector
|
||||
std::vector<ElementT *>().swap(bucket_list);
|
||||
current_size = 0;
|
||||
}
|
||||
|
||||
inline void push_back(const ElementT & element) {
|
||||
std::size_t _capacity = capacity();
|
||||
if(mCurrentSize == _capacity) {
|
||||
mBucketList.push_back(new ElementT[bucketSizeC]);
|
||||
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]);
|
||||
}
|
||||
|
||||
std::size_t _index = size()%bucketSizeC;
|
||||
mBucketList.back()[_index] = element;
|
||||
++mCurrentSize;
|
||||
std::size_t current_index = size() % bucketSizeC;
|
||||
bucket_list.back()[current_index] = element;
|
||||
++current_size;
|
||||
}
|
||||
|
||||
inline void reserve(const std::size_t) const {
|
||||
//don't do anything
|
||||
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]);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
mCurrentSize = new_size;
|
||||
current_size = new_size;
|
||||
}
|
||||
if(new_size < mCurrentSize) {
|
||||
std::size_t number_of_necessary_buckets = 1+(new_size / bucketSizeC);
|
||||
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 < mBucketList.size(); ++i) {
|
||||
delete[] mBucketList[i];
|
||||
for (unsigned i = number_of_necessary_buckets; i < bucket_list.size(); ++i)
|
||||
{
|
||||
delete[] bucket_list[i];
|
||||
}
|
||||
mBucketList.resize(number_of_necessary_buckets);
|
||||
mCurrentSize = new_size;
|
||||
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]);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user