00001 // $Id $ 00002 #ifndef GAUDIKERNEL_KEYEDOBJECT_H 00003 #define GAUDIKERNEL_KEYEDOBJECT_H 00004 00005 namespace GaudiDict { 00006 template <class T> struct KeyedObjectDict; 00007 } 00008 00009 // Framework include files 00010 #include "GaudiKernel/ContainedObject.h" 00011 #include "GaudiKernel/KeyedTraits.h" 00012 #include "GaudiKernel/KeyedContainer.h" 00013 00028 template < class KEY > 00029 class KeyedObject : public ContainedObject { 00030 friend struct GaudiDict::KeyedObjectDict<KEY>; 00031 public: 00033 typedef KEY key_type; 00034 00035 protected: 00037 typedef typename Containers::key_traits<key_type> traits; 00039 //#ifdef _WIN32 00040 // friend traits; 00041 //#else 00042 friend struct Containers::key_traits<key_type>; 00043 //#endif 00044 00046 key_type m_key; 00048 long m_refCount; 00050 bool m_hasKey; 00052 unsigned long addRef(); 00054 unsigned long release(); 00059 void setKey(const key_type& key); 00060 public: 00062 KeyedObject() : m_refCount(0), m_hasKey(false) { } 00066 KeyedObject(const key_type& kval):m_key(kval),m_refCount(0),m_hasKey(true) { } 00068 virtual ~KeyedObject(); 00070 const key_type& key() const { return m_key; } 00072 bool hasKey() const { return m_hasKey; } 00073 virtual long index() const { return traits::identifier(m_key); } 00075 virtual StreamBuffer& serialize( StreamBuffer& s ) const; 00077 virtual StreamBuffer& serialize( StreamBuffer& s ); 00078 private: 00080 KeyedObject(const KeyedObject& copy) : ContainedObject(copy) { } 00081 }; 00082 00083 /* 00084 * 00085 * 00086 * Inline code for keyed KeyedObject class 00087 * 00088 */ 00089 00090 // Standard destructor. 00091 template<class KEY> inline 00092 KeyedObject<KEY>::~KeyedObject() 00093 { 00094 ObjectContainerBase* p = const_cast<ObjectContainerBase*>(parent()); 00095 if ( p ) { 00096 setParent(0); 00097 p->remove(this); 00098 } 00099 } 00100 00101 // Add reference to object (Increase reference counter). 00102 template<class KEY> inline 00103 unsigned long KeyedObject<KEY>::addRef() { 00104 return ++m_refCount; 00105 } 00106 00107 // Release reference. If the reference count is ZERO, delete the object. 00108 template<class KEY> inline 00109 unsigned long KeyedObject<KEY>::release() { 00110 long cnt = --m_refCount; 00111 if ( cnt <= 0 ) { 00112 delete this; 00113 } 00114 return cnt; 00115 } 00116 00117 /* Set object key. The key for consistency reasons 00118 can be set only once for the object. Any attempt to 00119 redefine the key results in an exception. 00120 */ 00121 template<class KEY> inline 00122 void KeyedObject<KEY>::setKey(const key_type& key) { 00123 if ( !m_hasKey ) { 00124 m_key = key; 00125 m_hasKey = true; 00126 return; 00127 } 00128 Containers::cannotAssignObjectKey(); 00129 } 00130 00131 // Serialize the object for writing 00132 template<class KEY> inline 00133 StreamBuffer& KeyedObject<KEY>::serialize( StreamBuffer& s ) const { 00134 return ContainedObject::serialize(s) << traits::identifier(m_key); 00135 } 00136 00137 // Serialize the object for reading 00138 template<class KEY> inline 00139 StreamBuffer& KeyedObject<KEY>::serialize( StreamBuffer& s ) { 00140 long k; 00141 ContainedObject::serialize(s) >> k; 00142 m_key = traits::makeKey(k); 00143 m_hasKey = true; 00144 return s; 00145 } 00146 #endif // GAUDIKERNEL_KEYEDOBJECT_H