Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_sg_holder 4 #ifndef tools_sg_holder 5 #define tools_sg_holder 5 #define tools_sg_holder 6 6 7 // class to manage an object. 7 // class to manage an object. 8 // Only one holder owns the object. In case 8 // Only one holder owns the object. In case 9 // of holder copy(), the new holder receives a 9 // of holder copy(), the new holder receives a null object. 10 10 11 #include "node" 11 #include "node" 12 12 13 #include "sf_string" 13 #include "sf_string" 14 14 15 namespace tools { 15 namespace tools { 16 namespace sg { 16 namespace sg { 17 17 18 class base_holder : public node { 18 class base_holder : public node { 19 TOOLS_NODE(base_holder,tools::sg::base_holde 19 TOOLS_NODE(base_holder,tools::sg::base_holder,node) 20 public: 20 public: 21 base_holder(const std::string& a_name):paren 21 base_holder(const std::string& a_name):parent(),m_name(a_name) {} 22 virtual ~base_holder(){} 22 virtual ~base_holder(){} 23 public: 23 public: 24 base_holder(const base_holder& a_from):paren 24 base_holder(const base_holder& a_from):parent(a_from),m_name(a_from.m_name) {} 25 base_holder& operator=(const base_holder& a_ 25 base_holder& operator=(const base_holder& a_from){ 26 parent::operator=(a_from); 26 parent::operator=(a_from); 27 m_name = a_from.m_name; 27 m_name = a_from.m_name; 28 return *this; 28 return *this; 29 } 29 } 30 public: 30 public: 31 const std::string& name() const {return m_na 31 const std::string& name() const {return m_name;} 32 protected: 32 protected: 33 std::string m_name; 33 std::string m_name; 34 }; 34 }; 35 35 36 template <class T> 36 template <class T> 37 class holder : public base_holder { 37 class holder : public base_holder { 38 typedef base_holder parent; 38 typedef base_holder parent; 39 public: 39 public: 40 //WARNING : we do not put the T class name i 40 //WARNING : we do not put the T class name in the name of this class. 41 // We put it in the class_name fiel 41 // We put it in the class_name field. 42 // We do that because of the bsg fi 42 // We do that because of the bsg file format in order to be able 43 // to read back the object without 43 // to read back the object without having the T class around. 44 TOOLS_T_SCLASS(T,tools::sg::holder) 44 TOOLS_T_SCLASS(T,tools::sg::holder) 45 public: 45 public: 46 virtual void* cast(const std::string& a_clas 46 virtual void* cast(const std::string& a_class) const { 47 if(void* p = cmp_cast< holder<T> >(this,a_ 47 if(void* p = cmp_cast< holder<T> >(this,a_class)) {return p;} 48 return parent::cast(a_class); 48 return parent::cast(a_class); 49 } 49 } 50 virtual node* copy() const {return new holde 50 virtual node* copy() const {return new holder(*this);} 51 virtual const std::string& s_cls() const {re 51 virtual const std::string& s_cls() const {return s_class();} 52 public: 52 public: 53 sf_string class_name; 53 sf_string class_name; 54 public: 54 public: 55 virtual const desc_fields& node_desc_fields( 55 virtual const desc_fields& node_desc_fields() const { 56 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::hol 56 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::holder) 57 static const desc_fields s_v(parent::node_ 57 static const desc_fields s_v(parent::node_desc_fields(),1, //WARNING : take care of count. 58 TOOLS_ARG_FIELD_DESC(class_name) 58 TOOLS_ARG_FIELD_DESC(class_name) 59 ); 59 ); 60 return s_v; 60 return s_v; 61 } 61 } 62 private: 62 private: 63 void add_fields(){ 63 void add_fields(){ 64 add_field(&class_name); 64 add_field(&class_name); 65 } 65 } 66 public: 66 public: 67 holder(T* a_obj = 0,const std::string& a_nam 67 holder(T* a_obj = 0,const std::string& a_name = "",bool a_own=true) 68 :parent(a_name) 68 :parent(a_name) 69 ,class_name(T::s_class()) 69 ,class_name(T::s_class()) 70 ,m_obj(a_obj) //it takes a_obj ownership. 70 ,m_obj(a_obj) //it takes a_obj ownership. 71 ,m_own(a_own) 71 ,m_own(a_own) 72 { 72 { 73 add_fields(); 73 add_fields(); 74 } 74 } 75 75 76 virtual ~holder(){if(m_own) delete m_obj;} 76 virtual ~holder(){if(m_own) delete m_obj;} 77 public: 77 public: 78 //any copy of a holder does NOT own any obje 78 //any copy of a holder does NOT own any object (and we empty the name). 79 holder(const holder& a_from) 79 holder(const holder& a_from) 80 :parent(a_from) 80 :parent(a_from) 81 ,class_name(std::string()) 81 ,class_name(std::string()) 82 ,m_obj(0) 82 ,m_obj(0) 83 ,m_own(false) 83 ,m_own(false) 84 { 84 { 85 parent::m_name.clear(); 85 parent::m_name.clear(); 86 add_fields(); 86 add_fields(); 87 } 87 } 88 holder& operator=(const holder& a_from){ 88 holder& operator=(const holder& a_from){ 89 parent::operator=(a_from); 89 parent::operator=(a_from); 90 class_name.value().clear(); 90 class_name.value().clear(); 91 m_obj = 0; 91 m_obj = 0; 92 m_own = false; 92 m_own = false; 93 parent::m_name.clear(); 93 parent::m_name.clear(); 94 return *this; 94 return *this; 95 } 95 } 96 public: 96 public: 97 const T* object() const {return m_obj;} 97 const T* object() const {return m_obj;} 98 T* object() {return m_obj;} 98 T* object() {return m_obj;} 99 protected: 99 protected: 100 T* m_obj; 100 T* m_obj; 101 bool m_own; 101 bool m_own; 102 }; 102 }; 103 103 104 template <class T> 104 template <class T> 105 inline holder<T>* cast_holder(node& a_node) { 105 inline holder<T>* cast_holder(node& a_node) { 106 typedef holder<T> h_t; 106 typedef holder<T> h_t; 107 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 107 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 108 if(!_h) return 0; 108 if(!_h) return 0; 109 return (_h->class_name.value()==T::s_class() 109 return (_h->class_name.value()==T::s_class()?_h:0); 110 } 110 } 111 111 112 template <class T> 112 template <class T> 113 inline const holder<T>* cast_holder(const node 113 inline const holder<T>* cast_holder(const node& a_node) { 114 typedef holder<T> h_t; 114 typedef holder<T> h_t; 115 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 115 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 116 if(!_h) return 0; 116 if(!_h) return 0; 117 return (_h->class_name.value()==T::s_class() 117 return (_h->class_name.value()==T::s_class()?_h:0); 118 } 118 } 119 119 120 template <class T> 120 template <class T> 121 inline const T* cast_holder_object(const node& 121 inline const T* cast_holder_object(const node& a_node) { 122 typedef holder<T> h_t; 122 typedef holder<T> h_t; 123 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 123 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 124 if(!_h) return 0; 124 if(!_h) return 0; 125 return (_h->class_name.value()==T::s_class() 125 return (_h->class_name.value()==T::s_class()?_h->object():0); 126 } 126 } 127 template <class T> 127 template <class T> 128 inline T* cast_holder_object(node& a_node) { 128 inline T* cast_holder_object(node& a_node) { 129 typedef holder<T> h_t; 129 typedef holder<T> h_t; 130 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 130 h_t* _h = (h_t*)a_node.cast(h_t::s_class()); 131 if(!_h) return 0; 131 if(!_h) return 0; 132 return (_h->class_name.value()==T::s_class() 132 return (_h->class_name.value()==T::s_class()?_h->object():0); 133 } 133 } 134 134 135 template <class T> 135 template <class T> 136 inline void remove_holders(std::vector<node*>& 136 inline void remove_holders(std::vector<node*>& a_vec){ 137 typedef holder<T> h_t; 137 typedef holder<T> h_t; 138 138 139 std::vector<node*>::iterator it; 139 std::vector<node*>::iterator it; 140 for(it=a_vec.begin();it!=a_vec.end();) { 140 for(it=a_vec.begin();it!=a_vec.end();) { 141 if(h_t* h = cast_holder<T>(*(*it))){ 141 if(h_t* h = cast_holder<T>(*(*it))){ 142 it = a_vec.erase(it); 142 it = a_vec.erase(it); 143 delete h; 143 delete h; 144 continue; 144 continue; 145 } 145 } 146 146 147 ++it; 147 ++it; 148 } 148 } 149 } 149 } 150 150 151 template <class T> 151 template <class T> 152 inline void remove_holders(std::vector<node*>& 152 inline void remove_holders(std::vector<node*>& a_vec,const std::string& a_name){ 153 typedef holder<T> h_t; 153 typedef holder<T> h_t; 154 154 155 std::vector<node*>::iterator it; 155 std::vector<node*>::iterator it; 156 for(it=a_vec.begin();it!=a_vec.end();) { 156 for(it=a_vec.begin();it!=a_vec.end();) { 157 if(h_t* h = cast_holder<T>(*(*it))){ 157 if(h_t* h = cast_holder<T>(*(*it))){ 158 if(h->name()==a_name) { 158 if(h->name()==a_name) { 159 it = a_vec.erase(it); 159 it = a_vec.erase(it); 160 delete h; 160 delete h; 161 continue; 161 continue; 162 } 162 } 163 } 163 } 164 164 165 ++it; 165 ++it; 166 } 166 } 167 } 167 } 168 168 169 template <class T> 169 template <class T> 170 inline T* find_holder(std::vector<node*>& a_ve 170 inline T* find_holder(std::vector<node*>& a_vec,const std::string& a_name) { 171 //return the first named found. 171 //return the first named found. 172 172 173 typedef holder<T> h_t; 173 typedef holder<T> h_t; 174 std::vector<node*>::iterator it; 174 std::vector<node*>::iterator it; 175 for(it=a_vec.begin();it!=a_vec.end();++it) { 175 for(it=a_vec.begin();it!=a_vec.end();++it) { 176 if(h_t* h = cast_holder<T>(*(*it))){ 176 if(h_t* h = cast_holder<T>(*(*it))){ 177 if(h->name()==a_name) return h->object() 177 if(h->name()==a_name) return h->object(); 178 } 178 } 179 } 179 } 180 return 0; 180 return 0; 181 } 181 } 182 182 183 template <class T> 183 template <class T> 184 inline T* find_first_holder(std::vector<node*> 184 inline T* find_first_holder(std::vector<node*>& a_vec){ 185 //return the first T found. 185 //return the first T found. 186 186 187 typedef holder<T> h_t; 187 typedef holder<T> h_t; 188 std::vector<node*>::iterator it; 188 std::vector<node*>::iterator it; 189 for(it=a_vec.begin();it!=a_vec.end();++it) { 189 for(it=a_vec.begin();it!=a_vec.end();++it) { 190 if(h_t* h = cast_holder<T>(*(*it))) return 190 if(h_t* h = cast_holder<T>(*(*it))) return h->object(); 191 } 191 } 192 192 193 193 194 return 0; 194 return 0; 195 } 195 } 196 196 197 }} 197 }} 198 198 199 #endif 199 #endif