00001
00002 #ifndef LHCBEVENT_REFTABLE_H
00003 #define LHCBEVENT_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/HashTable.h"
00013
00014
00015
00016 extern const CLID& CLID_RefTable1to1;
00017 extern const CLID& CLID_RefTable1toN;
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00047 template <class FROM, class MAPENTRY> class RefTableBase : public DataObject {
00048 public:
00049
00050 typedef FROM KeyType;
00051
00052 typedef MAPENTRY EntryType;
00053
00054 typedef RefTableBase<FROM, EntryType> BaseType;
00058 typedef HashTable< const void* , EntryType > TableType;
00059 #ifdef WIN32
00060
00061 typedef TableType::container_type::iterator iterator;
00063 typedef TableType::container_type::const_iterator const_iterator;
00064 #else
00065
00066 typedef TableType::iterator iterator;
00068 typedef TableType::const_iterator const_iterator;
00069 #endif
00070
00071 CLID m_clid;
00072 private:
00074 TableType m_table;
00075 protected:
00077 bool insertMapElement ( const FROM* from, EntryType& to ) {
00078 return m_table.insert( from, to );
00079 }
00081 EntryType* i_reference(const FROM* from) {
00082 TableType::value_type* i = m_table.find( from );
00083 if ( i != 0 ) {
00084 return &((*i).second);
00085 }
00086 return 0;
00087 }
00089 const EntryType* i_reference(const FROM* from) const {
00090 const TableType::value_type* i = m_table.find( from );
00091 if ( i != m_table.end() ) {
00092 return &((*i).second);
00093 }
00094 return 0;
00095 }
00096
00097 public:
00099 RefTableBase(const CLID& clid, int len) : m_clid(clid), m_table(len) {
00100 }
00102 virtual ~RefTableBase() {
00103 clear();
00104 }
00106 virtual void clear() {
00107 m_table.clear();
00108 }
00110 iterator begin() {
00111 return m_table.begin();
00112 }
00114 const_iterator begin() const {
00115 return m_table.begin();
00116 }
00118 iterator end() {
00119 return m_table.end();
00120 }
00122 const_iterator end() const {
00123 return m_table.end();
00124 }
00126 long size() const {
00127 return m_table.size();
00128 }
00130 void reserve(int len) {
00131 m_table.reserve(len);
00132 }
00134 virtual StreamBuffer& serialize( StreamBuffer& s ) const {
00135 DataObject::serialize(s) << m_table.size();
00136 for (TableType::const_iterator i = m_table.begin(), stop = m_table.end(); i != stop; i++ ) {
00137 s << (*i).second(this);
00138 }
00139 return s;
00140 }
00142 virtual StreamBuffer& serialize( StreamBuffer& s ) {
00143 long siz;
00144 DataObject::serialize(s) >> siz;
00145 m_table.reserve(siz);
00146 for ( long i = 0; i < siz; i++ ) {
00147 SmartRef<FROM> fromRef;
00148 EntryType entry;
00149
00150
00151 insertMapElement( fromRef, entry);
00152 }
00153 return s;
00154 }
00155 };
00156
00157 template <class FROM, class TO> class RefTable1to1
00158 : public RefTableBase< FROM , SmartRef<TO> > {
00159 public:
00161 RefTable1to1 (const CLID& clid, int len=16)
00162 : RefTableBase< FROM , SmartRef<TO> >(clid, len)
00163 {
00164 }
00166 virtual ~RefTable1to1() {
00167 }
00169 virtual const CLID& clID() const {
00170 return m_clid;
00171 }
00173 bool insert ( const FROM* from, TO* to ) {
00174 return insertMapElement(from, EntryType(to));
00175 }
00177 bool insert ( const FROM* from, const EntryType& to) {
00178
00179 if ( 0 != to.data() || StreamBuffer::INVALID != to.hintID() ) {
00180 return insertMapElement(from, EntryType(to));
00181 }
00182 return false;
00183 }
00185 TO* reference(const FROM* from) {
00186 EntryType* e = i_reference(from);
00187 return (0 == e) ? 0 : (*e);
00188 }
00190 const TO* reference(const FROM* from) const {
00191 const EntryType* e = i_reference(from);
00192 return (0 == e) ? 0 : (*e);
00193 }
00195 bool isReferenced(const FROM* from, const TO* to ) {
00196 const EntryType* e = i_reference(from);
00197 return (e == 0) ? false : ((*e) == to);
00198 }
00200 bool isReferenced(const FROM* from, const EntryType& to ) {
00201 const EntryType* e = i_reference(from);
00202 return (assoc!=0) ? ((*e)=!to) ? (e->target()==to.target()) : false : false;
00203 }
00204 };
00205
00206 template <class FROM, class TO> class RefTable1toN
00207 : public RefTableBase< FROM , SmartRefVector<TO> > {
00208 public:
00210 RefTable1toN (const CLID& clid, int len=16)
00211 : RefTableBase< FROM , SmartRefVector<TO> >(clid, len) {
00212 }
00214 virtual ~RefTable1toN() {
00215 }
00217 virtual const CLID& clID() const {
00218 return m_clid;
00219 }
00221 bool insert ( const FROM* from, TO* to) {
00222 EntryType& entry = i_reference(from);
00223 if ( entry == empty() ) {
00224 bool result = insertMapElement(from, EntryType());
00225 EntryType& newEntry = i_reference(from);
00226 if ( newEntry != empty() ) {
00227 newEntry.push_back( SmartRef<TO>(to) );
00228 return true;
00229 }
00230 return false;
00231 }
00232 entry.push_back( SmartRef<TO>(to) );
00233 return true;
00234 }
00236 bool insert ( const FROM* from, const SmartRef<TO>& to) {
00237 EntryType& entry = i_reference(from);
00238 if ( entry == empty() ) {
00239 bool result = insertMapElement(from, EntryType());
00240 EntryType& newEntry = i_reference(from);
00241 if ( newEntry != empty() ) {
00242 newEntry.push_back( to );
00243 return true;
00244 }
00245 return false;
00246 }
00247 entry.push_back( to );
00248 return true;
00249 }
00251 bool insert ( const FROM* from, const EntryType& to) {
00252 return insertMapElement(from, const_cast<EntryType&>(to));
00253 }
00255 EntryType& reference(const FROM* from) {
00256 static EntryType empty;
00257 EntryType* e = i_reference(from);
00258 return (0 == e) ? empty : *e;
00259 }
00261 const EntryType& reference(const FROM* from) const {
00262 static EntryType empty;
00263 EntryType* e = i_reference(from);
00264 return (0 == e) ? empty : (*e);
00265 }
00267 bool isReferenced(const FROM* from, const EntryType& to ) {
00268 const EntryType* e = i_reference(from);
00269 return (0 == e) ? false : (*e == to);
00270 }
00272 bool isReferenced(const FROM* from, const TO* to ) {
00273 return isReferenced(from, SmartRef<TO>(to));
00274 }
00276 bool isReferenced(const FROM* from, const SmartRef<TO>& to ) {
00277 const EntryType* e = i_reference(from);
00278 if ( 0 != assoc ) {
00279 SmartRefVector<TO>::const_iterator i = std::find(e->begin(), e->end(), to);
00280 return (i == e->end()) ? false : true;
00281 }
00282 return false;
00283 }
00284 };
00285
00286
00287 #endif // LHCBEVENT_REFTABLE_H