00001 /**************************************************************************** 00002 * VCGLib o o * 00003 * Visual and Computer Graphics Library o o * 00004 * _ O _ * 00005 * Copyright(C) 2004 \/)\/ * 00006 * Visual Computing Lab /\/| * 00007 * ISTI - Italian National Research Council | * 00008 * \ * 00009 * All rights reserved. * 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 * This program is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * 00020 * for more details. * 00021 * * 00022 ****************************************************************************/ 00023 00024 #ifndef __VCGLIB_TRACED_VECTOR__ 00025 #define __VCGLIB_TRACED_VECTOR__ 00026 00027 00028 #include <vcg/container/container_allocation_table.h> 00029 #include <vcg/container/entries_allocation_table.h> 00030 00031 #include <assert.h> 00032 00033 namespace vcg { 00043 template <class VALUE_TYPE> 00044 class vector_occ: public std::vector<VALUE_TYPE>{ 00045 typedef vector_occ<VALUE_TYPE> ThisType; 00046 typedef std::vector<VALUE_TYPE> TT; 00047 00048 public: 00049 vector_occ():std::vector<VALUE_TYPE>(){id = ID(); ID()=ID()+1; reserve(1);} 00050 ~vector_occ(); 00051 00052 VALUE_TYPE * Pointer2begin(){ 00053 if(TT::empty()) return (VALUE_TYPE *)id; else return &*std::vector<VALUE_TYPE>::begin(); 00054 } 00055 std::list < CATBase<ThisType>* > attributes; 00056 // override di tutte le funzioni che possono spostare 00057 // l'allocazione in memoria del container 00058 void push_back(const VALUE_TYPE & v); 00059 void pop_back(); 00060 void resize(const unsigned int & size); 00061 void reserve(const unsigned int & size); 00062 00064 template <class ATTR_TYPE> 00065 void Enable(){ 00066 CAT<ThisType,ATTR_TYPE> * cat = CAT<ThisType,ATTR_TYPE>::New(); 00067 cat->Insert(*this); 00068 attributes.push_back(cat); 00069 } 00070 00073 template <class ATTR_TYPE> 00074 bool IsEnabled() const{ 00075 typename std::list < CATBase<ThisType> * >::const_iterator ia; 00076 for(ia = attributes.begin(); ia != attributes.end(); ++ia) 00077 if((*ia)->Id() == CAT<ThisType,ATTR_TYPE>::Id()) 00078 return true; 00079 return false; 00080 } 00081 00082 00085 template <class ATTR_TYPE> 00086 void Disable(){ 00087 typename std::list < CATBase<ThisType> * >::iterator ia; 00088 for(ia = attributes.begin(); ia != attributes.end(); ++ia) 00089 if((*ia)->Id() == CAT<ThisType,ATTR_TYPE>::Id()) 00090 { 00091 (*ia)->Remove(*this); 00092 //delete (*ia); 00093 attributes.erase(ia); 00094 break; 00095 } 00096 } 00097 00098 private: 00099 VALUE_TYPE * old_start; 00100 int id; 00101 static int & ID(){static int id; return id;} 00102 void Update(); 00103 }; 00104 00107 template <class VALUE_TYPE> 00108 void vector_occ<VALUE_TYPE>::push_back(const VALUE_TYPE & v){ 00109 std::vector<VALUE_TYPE>::push_back(v); 00110 Update(); 00111 typename std::list < CATBase<ThisType> * >::iterator ia; 00112 for(ia = attributes.begin(); ia != attributes.end(); ++ia) 00113 (*ia)->AddDataElem(&(*(this->begin())),1); 00114 00115 } 00116 template <class VALUE_TYPE> 00117 void vector_occ<VALUE_TYPE>::pop_back(){ 00118 std::vector<VALUE_TYPE>::pop_back(); 00119 Update(); 00120 } 00121 00122 template <class VALUE_TYPE> 00123 void vector_occ<VALUE_TYPE>::resize(const unsigned int & size){ 00124 std::vector<VALUE_TYPE>::resize(size); 00125 Update(); 00126 typename std::list < CATBase<ThisType> * >::iterator ia; 00127 for(ia = attributes.begin(); ia != attributes.end(); ++ia) 00128 (*ia)-> 00129 Resize(&(*(this->begin())),size); 00130 } 00131 00132 template <class VALUE_TYPE> 00133 void vector_occ<VALUE_TYPE>::reserve(const unsigned int & size){ 00134 std::vector<VALUE_TYPE>::reserve(size); 00135 Update(); 00136 } 00137 00138 template <class VALUE_TYPE> 00139 void vector_occ<VALUE_TYPE>:: 00140 Update(){ 00141 typename std::list < CATBase<ThisType> * >::iterator ia; 00142 if(Pointer2begin() != old_start) 00143 for(ia = attributes.begin(); ia != attributes.end(); ++ia) 00144 (*ia)->Resort(old_start,Pointer2begin()); 00145 00146 old_start = Pointer2begin(); 00147 } 00148 00149 00150 00151 template <class VALUE_TYPE> 00152 vector_occ<VALUE_TYPE>::~vector_occ(){ 00153 typename std::list < CATBase<ThisType> * >::iterator ia; 00154 for(ia = attributes.begin(); ia != attributes.end(); ++ia) 00155 { 00156 (*ia)->Remove(*this); 00157 delete *ia; 00158 } 00159 } 00160 00161 }; // end namespace 00162 #endif