/*
===========================================================================
Copyright (C) 2000 - 2013, Raven Software, Inc.
Copyright (C) 2001 - 2013, Activision, Inc.
Copyright (C) 2013 - 2015, OpenJK contributors
This file is part of the OpenJK source code.
OpenJK is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see .
===========================================================================
*/
////////////////////////////////////////////////////////////////////////////////////////
// RAVEN STANDARD TEMPLATE LIBRARY
// (c) 2002 Activision
//
//
// Memory Pool
// -----------
// The memory pool class is a simple routine for constant time allocation and deallocation
// from a fixed size pool of objects. The class uses a simple array to hold the actual
// data, a queue for the free list, and a bit field to mark which spots in the array
// are allocated.
//
//
//
// NOTES:
//
//
//
////////////////////////////////////////////////////////////////////////////////////////
#if !defined(RATL_POOL_VS_INC)
#define RATL_POOL_VS_INC
////////////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////////////
#if !defined(RATL_COMMON_INC)
#include "ratl_common.h"
#endif
#if !defined(RATL_QUEUE_VS_INC)
#include "queue_vs.h"
#endif
namespace ratl
{
// fixme, this could be made more efficient by keepingtrack of the highest slot ever used
// then there is no need to fill the free list
template
class pool_root : public ratl_base
{
public:
typedef T TStorageTraits;
typedef typename T::TValue TTValue;
////////////////////////////////////////////////////////////////////////////////////
// Capacity Enum
////////////////////////////////////////////////////////////////////////////////////
static const int CAPACITY = T::CAPACITY;
private:
////////////////////////////////////////////////////////////////////////////////////
// Data
////////////////////////////////////////////////////////////////////////////////////
array_base mData;
queue_vs mFree;
bits_base mUsed;
int mSize;
void FillFreeList()
{
mFree.clear();
int i;
for (i=0;i0);
int index=mData.pointer_to_index(me);
assert(index>=0 && index0);
int index=mData.pointer_to_index(me);
assert(index>=0 && index=0 && i=0 && j0);
assert(i>=0 && i;
friend class const_iterator;
int mIndex;
pool_root* mOwner;
public:
// Constructors
//--------------
iterator() : mOwner(0)
{}
iterator(pool_root* p, int index) : mIndex(index), mOwner(p)
{}
iterator(const iterator &t) : mIndex(t.mIndex), mOwner(t.mOwner)
{}
// Assignment Operator
//---------------------
void operator= (const iterator &t)
{
mOwner = t.mOwner;
mIndex = t.mIndex;
}
// Equality Operators
//--------------------
bool operator!=(const iterator& t) {assert(mOwner && mOwner==t.mOwner); return (mIndex!=t.mIndex);}
bool operator==(const iterator& t) {assert(mOwner && mOwner==t.mOwner); return (mIndex==t.mIndex);}
// Dereference Operators
//----------------------
TTValue& operator* () const {assert(mOwner && mOwner->is_used_index(mIndex)); return (mOwner->mData[mIndex]);}
TTValue* operator->() const {assert(mOwner && mOwner->is_used_index(mIndex)); return (&mOwner->mData[mIndex]);}
// Handle & Index Access
//-----------------------
int index() {assert(mOwner && mOwner->is_used_index(mIndex)); return mIndex;}
// Inc Operator
//-------------
iterator operator++(int) // postfix
{
assert(mIndex>=0&&mIndexis_used_index(mIndex));
iterator ret(*this);
mIndex = mOwner->mUsed.next_bit(mIndex+1);
return ret;
}
// Inc Operator
//-------------
iterator operator++() // prefix
{
assert(mIndex>=0&&mIndexis_used_index(mIndex));
mIndex = mOwner->mUsed.next_bit(mIndex+1);
return *this;
}
};
friend class iterator;
////////////////////////////////////////////////////////////////////////////////////
// Iterator
////////////////////////////////////////////////////////////////////////////////////
class const_iterator
{
int mIndex;
const pool_root* mOwner;
public:
// Constructors
//--------------
const_iterator() : mOwner(0)
{}
const_iterator(const pool_root* p, int index) : mOwner(p), mIndex(index)
{}
const_iterator(const iterator &t) : mOwner(t.mOwner), mIndex(t.mIndex)
{}
const_iterator(const const_iterator &t) : mOwner(t.mOwner), mIndex(t.mIndex)
{}
// Equality Operators
//--------------------
bool operator!=(const const_iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex!=t.mIndex);}
bool operator==(const const_iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex==t.mIndex);}
bool operator!=(const iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex!=t.mIndex);}
bool operator==(const iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex==t.mIndex);}
// Dereference Operators
//----------------------
const TTValue& operator* () const {assert(mOwner && mOwner->is_used_index(mIndex)); return (mOwner->mData[mIndex]);}
const TTValue* operator->() const {assert(mOwner && mOwner->is_used_index(mIndex)); return (&mOwner->mData[mIndex]);}
// Handle & Index Access
//-----------------------
int index() const {assert(mOwner && mOwner->is_used_index(mIndex)); return mIndex;}
// Inc Operator
//-------------
const_iterator operator++(int) // postfix
{
assert(mIndex>=0&&mIndexis_used_index(mIndex));
const_iterator ret(*this);
mIndex = mOwner->mUsed.next_bit(mIndex+1);
return ret;
}
// Inc Operator
//-------------
const_iterator operator++() // prefix
{
assert(mIndex>=0&&mIndexis_used_index(mIndex));
mIndex = mOwner->mUsed.next_bit(mIndex+1);
return *this;
}
};
friend class const_iterator;
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The First Allocated Memory Block
////////////////////////////////////////////////////////////////////////////////////
iterator begin()
{
int idx=mUsed.next_bit(0);
return iterator(this,idx); // Find The First Allocated
}
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The Object At index
////////////////////////////////////////////////////////////////////////////////////
iterator at_index(int index)
{
assert(mUsed[index]); // disallow iterators to non alloced things
return iterator(this, index);
}
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The End Of The Memroy (One Step Beyond)
////////////////////////////////////////////////////////////////////////////////////
iterator end()
{
return iterator(this, CAPACITY);
}
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The First Allocated Memory Block
////////////////////////////////////////////////////////////////////////////////////
const_iterator begin() const
{
int idx=mUsed.next_bit(0);
return iterator(this,idx); // Find The First Allocated
}
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The Object At index
////////////////////////////////////////////////////////////////////////////////////
const_iterator at_index(int index) const
{
assert(mUsed[index]); // disallow iterators to non alloced things
return iterator(this, index);
}
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The End Of The Memroy (One Step Beyond)
////////////////////////////////////////////////////////////////////////////////////
const_iterator end() const
{
return iterator(this, CAPACITY);
}
template
CAST_TO *verify_alloc(CAST_TO *p) const
{
return mData.verify_alloc(p);
}
};
/*
pool_base, base class for the pools
operations:
size()
empty()
full()
clear() op[]
at_index() op[]
at_index() const
index pointer_to_index(ptr)
index alloc_index() alloc()
index alloc_index(ref) alloc()
ptr alloc_raw()
free_index(index)
free(ptr)
is_used_index(index)
*/
template
class pool_base : public pool_root
{
public:
typedef typename T::TValue TTValue;
////////////////////////////////////////////////////////////////////////////////////
// Constant Accessor
////////////////////////////////////////////////////////////////////////////////////
const TTValue& operator[](int i) const
{
return pool_root::value_at_index(i);
}
////////////////////////////////////////////////////////////////////////////////////
// Accessor
////////////////////////////////////////////////////////////////////////////////////
TTValue& operator[](int i)
{
return pool_root::value_at_index(i);
}
bool is_used(int i) const
{
return pool_root::is_used_index(i);
}
////////////////////////////////////////////////////////////////////////////////////
// Swap two items based on index
////////////////////////////////////////////////////////////////////////////////////
void swap(int i,int j)
{
pool_root::swap_index(i,j);
}
////////////////////////////////////////////////////////////////////////////////////
// The Allocator returns an index
////////////////////////////////////////////////////////////////////////////////////
int alloc()
{
return pool_root::alloc_index();
}
////////////////////////////////////////////////////////////////////////////////////
// The Allocator returns an index
////////////////////////////////////////////////////////////////////////////////////
int alloc(const TTValue &v)
{
return pool_root::alloc_index(v);
}
////////////////////////////////////////////////////////////////////////////////////
// The Deallocator
////////////////////////////////////////////////////////////////////////////////////
void free(int i)
{
pool_root::free_index(i);
}
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The Object At index
////////////////////////////////////////////////////////////////////////////////////
typename pool_root::iterator at(int index)
{
return pool_root::at_index(index);
}
////////////////////////////////////////////////////////////////////////////////////
// Get An Iterator To The Object At index
////////////////////////////////////////////////////////////////////////////////////
typename pool_root::const_iterator at(int index) const
{
return pool_root::at_index(index);
}
};
template
class pool_vs : public pool_base >
{
public:
typedef typename storage::value_semantics TStorageTraits;
typedef typename TStorageTraits::TValue TTValue;
static const int CAPACITY = ARG_CAPACITY;
pool_vs() {}
};
template
class pool_os : public pool_base >
{
public:
typedef typename storage::object_semantics TStorageTraits;
typedef typename TStorageTraits::TValue TTValue;
static const int CAPACITY = ARG_CAPACITY;
pool_os() {}
};
template
class pool_is : public pool_base >
{
public:
typedef typename storage::virtual_semantics TStorageTraits;
typedef typename TStorageTraits::TValue TTValue;
static const int CAPACITY = ARG_CAPACITY;
static const int MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE;
pool_is() {}
};
}
#endif