diff --git a/vcg/container_allocation_table.h b/vcg/container_allocation_table.h new file mode 100644 index 00000000..ee81743c --- /dev/null +++ b/vcg/container_allocation_table.h @@ -0,0 +1,317 @@ +/**************************************************************************** +* 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; +virtual void Reserve(STL_CONT::value_type * pt,const int & rs)=0; +virtual void Resize(STL_CONT::value_type * pt,const int & rs)=0; + +public: +// ID serve 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; + +CATEntry(){if(Id()==0){ + Id() = CATBase::Id()+1; + CATBase::Id() = Id(); + } + } + + +static unsigned int Ord(VALUE_TYPE *); +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) + +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).C() != &c;++ite) + AT().erase(ite); +UTD() = false; +} + +template +void CATEntry:: + +Remove(VALUE_TYPE * pt) +{ + std::list::iterator lower_ite; + lower_ite = FindBase(pt); + AT().erase(lower_ite); + UTD() = false; +} + + +// 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...) +// For generic user-defined data see CATMulti +template +class CAT:public CATEntry >{ +public: +typedef typename EntryCAT EntryType; +static ATTR_TYPE & Get(STL_CONT::value_type * pt); +static std::vector & Data(STL_CONT::value_type * pt); +static void Insert( STL_CONT & c); +virtual void Reserve(STL_CONT::value_type * pt,const int & rs); +virtual void Resize(STL_CONT::value_type * pt,const int & rs); +virtual void AddDataElem(STL_CONT::value_type * pt,int n);// add n element to the auxiliary data + }; + + +//---------------------- CAT: implementation--------------------------------------------------- +template +void CAT:: + +AddDataElem(STL_CONT::value_type * pt,int n) +{ +Update(pt); +for(int i = 0 ; i < n; ++i) + Curr()->push_back(); +} + +template +ATTR_TYPE & CAT:: + +Get(STL_CONT::value_type * pt) +{ +int ord = Ord(pt); +return Curr()->Data()[ord]; +} + +template +std::vector & CAT:: +Data(STL_CONT::value_type * pt) +{ +Update(pt); +return Curr()->Data(); +} + +template +void CAT:: + +Insert( STL_CONT & c ) +{ +EntryType 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->Data().reserve(c.capacity()); +lower_ite->Data().resize(c.size()); +UTD() = false; +} + +template +void CAT:: +Reserve(STL_CONT::value_type * pt,const int & rs) +{ +Update(pt); +Curr()->Data().reserve(rs); +} + +template +void CAT:: +Resize(STL_CONT::value_type * pt,const int & rs) +{ +Update(pt); +Curr()->Data().resize(rs); +} + +template +class CATMulti:public CATEntry{ +public: +typedef typename ENTRY_TYPE EntryType; +static void Insert( STL_CONT & c); +static ENTRY_TYPE & GetEntry(STL_CONT::value_type *); +virtual void Reserve(const int & rs){}; +virtual void Resize(const int & rs){}; +}; + +// --------------------------- CATMulti: implementation ------------------ +template +void CATMulti:: +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); +UTD() = false; +} + +template +ENTRY_TYPE & CATMulti:: +GetEntry(STL_CONT::value_type*pt){ +Update(pt); +return *Curr(); +} + +};//end namespace vcg + +#endif \ No newline at end of file diff --git a/vcg/entries_allocation_table.h b/vcg/entries_allocation_table.h new file mode 100644 index 00000000..37f5da3b --- /dev/null +++ b/vcg/entries_allocation_table.h @@ -0,0 +1,100 @@ +/**************************************************************************** +* 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 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(){ data.push_back(ATTR_TYPE());} +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; + } + + +// EntryCATMulti: entry type for generic data (matches with CATMulti) +template +struct EntryCATMulti: public EntryCATBase{ +EntryCATMulti(STL_CONT & _c) : EntryCATBase(_c){}; +std::list< void * > & Data(){return data;} +void push_back(){} +private: + std::list< void * > data; +}; + +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 = CATMulti >::Ord(v); + return (*item)[pos]; + } + }; + +}; // end namespace vcg + +#endif \ No newline at end of file diff --git a/vcg/traced_vector.h b/vcg/traced_vector.h new file mode 100644 index 00000000..3dc616e5 --- /dev/null +++ b/vcg/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) + CATMulti >::EntryType + entry = CATMulti >::GetEntry(&*begin()); + entry.Data().push_back(new std::vector); + + ((std::vector*)entry.Data().back())->reserve(capacity()); + ((std::vector*)entry.Data().back())->resize(size()); + + return TempData((std::vector*) entry.Data().back()); + } + + template + void DeleteTempData(TempData & td){ + //CAT::Insert(*this) + CATMulti >::EntryType + entry = CATMulti >::GetEntry(&*begin()); + + entry.Data().remove(td.Item()); + delete 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