00001
00002 #ifndef GAUDIKERNEL_REFTABLE_H
00003 #define GAUDIKERNEL_REFTABLE_H 1
00004
00005
00006
00007 #include "GaudiKernel/Kernel.h"
00008 #include "GaudiKernel/DataObject.h"
00009 #include "GaudiKernel/StreamBuffer.h"
00010 #include "GaudiKernel/SmartRefVector.h"
00011 #include "GaudiKernel/SmartRef.h"
00012 #include "GaudiKernel/HashMap.h"
00013
00014
00015 static const CLID CLID_RefTable1to1 = 300;
00016 static const CLID CLID_RefTable1toN = 301;
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00046 template <class FROM, class MAPENTRY> class RefTableBase : public DataObject {
00047 public:
00048
00049 typedef FROM KeyType;
00050
00051 typedef MAPENTRY EntryType;
00052
00053 typedef RefTableBase<FROM, EntryType> BaseType;
00057 typedef GaudiUtils::HashMap< const void* , EntryType > TableType;
00059 typedef TableType::iterator iterator;
00061 typedef TableType::const_iterator const_iterator;
00063 CLID m_clid;
00064 private:
00066 TableType m_table;
00071 SmartRef<KeyType> m_fromRef;
00072
00073 protected:
00075 bool insertMapElement ( const KeyType* from, EntryType& to ) {
00076 return m_table.insert( from, to );
00077 }
00079 EntryType* i_reference(const KeyType* from) {
00080 iterator i = m_table.find( from );
00081 if ( i != 0 ) {
00082 return &((*i).second);
00083 }
00084 return 0;
00085 }
00087 const EntryType* i_reference(const KeyType* from) const {
00088 const_iterator i = m_table.find( from );
00089 if ( i != m_table.end() ) {
00090 return &((*i).second);
00091 }
00092 return 0;
00093 }
00094
00095 public:
00097 RefTableBase(const CLID& clid, int len) : m_clid(clid), m_table(len) {
00098 }
00100 virtual ~RefTableBase() {
00101 clear();
00102 }
00104 virtual void clear() {
00105 m_table.clear();
00106 }
00108 iterator begin() {
00109 return m_table.begin();
00110 }
00112 const_iterator begin() const {
00113 return m_table.begin();
00114 }
00116 iterator end() {
00117 return m_table.end();
00118 }
00120 const_iterator end() const {
00121 return m_table.end();
00122 }
00124 long size() const {
00125 return m_table.size();
00126 }
00128 void reserve(int len) {
00129 m_table.reserve(len);
00130 }
00132 virtual StreamBuffer& serialize( StreamBuffer& s ) const {
00133 DataObject::serialize(s) << m_table.size();
00134
00135
00136
00137
00138
00139
00140 return s;
00141 }
00143 virtual StreamBuffer& serialize( StreamBuffer& s ) {
00144 long siz;
00145 DataObject::serialize(s) >> siz;
00146 m_table.reserve(siz);
00147
00148
00149
00150
00151
00152
00153
00154 return s;
00155 }
00156 };
00157
00158 template <class FROM, class TO> class RefTable1to1
00159 : public RefTableBase< FROM , SmartRef<TO> > {
00160 public:
00162 RefTable1to1 (const CLID& clid, int len=16)
00163 : RefTableBase< FROM , SmartRef<TO> >(clid, len)
00164 {
00165 }
00167 virtual ~RefTable1to1() {
00168 }
00170 virtual const CLID& clID() const {
00171 return m_clid;
00172 }
00174 bool insert ( const FROM* from, TO* to ) {
00175 return insertMapElement(from, EntryType(to));
00176 }
00178 bool insert ( const FROM* from, const EntryType& to) {
00179
00180 if ( 0 != to.data() || StreamBuffer::INVALID != to.hintID() ) {
00181 return insertMapElement(from, EntryType(to));
00182 }
00183 return false;
00184 }
00186 TO* reference(const FROM* from) {
00187 EntryType* e = i_reference(from);
00188 return (0 == e) ? 0 : (*e);
00189 }
00190
00192 const TO* reference(const FROM* from) const {
00193 const EntryType* e = i_reference(from);
00194 return (0 == e) ? 0 : (*e);
00195 }
00196
00198 bool isReferenced(const FROM* from, const TO* to ) {
00199 const EntryType* e = i_reference(from);
00200 return (e == 0) ? false : ((*e) == to);
00201 }
00203 bool isReferenced(const FROM* from, const EntryType& to ) {
00204 const EntryType* e = i_reference(from);
00205 return (assoc!=0) ? ((*e)=!to) ? (e->target()==to.target()) : false : false;
00206 }
00207 };
00208
00209 template <class FROM, class TO> class RefTable1toN
00210 : public RefTableBase< FROM , SmartRefVector<TO> > {
00211 public:
00213 RefTable1toN (const CLID& clid, int len=16)
00214 : RefTableBase< FROM , SmartRefVector<TO> >(clid, len) {
00215 }
00217 virtual ~RefTable1toN() {
00218 }
00220 virtual const CLID& clID() const {
00221 return m_clid;
00222 }
00224 bool insert ( const FROM* from, TO* to) {
00225 EntryType* entry = i_reference(from);
00226 if ( 0 == entry ) {
00227 bool result = insertMapElement(from, EntryType());
00228 EntryType* newEntry = i_reference(from);
00229 if ( !( 0 == newEntry) ) {
00230 newEntry->push_back( SmartRef<TO>(to) );
00231 return true;
00232 }
00233 return false;
00234 }
00235 entry->push_back( SmartRef<TO>(to) );
00236 return true;
00237 }
00239 bool insert ( const FROM* from, const SmartRef<TO>& to) {
00240 EntryType* entry = i_reference(from);
00241 if ( 0 == entry ) {
00242 bool result = insertMapElement(from, EntryType());
00243 EntryType* newEntry = i_reference(from);
00244 if ( !(0 == newEntry) ) {
00245 newEntry->push_back( to );
00246 return true;
00247 }
00248 return false;
00249 }
00250 entry->push_back( to );
00251 return true;
00252 }
00254 bool insert ( const FROM* from, const EntryType& to) {
00255 return insertMapElement(from, const_cast<EntryType&>(to));
00256 }
00258 EntryType& reference(const FROM* from) {
00259 static EntryType empty;
00260 EntryType* e = i_reference(from);
00261 return (0 == e) ? empty : *e;
00262 }
00264 const EntryType& reference(const FROM* from) const {
00265 static EntryType empty;
00266 EntryType* e = i_reference(from);
00267 return (0 == e) ? empty : (*e);
00268 }
00270 bool isReferenced(const FROM* from, const EntryType& to ) {
00271 const EntryType* e = i_reference(from);
00272 return (0 == e) ? false : (*e == to);
00273 }
00275 bool isReferenced(const FROM* from, const TO* to ) {
00276 return isReferenced(from, SmartRef<TO>(to));
00277 }
00279 bool isReferenced(const FROM* from, const SmartRef<TO>& to ) {
00280 const EntryType* e = i_reference(from);
00281 if ( 0 != assoc ) {
00282 SmartRefVector<TO>::const_iterator i = std::find(e->begin(), e->end(), to);
00283 return (i == e->end()) ? false : true;
00284 }
00285 return false;
00286 }
00287 };
00288
00289
00290 #endif // GAUDIKERNEL_REFTABLE_H
00291