From 48d93d63393a78448bd5614e015b86afd1668dcc Mon Sep 17 00:00:00 2001 From: ganovelli Date: Wed, 31 Mar 2004 12:40:42 +0000 Subject: [PATCH] Data structure to handle temporary attributes. First version --- vcg/container/container_allocation_table.h | 269 +++++++++++++++++++++ vcg/container/entries_allocation_table.h | 149 ++++++++++++ vcg/container/simple_temporary_data.h | 65 +++++ vcg/container/traced_vector.h | 152 ++++++++++++ 4 files changed, 635 insertions(+) create mode 100644 vcg/container/container_allocation_table.h create mode 100644 vcg/container/entries_allocation_table.h create mode 100644 vcg/container/simple_temporary_data.h create mode 100644 vcg/container/traced_vector.h diff --git a/vcg/container/container_allocation_table.h b/vcg/container/container_allocation_table.h new file mode 100644 index 00000000..a3107279 --- /dev/null +++ b/vcg/container/container_allocation_table.h @@ -0,0 +1,269 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* 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 (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + + +#ifndef __VCGLIB_CAT__ +#define __VCGLIB_CAT__ + +#include +#include +#include +#include +#include + +namespace vcg { + +// CATBase: abstract base class for all the allocation tables +template +class CATBase{ +public: +typedef STL_CONT::value_type VALUE_TYPE; + +virtual void Resort(VALUE_TYPE*,VALUE_TYPE*) =0; +virtual void Remove(const STL_CONT&) = 0; +virtual void AddDataElem(VALUE_TYPE*,int)=0; + +public: +// ID serves as a type trait. +static int & Id(){ + static int id=0; + return id; + } +}; + +// CATEntry: first derivation templated on the type of entry +// It implements all the methods to trace and access TVector element +template +class CATEntry: public CATBase{ +public: +typedef STL_CONT::value_type VALUE_TYPE; +typedef ENTRY_TYPE EntryType; + +CATEntry(){if(Id()==0){ + Id() = CATBase::Id()+1; + CATBase::Id() = Id(); + } + } + + +static unsigned int Ord(VALUE_TYPE *); +static ENTRY_TYPE & GetEntry(STL_CONT::value_type*pt); + +static void Insert( STL_CONT & c ); // insert a vector to trace +virtual void Remove( const STL_CONT & c); // remove the container c +static void Remove( VALUE_TYPE * v); // remove the container that contains v + +virtual void Resort( VALUE_TYPE* old_start, // resort the allocation table + VALUE_TYPE* new_start); // after a container was moved + +protected: + +static std::list& AT(){ // tallocation table +static std::list allocation_table; + return allocation_table; + } +static bool & UTD(){ + static bool upToDate; // true if Lower() and Upper() + return upToDate; // are up to date + } + +static VALUE_TYPE *& Lower() { + static VALUE_TYPE * lower; // pointer to the first element + return lower; // of the last container accessed + } +static VALUE_TYPE *& Upper() { + static VALUE_TYPE * upper; // pointer to the first element + return upper; // if the container next to the last accessed +} + +static std::list::iterator & Curr(){ // container that was last accessed + static std::list::iterator currEntry; + return currEntry; +} + + +static bool IsTheSameAsLast(VALUE_TYPE *pt); // true if pt is in the container + // that was accessed last +static void Update(VALUE_TYPE*); // set Upper() e Lower() +static std::list::iterator FindBase(const VALUE_TYPE * pt); + // find the container that contains pt (naive) +virtual void AddDataElem(STL_CONT::value_type * pt,int n);// add n element to the auxiliary data + +public: +static int & Id(){ // unique identifier of the istance + static int id=0; // (used as type trait) + return id; + } +}; + +// --------------------------- CATEntry: implementation -------------------- + +template +unsigned int CATEntry:: + +Ord(VALUE_TYPE * pt) +{ + Update(pt); + return (pt-Lower()); +} + + +template +std::list::iterator CATEntry:: + +FindBase(const VALUE_TYPE * pt) +{ +std::list::iterator +ite = AT().begin(),curr_base; + +std::list tmp = AT(); +for(;ite != AT().end();ite++) + if( pt < (*ite).Start()) + return curr_base; + else + curr_base = ite; + +return curr_base; +} + + +template + bool CATEntry< STL_CONT, ENTRY_TYPE>:: + +IsTheSameAsLast(VALUE_TYPE * pt) +{ +return ( UTD() && ( !(Lower()> pt)) && (pt < Upper()) ); +} + +template +void CATEntry< STL_CONT, ENTRY_TYPE>:: + +Update(VALUE_TYPE * pt) +{ +if(!IsTheSameAsLast(pt)){ + std::list::iterator lower_ite; + lower_ite = FindBase(pt); + + assert( lower_ite!=AT().end()); + + Lower() = (*lower_ite).Start(); + if( (*lower_ite).Start() == AT().back().Start()) + Upper() = (VALUE_TYPE *) 0xffffffff; + else + { + lower_ite++; + Upper() = (*lower_ite).Start(); + } + + Curr() = lower_ite; + UTD() = true; + } +} + +template +void CATEntry< STL_CONT, ENTRY_TYPE>:: +Resort(VALUE_TYPE* old_start,VALUE_TYPE* new_start) +{ +AT().sort(); +UTD() = false; +} + +template +void CATEntry:: + +Remove( const STL_CONT & c ) +{ +std::list::iterator ite; +for(ite = AT().begin(); ite != AT().end(); ++ite) +if((*ite).C() == &c) + { + AT().erase(ite); + break; + } +UTD() = false; +} + +template +void CATEntry:: + +Remove(VALUE_TYPE * pt) +{ + std::list::iterator lower_ite; + lower_ite = FindBase(pt); + AT().erase(lower_ite); + UTD() = false; +} + +template +void CATEntry:: + +Insert( STL_CONT & c ) +{ +ENTRY_TYPE entry(c); +std::list::iterator lower_ite,upper_ite; +upper_ite = std::lower_bound(AT().begin(), AT().end(), entry); +lower_ite = AT().insert(upper_ite,entry); +lower_ite->Reserve(c.capacity()); +lower_ite->Resize(c.size()); +UTD() = false; +} +template +ENTRY_TYPE & CATEntry:: +GetEntry(STL_CONT::value_type*pt){ +Update(pt); +return *Curr(); +} + +template +void CATEntry:: + +AddDataElem(STL_CONT::value_type * pt,int n) +{ +Update(pt); +Curr()->Push_back(n); +} + +//-------------------------------------------------------------------------------------------- +// CAT: derivation of CATEntry for the case where the temporary data is unique for each type. +// VERY IMPORTANT: there cannot be two vector of value with the same type of temporary datya +// This class is used to implement optional core data (NormalOpt, CoordOpt etc...) +template +class CAT:public CATEntry >{ +public: +typedef typename EntryCAT EntryType; +static ATTR_TYPE & Get(STL_CONT::value_type * pt); +}; +//---------------------- CAT: implementation--------------------------------------------------- +template +ATTR_TYPE & CAT:: + +Get(STL_CONT::value_type * pt) +{ +int ord = Ord(pt); +return Curr()->Data()[ord]; +} +//--------------------------------------------------------------------------------------------- + +};//end namespace vcg + +#endif \ No newline at end of file diff --git a/vcg/container/entries_allocation_table.h b/vcg/container/entries_allocation_table.h new file mode 100644 index 00000000..4eed0ff3 --- /dev/null +++ b/vcg/container/entries_allocation_table.h @@ -0,0 +1,149 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* 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 (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + + +#ifndef __VCGLIB_ENTRIES__ +#define __VCGLIB_ENTRIES__ + +namespace vcg { + +// EntryCATBase: base class for the entry of the allocation table +// templated over the container type +template +struct EntryCATBase{ + +EntryCATBase(STL_CONT & _c):c(_c){}; +STL_CONT::value_type * Start() const; +const STL_CONT * C(); +virtual void Push_back(const int &){}; + +virtual void Reserve(const int & s){}; +virtual void Resize(const int & s){}; + +const bool operator < (const EntryCATBase & other) const; + +private: + STL_CONT & c; +}; + +//EntryCAT: entry for the case of optional core types (matches with CAT) +template +struct EntryCAT: public EntryCATBase{ +typedef ATTR_TYPE attr_type; +EntryCAT(STL_CONT & _c) : EntryCATBase(_c){}; +std::vector & Data(){return data;} +void Push_back(const int & n){ for(int i = 0; i < n ; ++i) data.push_back(ATTR_TYPE());} +virtual void Reserve(const int & s){data.reserve(s);}; +virtual void Resize(const int & s){data.resize(s);}; + + +private: +std::vector data; +}; + +//----------------------EntryCAT: implementation ---------------------------------------- +template +const bool EntryCATBase:: operator < (const EntryCATBase & other) const{ + return (Start() < other.Start()); +} + +template + STL_CONT::value_type * EntryCATBase::Start()const { + return &(*(c.begin())); + } + +template + const STL_CONT * EntryCATBase::C(){ + return &c; + } + + + +// ----------------------------------------------------------------------------------------- +// WrapBase: used to implement a list of pointers to std::vector of different types +// Wrap: derived from WrapBase (to take the function and from std::vector) +struct WrapBase{ +virtual void Push_back(const int & n)=0; +virtual void Reserve(const int & n)=0; +virtual void Resize(const int & n)=0; + }; +// (note) double hineritance is not necessary, just handy +template +struct Wrap: public WrapBase,std::vector{ + virtual void Push_back(const int & n){for (int i = 0 ; i < n; ++i) push_back( ATTR_TYPE());} + virtual void Reserve(const int & n){reserve(n);} + virtual void Resize(const int & n){resize(n);} + }; +//------------------------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------------------- +// EntryCATMulti: entry type for multiple user data +template +struct EntryCATMulti: public EntryCATBase{ + +EntryCATMulti(STL_CONT & _c) : EntryCATBase(_c){}; +std::list & Data(){return data;} +void push_back(const int & n ){ + std::list< void * >::iterator ite; + for(ite = data.begin(); ite != data.end(); ++ite) + (*ite)->Push_back(n); + } +virtual void Reserve(const int & n){ + std::list::iterator ite; + for(ite = data.begin(); ite != data.end(); ++ite) + (*ite)->Reserve(n); + }; +virtual void Resize(const int & n){ + std::list::iterator ite; + for(ite = data.begin(); ite != data.end(); ++ite) + (*ite)->Resize(n); + }; + +private: + std::list< WrapBase * > data; +}; +//---------------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------------- +// TempData implements a handle to one of the vector od data stored in EntryCATMulti +template +class TempData{ +public: + TempData(std::vector *d):item(d){}; + typedef typename ATTR_TYPE attr_type; + + std::vector * Item(){return item;}; + std::vector * item; + ATTR_TYPE & operator [](STL_CONT::value_type * v) + { + int pos = CATEntry >::Ord(v); + return (*item)[pos]; + } + }; +//---------------------------------------------------------------------------------- + + +}; // end namespace vcg + +#endif \ No newline at end of file diff --git a/vcg/container/simple_temporary_data.h b/vcg/container/simple_temporary_data.h new file mode 100644 index 00000000..91b20081 --- /dev/null +++ b/vcg/container/simple_temporary_data.h @@ -0,0 +1,65 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* 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 (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + + +#ifndef __VCGLIB_SIMPLE__ +#define __VCGLIB_SIMPLE__ + +#include + +namespace vcg { + +template +class SimpleTempData{ +public: +typedef typename ATTR_TYPE attr_type; + +STL_CONT& c; +std::vector data; + +SimpleTempData(STL_CONT &_c):c(_c){}; + +// access to data +ATTR_TYPE & operator[](const STL_CONT::value_type *v){return data[v-&*c.begin()];} +ATTR_TYPE & operator[](const int & i){return data[i];} + +// start temporary attribute +void Start(){data.reserve(c.capacity());data.resize(c.size());} + +// stop temporary attribute +void Stop(){data.clear();} + +// update temproary data size +bool UpdateSize(){ + if(data.size() != c.size()) + { + data.resize(c.size()); + return false; + } + return true; + } +}; + +}; // end namespace vcg + +#endif \ No newline at end of file diff --git a/vcg/container/traced_vector.h b/vcg/container/traced_vector.h new file mode 100644 index 00000000..99e0148d --- /dev/null +++ b/vcg/container/traced_vector.h @@ -0,0 +1,152 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* 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 (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + + +#ifndef __VCGLIB_TRACED_VECTOR__ +#define __VCGLIB_TRACED_VECTOR__ + + +#include +#include + +namespace vcg { + +template +class TVector: public std::vector{ + typedef TVector THIS_TYPE; +public: + TVector():std::vector(){reserve(1);} + ~TVector(); + + + std::list < CATBase* > attributes; + // override di tutte le funzioni che possono spostare + // l'allocazione in memoria del container + void push_back(const VALUE_TYPE & v); + void pop_back(); + void resize(const unsigned int & size); + void reserve(const unsigned int & size); + + template + void EnableAttribute(){ + CAT * cat = new CAT(); + cat->Insert(*this); + attributes.push_back(cat); + } + + template + void DisableAttribute(){ + std::list < CATBase * >::iterator ia; + for(ia = attributes.begin(); ia != attributes.end(); ++ia) + if((*ia)->Id() == CAT::Id()) + { + (*ia)->Remove(*this); + delete (*ia); + attributes.erase(ia); + break; + } + } + + template + TempData NewTempData(){ + //CAT::Insert(*this) + CATEntry >::EntryType + entry = CATEntry >::GetEntry(&*begin()); + entry.Data().push_back(new Wrap< ATTR_TYPE>); + + ((Wrap*)entry.Data().back())->reserve(capacity()); + ((Wrap*)entry.Data().back())->resize(size()); + + return TempData((Wrap*) entry.Data().back()); + } + + template + void DeleteTempData(TempData & td){ + //CAT::Insert(*this) + CATEntry >::EntryType + entry = CATEntry >::GetEntry(&*begin()); + + entry.Data().remove((Wrap*)td.Item()); + delete ((Wrap*)td.Item()); + } + + +private: + VALUE_TYPE * old_start; + void Update(); +}; + +template +void TVector::push_back(const VALUE_TYPE & v){ + std::vector::push_back(v); + std::list < CATBase * >::iterator ia; + for(ia = attributes.begin(); ia != attributes.end(); ++ia) + (*ia)->AddDataElem(&(*(this->begin())),1); + Update(); +} +template +void TVector::pop_back(){ + std::vector::pop_back(); + Update(); +} + +template +void TVector::resize(const unsigned int & size){ + std::vector::resize(size); + std::list < CATBase * >::iterator ia; + for(ia = attributes.begin(); ia != attributes.end(); ++ia) + (*ia)-> + Update(); +} + +template +void TVector::reserve(const unsigned int & size){ + std::vector::reserve(size); + Update(); +} + +template + void TVector:: + Update(){ + std::list < CATBase * >::iterator ia; + if(&(*begin()) != old_start) + for(ia = attributes.begin(); ia != attributes.end(); ++ia) + (*ia)->Resort(old_start,&(*begin())); + + old_start = &(*begin()); + } + + + +template +TVector::~TVector(){ + std::list < CATBase * >::iterator ia; + for(ia = attributes.begin(); ia != attributes.end(); ++ia) + { + (*ia)->Remove(*this); + delete *ia; + } + } + +}; // end namespace +#endif