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/HashTable.h"
00013
00014
00015 extern const CLID& CLID_RefTable1to1;
00016 extern const CLID& CLID_RefTable1toN;
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 HashTable< const void* , EntryType > TableType;
00058 #ifdef WIN32
00059
00060 typedef TableType::container_type::iterator iterator;
00062 typedef TableType::container_type::const_iterator const_iterator;
00063 #else
00064
00065 typedef TableType::iterator iterator;
00067 typedef TableType::const_iterator const_iterator;
00068 #endif
00069
00070 CLID m_clid;
00071 private:
00073 TableType m_table;
00074 protected:
00076 bool insertMapElement ( const FROM* from, EntryType& to ) {
00077 return m_table.insert( from, to );
00078 }
00080 EntryType* i_reference(const FROM* from) {
00081 TableType::value_type* i = m_table.find( from );
00082 if ( i != 0 ) {
00083 return &((*i).second);
00084 }
00085 return 0;
00086 }
00088 const EntryType* i_reference(const FROM* from) const {
00089 const TableType::value_type* i = m_table.find( from );
00090 if ( i != m_table.end() ) {
00091 return &((*i).second);
00092 }
00093 return 0;
00094 }
00095
00096 public:
00098 RefTableBase(const CLID& clid, int len) : m_clid(clid), m_table(len) {
00099 }
00101 virtual ~RefTableBase() {
00102 clear();
00103 }
00105 virtual void clear() {
00106 m_table.clear();
00107 }
00109 iterator begin() {
00110 return m_table.begin();
00111 }
00113 const_iterator begin() const {
00114 return m_table.begin();
00115 }
00117 iterator end() {
00118 return m_table.end();
00119 }
00121 const_iterator end() const {
00122 return m_table.end();
00123 }
00125 long size() const {
00126 return m_table.size();
00127 }
00129 void reserve(int len) {
00130 m_table.reserve(len);
00131 }
00133 virtual StreamBuffer& serialize( StreamBuffer& s ) const {
00134 DataObject::serialize(s) << m_table.size();
00135 for (TableType::const_iterator i = m_table.begin(), stop = m_table.end(); i != stop; i++ ) {
00136
00137 }
00138 return s;
00139 }
00141 virtual StreamBuffer& serialize( StreamBuffer& s ) {
00142 long siz;
00143 DataObject::serialize(s) >> siz;
00144 m_table.reserve(siz);
00145 for ( long i = 0; i < siz; i++ ) {
00146 SmartRef<FROM> fromRef;
00147 EntryType entry;
00148
00149
00150 insertMapElement( fromRef, entry);
00151 }
00152 return s;
00153 }
00154 };
00155
00156 template <class FROM, class TO> class RefTable1to1
00157 : public RefTableBase< FROM , SmartRef<TO> > {
00158 public:
00160 RefTable1to1 (const CLID& clid, int len=16)
00161 : RefTableBase< FROM , SmartRef<TO> >(clid, len)
00162 {
00163 }
00165 virtual ~RefTable1to1() {
00166 }
00168 virtual const CLID& clID() const {
00169 return m_clid;
00170 }
00172 bool insert ( const FROM* from, TO* to ) {
00173 return insertMapElement(from, EntryType(to));
00174 }
00176 bool insert ( const FROM* from, const EntryType& to) {
00177
00178 if ( 0 != to.data() || StreamBuffer::INVALID != to.hintID() ) {
00179 return insertMapElement(from, EntryType(to));
00180 }
00181 return false;
00182 }
00184 TO* reference(const FROM* from) {
00185 EntryType* e = i_reference(from);
00186 return (0 == e) ? 0 : (*e);
00187 }
00188
00190 const TO* reference(const FROM* from) const {
00191 const EntryType* e = i_reference(from);
00192 return (0 == e) ? 0 : (*e);
00193 }
00194
00196 bool isReferenced(const FROM* from, const TO* to ) {
00197 const EntryType* e = i_reference(from);
00198 return (e == 0) ? false : ((*e) == to);
00199 }
00201 bool isReferenced(const FROM* from, const EntryType& to ) {
00202 const EntryType* e = i_reference(from);
00203 return (assoc!=0) ? ((*e)=!to) ? (e->target()==to.target()) : false : false;
00204 }
00205 };
00206
00207 template <class FROM, class TO> class RefTable1toN
00208 : public RefTableBase< FROM , SmartRefVector<TO> > {
00209 public:
00211 RefTable1toN (const CLID& clid, int len=16)
00212 : RefTableBase< FROM , SmartRefVector<TO> >(clid, len) {
00213 }
00215 virtual ~RefTable1toN() {
00216 }
00218 virtual const CLID& clID() const {
00219 return m_clid;
00220 }
00222 bool insert ( const FROM* from, TO* to) {
00223 EntryType* entry = i_reference(from);
00224 if ( 0 == entry ) {
00225 bool result = insertMapElement(from, EntryType());
00226 EntryType* newEntry = i_reference(from);
00227 if ( !( 0 == newEntry) ) {
00228 newEntry->push_back( SmartRef<TO>(to) );
00229 return true;
00230 }
00231 return false;
00232 }
00233 entry->push_back( SmartRef<TO>(to) );
00234 return true;
00235 }
00237 bool insert ( const FROM* from, const SmartRef<TO>& to) {
00238 EntryType* entry = i_reference(from);
00239 if ( 0 == entry ) {
00240 bool result = insertMapElement(from, EntryType());
00241 EntryType* newEntry = i_reference(from);
00242 if ( !(0 == newEntry) ) {
00243 newEntry->push_back( to );
00244 return true;
00245 }
00246 return false;
00247 }
00248 entry->push_back( to );
00249 return true;
00250 }
00252 bool insert ( const FROM* from, const EntryType& to) {
00253 return insertMapElement(from, const_cast<EntryType&>(to));
00254 }
00256 EntryType& reference(const FROM* from) {
00257 static EntryType empty;
00258 EntryType* e = i_reference(from);
00259 return (0 == e) ? empty : *e;
00260 }
00262 const EntryType& reference(const FROM* from) const {
00263 static EntryType empty;
00264 EntryType* e = i_reference(from);
00265 return (0 == e) ? empty : (*e);
00266 }
00268 bool isReferenced(const FROM* from, const EntryType& to ) {
00269 const EntryType* e = i_reference(from);
00270 return (0 == e) ? false : (*e == to);
00271 }
00273 bool isReferenced(const FROM* from, const TO* to ) {
00274 return isReferenced(from, SmartRef<TO>(to));
00275 }
00277 bool isReferenced(const FROM* from, const SmartRef<TO>& to ) {
00278 const EntryType* e = i_reference(from);
00279 if ( 0 != assoc ) {
00280 SmartRefVector<TO>::const_iterator i = std::find(e->begin(), e->end(), to);
00281 return (i == e->end()) ? false : true;
00282 }
00283 return false;
00284 }
00285 };
00286
00287
00288 #endif // GAUDIKERNEL_REFTABLE_H