Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_rroot_obj_list 5 #define tools_rroot_obj_list 6 7 //#include "../vmanip" 8 9 #include "iro" 10 11 #include "object" 12 #include "cids" 13 14 #include "../forit" 15 #include "../scast" 16 17 namespace tools { 18 namespace rroot { 19 20 class obj_list : public virtual iro, protected std::vector<iro*> { //proteced to avoid using std::vector::clear(). 21 typedef std::vector<iro*> parent; 22 public: 23 static const std::string& s_store_class() { 24 static const std::string s_v("TList"); 25 return s_v; 26 } 27 public: 28 static const std::string& s_class() { 29 static const std::string s_v("tools::rroot::obj_list"); 30 return s_v; 31 } 32 public: //iro 33 virtual void* cast(const std::string& a_class) const { 34 if(void* p = cmp_cast<obj_list>(this,a_class)) return p; 35 return 0; 36 } 37 virtual const std::string& s_cls() const {return s_class();} 38 public: 39 static cid id_class() {return obj_list_cid();} 40 virtual void* cast(cid a_class) const { 41 if(void* p = cmp_cast<obj_list>(this,a_class)) {return p;} 42 else return 0; 43 } 44 //virtual void* cast(cid) const {return obj_list_cid();} 45 public: 46 virtual iro* copy() const {return new obj_list(*this);} 47 virtual bool stream(buffer& a_buffer) { 48 safe_clear(); 49 50 short v; 51 unsigned int _s,_c; 52 if(!a_buffer.read_version(v,_s,_c)) return false; 53 54 //::printf("debug : obj_list::stream : version %d, byte count %d\n",v,c); 55 56 {uint32 id,bits; 57 if(!Object_stream(a_buffer,id,bits)) return false;} 58 59 std::string name; 60 if(!a_buffer.read(name)) return false; 61 int nobjects; 62 if(!a_buffer.read(nobjects)) return false; 63 64 //::printf("debug : obj_list : name \"%s\", nobject %d\n", 65 // name.c_str(),nobjects); 66 67 ifac::args args; 68 for (int i=0;i<nobjects;i++) { 69 //::printf("debug : obj_list : n=%d i=%d ...\n",nobjects,i); 70 71 iro* obj; 72 bool created; 73 if(!a_buffer.read_object(m_fac,args,obj,created)){ 74 a_buffer.out() << "tools::rroot::obj_list::stream : can't read object." << std::endl; 75 return false; 76 } 77 78 unsigned char nch; 79 if(!a_buffer.read(nch)) return false; 80 if(nch) { 81 char readOption[256]; 82 if(!a_buffer.read_fast_array(readOption,nch)) return false; 83 readOption[nch] = 0; 84 } 85 if(obj) { 86 if(created) { 87 parent::push_back(obj); 88 m_owns.push_back(true); 89 } else { //someone else may manage this object. 90 parent::push_back(obj); 91 m_owns.push_back(false); 92 } 93 } 94 } 95 96 return a_buffer.check_byte_count(_s,_c,s_store_class()); 97 } 98 public: 99 obj_list(ifac& a_fac) 100 :m_fac(a_fac) 101 { 102 #ifdef TOOLS_MEM 103 mem::increment(s_class().c_str()); 104 #endif 105 } 106 virtual ~obj_list(){ 107 safe_clear(); 108 #ifdef TOOLS_MEM 109 mem::decrement(s_class().c_str()); 110 #endif 111 } 112 public: 113 obj_list(const obj_list& a_from) 114 :iro(a_from) 115 ,parent() 116 ,m_fac(a_from.m_fac) 117 { 118 #ifdef TOOLS_MEM 119 mem::increment(s_class().c_str()); 120 #endif 121 tools_vforcit(iro*,a_from,it) { 122 parent::push_back((*it)->copy()); 123 m_owns.push_back(true); 124 } 125 } 126 obj_list& operator=(const obj_list& a_from) { 127 if(&a_from==this) return *this; 128 129 safe_clear(); 130 131 tools_vforcit(iro*,a_from,it) { 132 parent::push_back((*it)->copy()); 133 m_owns.push_back(true); 134 } 135 136 return *this; 137 } 138 public: 139 parent::const_iterator begin() const {return parent::begin();} 140 parent::iterator begin() {return parent::begin();} 141 parent::const_iterator end() const {return parent::end();} 142 parent::iterator end() {return parent::end();} 143 parent::size_type size() const {return parent::size();} 144 bool empty() const {return parent::empty();} 145 public: 146 void add_object(iro* a_obj) { //take ownership. 147 parent::push_back(a_obj); 148 m_owns.push_back(true); 149 } 150 151 template <class T> 152 T* get_entry(std::ostream& a_out,size_t a_index) const { 153 if(a_index>=size()) return 0; 154 iro* _obj = parent::operator[](a_index); 155 if(!_obj) return 0; 156 T* od = id_cast<iro,T>(*_obj); 157 if(!od) { 158 a_out << "tools::rroot::obj_list::get_entry :" 159 << " object of class " << sout(_obj->s_cls()) << " not a " << T::s_class() << std::endl; 160 return 0; 161 } 162 return od; 163 } 164 165 void safe_clear() { 166 typedef parent::iterator it_t; 167 typedef std::vector<bool>::iterator itb_t; 168 while(!parent::empty()) { 169 it_t it = parent::begin(); 170 itb_t itb = m_owns.begin(); 171 iro* entry = (*it); 172 bool own = (*itb); 173 parent::erase(it); 174 m_owns.erase(itb); 175 if(own) delete entry; 176 } 177 } 178 179 void cleanup() {safe_clear();} 180 protected: 181 ifac& m_fac; 182 std::vector<bool> m_owns; 183 }; 184 185 }} 186 187 #endif