Rev 562 | Rev 578 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/* ----------------------------------------------------------------------- *
* This file is part of GEL, http://www.imm.dtu.dk/GEL
* Copyright (C) the authors and DTU Informatics
* For license and list of authors, see ../../doc/intro.pdf
* ----------------------------------------------------------------------- */
#ifndef __HMESH_ITEMVECTOR_H__
#define __HMESH_ITEMVECTOR_H__
#include <cassert>
#include <vector>
namespace HMesh
{
template<typename ITEM>
class ItemVector
{
public:
/// default constructor
ItemVector(size_t _size = 0, ITEM i = ITEM());
/// Get a reference to item i from kernel
ITEM& get(size_t i);
/// Get a const reference to item i from kernel
const ITEM& get(size_t i) const;
/// Get a reference to item i from kernel
ITEM& operator[](size_t i);
/// Get a const reference to item i from kernel
const ITEM& operator[](size_t i) const;
/// Add an entity to the kernel
size_t add(const ITEM& i);
/// remove an entity from kernel - entity is NOT erased!
void remove(size_t i);
/// erase unused entities from the kernel
void cleanup();
/// active size of vector
size_t active_size() const;
/// total size of vector
size_t total_size() const;
/// Resize the kernel NOTE: Sets all active flags to true
void resize(size_t _size, ITEM i = ITEM());
/// Request size change in kernel
void reserve(size_t i);
/// Clear the kernel
void clear();
/// Check if entity i is used
bool in_use(size_t i) const;
/// get starting index (default: skip to first active index)
size_t index_begin(bool skip = true) const;
/// get one past the end index of vector
size_t index_end() const;
/// get the next index (default: skip to first active index)
size_t index_next(size_t index, bool skip = true) const;
/// get the previous index (default: skip to first active index)
size_t index_prev(size_t index, bool skip = true) const;
private:
size_t size_active;
std::vector<ITEM> items;
/// Memory consideration - objects flagged as unused should be remembered for future use (unless purged)
std::vector<bool> active_items;
};
template<typename ITEM>
inline ItemVector<ITEM>::ItemVector(size_t _size, ITEM i)
: size_active(_size),
items(_size, i),
active_items(_size, true){}
template<typename ITEM>
inline ITEM& ItemVector<ITEM>::get(size_t i)
{
assert(i < items.size());
return items[i];
}
template<typename ITEM>
inline const ITEM& ItemVector<ITEM>::get(size_t i) const
{
assert(i < items.size());
return items[i];
}
template<typename ITEM>
inline ITEM& ItemVector<ITEM>::operator [](size_t i)
{
assert(i < items.size());
return items[i];
}
template<typename ITEM>
inline const ITEM& ItemVector<ITEM>::operator [](size_t i) const
{
assert(i < items.size());
return items[i];
}
template<typename ITEM>
inline size_t ItemVector<ITEM>::add(const ITEM& i)
{
items.push_back(i);
active_items.push_back(true);
++size_active;
return items.size() - 1;
}
template<typename ITEM>
inline void ItemVector<ITEM>::remove(size_t i)
{
if(active_items[i]){
--size_active;
active_items[i] = false;
}
}
template<typename ITEM>
inline void ItemVector<ITEM>::cleanup()
{
std::vector<ITEM> new_items;
for(size_t i = 0; i < items.size(); ++i){
if(active_items[i])
new_items.push_back(items[i]);
}
std::swap(items, new_items);
active_items = std::vector<bool>(items.size(), true);
size_active = items.size();
}
template<typename ITEM>
inline size_t ItemVector<ITEM>::active_size() const
{ return size_active; }
template<typename ITEM>
inline size_t ItemVector<ITEM>::total_size() const
{ return items.size(); }
template<typename ITEM>
inline void ItemVector<ITEM>::resize(size_t _size, ITEM i)
{
items.resize(_size, i);
active_items.resize(_size, true);
size_active = _size;
}
template<typename ITEM>
inline void ItemVector<ITEM>::reserve(size_t i)
{
items.reserve(i);
active_items.reserve(i);
}
template<typename ITEM>
inline void ItemVector<ITEM>::clear()
{
items.clear();
active_items.clear();
size_active = 0;
}
template<typename ITEM>
inline bool ItemVector<ITEM>::in_use(size_t i) const
{
if(i < active_items.size())
return active_items[i];
return false;
}
template<typename ITEM>
inline size_t ItemVector<ITEM>::index_begin(bool skip) const
{
size_t i = 0;
if(!skip)
return i;
while(i < active_items.size() && !active_items[i])
++i;
return i;
}
template<typename ITEM>
inline size_t ItemVector<ITEM>::index_end() const
{ return items.size(); }
template<typename ITEM>
inline size_t ItemVector<ITEM>::index_next(size_t index, bool skip) const
{
if(index < items.size())
++index;
if(!skip)
return index;
while(index < items.size() && !active_items[index])
++index;
return index;
}
template<typename ITEM>
inline size_t ItemVector<ITEM>::index_prev(size_t index, bool skip) const
{
if(index > 0)
--index;
if(!skip)
return index;
while(!active_items[index] && index > 0)
--index;
return index;
}
}
#endif