00001 //StiCompositeTreeNode 00002 //M.L. Miller (Yale Software) 00003 //07/01 00004 00059 #ifndef StiCompositeTreeNode_H 00060 #define StiCompositeTreeNode_H 00061 00062 #include "Stiostream.h" 00063 #include <iterator> 00064 #include <vector> 00065 #include <string> 00066 #include <algorithm> 00067 00068 using namespace std; 00069 00070 /* 00071 using std::find; 00072 using std::vector; 00073 using std::string; 00074 using std::cout; 00075 using std::ostream; 00076 using std::endl; 00077 */ 00078 00082 struct StiOrderKey 00083 { 00084 StiOrderKey() 00085 : key(0.), index(0) {}; 00086 StiOrderKey(double k, unsigned int i) 00087 : key(k), index(i) {}; 00088 00089 double key; 00090 unsigned int index; 00091 }; 00092 00093 template <class T> 00094 class StiCompositeTreeNode 00095 { 00096 public: 00097 00099 StiCompositeTreeNode(); 00100 00102 virtual ~StiCompositeTreeNode(); 00103 00104 //Sets 00105 void reset(){;} 00106 void unset(){;} 00107 00109 void setName(const string&); 00110 00112 void setOrderKey(const StiOrderKey&); 00113 00115 void setData(T*); 00116 00117 //Gets 00118 00120 const string& getName() const; 00121 00123 unsigned int getChildCount() const; 00124 00126 StiCompositeTreeNode* getParent() const; 00127 00129 const StiOrderKey& getOrderKey() const; 00130 00132 T* getData() const; 00133 00134 //Action 00135 00137 virtual void add(StiCompositeTreeNode*); 00138 00139 public: 00140 //provide random access iterators to daughters 00141 00143 typedef vector<StiCompositeTreeNode *> vec_type; 00144 00146 typedef vector<StiCompositeTreeNode *> StiCompositeTreeNodeVector; 00147 00149 typename vec_type::iterator whereInParent() { 00150 return (mparent) ? (mparent->begin()+mkey.index) : mVec.end(); 00151 } 00152 00154 typename vec_type::iterator begin() {return mVec.begin();} 00155 00157 typename vec_type::iterator end() {return mVec.end();} 00158 00160 typename vec_type::const_iterator begin() const {return mVec.begin();} 00161 00163 typename vec_type::const_iterator end() const {return mVec.end();} 00164 00166 typename vec_type::reverse_iterator rbegin() {return mVec.rbegin();} 00167 00169 typename vec_type::reverse_iterator rend() {return mVec.rend();} 00170 00172 typename vec_type::const_reverse_iterator rbegin() const {return mVec.rbegin();} 00173 00175 typename vec_type::const_reverse_iterator rend() const {return mVec.rend();} 00176 00177 private: 00178 00181 void setParent(StiCompositeTreeNode* val); 00182 00184 vec_type mVec; 00185 00187 StiCompositeTreeNode* mparent; 00188 00190 T* mdata; 00191 00193 StiOrderKey mkey; 00194 00196 string mname; 00197 }; 00198 00199 //Implementation 00200 00204 template <class T> 00205 StiCompositeTreeNode<T>::StiCompositeTreeNode() 00206 : mparent(0), mdata(0) 00207 { 00208 mkey.key=0.; 00209 mkey.index=0; 00210 } 00211 00212 template <class T> 00213 StiCompositeTreeNode<T>::~StiCompositeTreeNode() 00214 { 00215 } 00216 00217 template <class T> 00218 inline void StiCompositeTreeNode<T>::setName(const string& val) 00219 { 00220 mname = val; 00221 } 00222 00223 template <class T> 00224 inline void StiCompositeTreeNode<T>::setOrderKey(const StiOrderKey& val) 00225 { 00226 mkey=val; 00227 } 00228 00232 template <class T> 00233 inline void StiCompositeTreeNode<T>::setData(T* val) 00234 { 00235 mdata=val; 00236 } 00237 00238 template <class T> 00239 inline const string& StiCompositeTreeNode<T>::getName() const 00240 { 00241 return mname; 00242 } 00243 00244 template <class T> 00245 inline unsigned int StiCompositeTreeNode<T>::getChildCount() const 00246 { 00247 return mVec.size(); 00248 } 00249 00250 template <class T> 00251 inline StiCompositeTreeNode<T>* 00252 StiCompositeTreeNode<T>::getParent() const 00253 { 00254 return mparent; 00255 } 00256 00257 template <class T> 00258 inline const StiOrderKey& StiCompositeTreeNode<T>::getOrderKey() const 00259 { 00260 return mkey; 00261 } 00262 00263 template <class T> 00264 inline T* StiCompositeTreeNode<T>::getData() const 00265 { 00266 return mdata; 00267 } 00268 00279 template <class T> 00280 void StiCompositeTreeNode<T>::add(StiCompositeTreeNode* newChild) 00281 { 00282 if (!newChild) return; 00283 typename StiCompositeTreeNodeVector::iterator where = find(mVec.begin(), mVec.end(), 00284 newChild); 00285 //Remove if we see an efficiency penalty 00286 if (where!=end()) { 00287 cout <<"StiCompositeTreeNode::add(). ERROR:\t"; 00288 cout <<"Child Already exists. Abort"<<endl; 00289 return; 00290 } 00291 //else add to list, set parent 00292 newChild->setParent(this); 00293 mVec.push_back(newChild); 00294 } 00295 00299 template <class T> 00300 inline void StiCompositeTreeNode<T>::setParent(StiCompositeTreeNode* val) 00301 { 00302 if (mparent) { 00303 cout <<"StiCompositeTreeNode::setParent()\tError:\t"; 00304 cout <<"parent already exists"<<endl; 00305 return; 00306 } 00307 mparent=val; 00308 return; 00309 } 00310 00311 // \warning This iterator makes no sense for nodes with no parent. In 00312 00313 /* \warning This iterator makes no sense for nodes with no parent. In 00314 that case whereInParent() returns end(). Therefore, a safe call to whereInParent() 00315 would be as follows: <code> \n 00316 StiCompositeTreeNode<T>::vec_type::iterator where = node->whereInParent(); \n 00317 if (where!=node->end()) {\\you're ok \n 00318 } 00319 <\code> 00320 00321 template <class T> 00322 StiCompositeTreeNode<T>::vec_type::iterator //return type 00323 StiCompositeTreeNode<T>::whereInParent() 00324 { 00325 return (mparent) ? (mparent->begin()+mkey.index) : mVec.end(); 00326 } 00327 00328 template <class T> 00329 StiCompositeTreeNode<T>::vec_type::iterator //return type 00330 StiCompositeTreeNode<T>::begin() 00331 { 00332 return mVec.begin(); 00333 } 00334 00335 template <class T> 00336 StiCompositeTreeNode<T>::vec_type::iterator //return type 00337 StiCompositeTreeNode<T>::end() 00338 { 00339 return mVec.end(); 00340 } 00341 00342 template <class T> 00343 StiCompositeTreeNode<T>::vec_type::const_iterator //return type 00344 StiCompositeTreeNode<T>::begin() const 00345 { 00346 return mVec.begin(); 00347 } 00348 00349 template <class T> 00350 StiCompositeTreeNode<T>::vec_type::const_iterator //return type 00351 StiCompositeTreeNode<T>::end() const 00352 { 00353 return mVec.end(); 00354 } 00355 00356 template <class T> 00357 StiCompositeTreeNode<T>::vec_type::reverse_iterator //return type 00358 StiCompositeTreeNode<T>::rbegin() 00359 { 00360 return mVec.rbegin(); 00361 } 00362 00363 template <class T> 00364 StiCompositeTreeNode<T>::vec_type::reverse_iterator //return type 00365 StiCompositeTreeNode<T>::rend() 00366 { 00367 return mVec.rend(); 00368 } 00369 00370 template <class T> 00371 StiCompositeTreeNode<T>::vec_type::const_reverse_iterator //return type 00372 StiCompositeTreeNode<T>::rbegin() const 00373 { 00374 return mVec.rbegin(); 00375 } 00376 00377 template <class T> 00378 StiCompositeTreeNode<T>::vec_type::const_reverse_iterator //return type 00379 StiCompositeTreeNode<T>::rend() const 00380 { 00381 return mVec.rend(); 00382 } 00383 */ 00384 00385 //For now, include some typdefs that will make for easy user includes 00386 #include "StiDetector.h" 00387 typedef StiDetector data_t; 00388 00389 #ifndef __CINT__ 00390 typedef StiCompositeTreeNode<StiDetector> StiDetectorNode; 00391 #else 00392 class StiDetectorNode; 00393 #endif 00394 typedef vector<StiDetectorNode*> StiDetectorNodeVector; 00395 00396 //non-members 00397 inline ostream& operator<<(ostream& os, const StiOrderKey& theKey) 00398 { 00399 return os<<"key: "<<theKey.key<<" index: "<<theKey.index; 00400 } 00401 00402 #endif
1.5.9