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
|
#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
|
||||||
|
@ -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]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user