1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* 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 <vcg/container/container_allocation_table.h>
#include <vcg/container/entries_allocation_table.h>
#include <assert.h>
namespace vcg {
/*@{*/
/*!
* This class represent a vector_occ. A vector_occ is derived by a std::vector.
* The characteristic of a vector_occ is that you can add (at run time) new attributes
* to the container::value_type elements contained in the vector. (see the example..)
* The position in memory of a traced vector is kept by the Container Allocation Table,
* which is a (unique) list of vector_occ positions.
*/
template <class VALUE_TYPE>
class vector_occ: public std::vector<VALUE_TYPE>{
typedef vector_occ<VALUE_TYPE> ThisType;
typedef std::vector<VALUE_TYPE> TT;
public:
vector_occ():std::vector<VALUE_TYPE>(){id = ID(); ID()=ID()+1; reserve(1);}
~vector_occ();
VALUE_TYPE * Pointer2begin(){
if(TT::empty()) return (VALUE_TYPE *)id; else return &*std::vector<VALUE_TYPE>::begin();
}
std::list < CATBase<ThisType>* > 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);
/// this function enable the use of an optional attribute (see...)
template <class ATTR_TYPE>
void Enable(){
CAT<ThisType,ATTR_TYPE> * cat = CAT<ThisType,ATTR_TYPE>::New();
cat->Insert(*this);
attributes.push_back(cat);
}
/// this function returns true if the attribute in the template parameter is enabled
/// Note: once an attribute is disabled, its data is lost (the memory freed)
template <class ATTR_TYPE>
bool IsEnabled() const{
typename std::list < CATBase<ThisType> * >::const_iterator ia;
for(ia = attributes.begin(); ia != attributes.end(); ++ia)
if((*ia)->Id() == CAT<ThisType,ATTR_TYPE>::Id())
return true;
return false;
}
/// this function disable the use of an optional attribute (see...)
/// Note: once an attribute is disabled, its data is lost (the memory freed)
template <class ATTR_TYPE>
void Disable(){
typename std::list < CATBase<ThisType> * >::iterator ia;
for(ia = attributes.begin(); ia != attributes.end(); ++ia)
if((*ia)->Id() == CAT<ThisType,ATTR_TYPE>::Id())
{
(*ia)->Remove(*this);
//delete (*ia);
attributes.erase(ia);
break;
}
}
private:
VALUE_TYPE * old_start;
int id;
static int & ID(){static int id; return id;}
void Update();
};
/*@}*/
template <class VALUE_TYPE>
void vector_occ<VALUE_TYPE>::push_back(const VALUE_TYPE & v){
std::vector<VALUE_TYPE>::push_back(v);
Update();
typename std::list < CATBase<ThisType> * >::iterator ia;
for(ia = attributes.begin(); ia != attributes.end(); ++ia)
(*ia)->AddDataElem(&(*(this->begin())),1);
}
template <class VALUE_TYPE>
void vector_occ<VALUE_TYPE>::pop_back(){
std::vector<VALUE_TYPE>::pop_back();
Update();
}
template <class VALUE_TYPE>
void vector_occ<VALUE_TYPE>::resize(const unsigned int & size){
std::vector<VALUE_TYPE>::resize(size);
Update();
typename std::list < CATBase<ThisType> * >::iterator ia;
for(ia = attributes.begin(); ia != attributes.end(); ++ia)
(*ia)->
Resize(&(*(this->begin())),size);
}
template <class VALUE_TYPE>
void vector_occ<VALUE_TYPE>::reserve(const unsigned int & size){
std::vector<VALUE_TYPE>::reserve(size);
Update();
}
template <class VALUE_TYPE>
void vector_occ<VALUE_TYPE>::
Update(){
typename std::list < CATBase<ThisType> * >::iterator ia;
if(Pointer2begin() != old_start)
for(ia = attributes.begin(); ia != attributes.end(); ++ia)
(*ia)->Resort(old_start,Pointer2begin());
old_start = Pointer2begin();
}
template <class VALUE_TYPE>
vector_occ<VALUE_TYPE>::~vector_occ(){
typename std::list < CATBase<ThisType> * >::iterator ia;
for(ia = attributes.begin(); ia != attributes.end(); ++ia)
{
(*ia)->Remove(*this);
delete *ia;
}
}
}; // end namespace
#endif
|