Go to the documentation of this file.00001
00002 #ifndef GAUDIKERNEL_IINTERFACE_H
00003 #define GAUDIKERNEL_IINTERFACE_H
00004
00005
00006 #include "GaudiKernel/Kernel.h"
00007 #include "GaudiKernel/System.h"
00008 #include "GaudiKernel/StatusCode.h"
00009 #include <ostream>
00010
00011 #ifndef __GCCXML__
00012
00013 #include <boost/mpl/set.hpp>
00014 #include <boost/mpl/insert.hpp>
00015 #include <boost/mpl/fold.hpp>
00016 #include <boost/mpl/for_each.hpp>
00017 namespace mpl = boost::mpl;
00018 #endif
00019
00020 #include <typeinfo>
00021
00022 #ifndef __GCCXML__
00023
00024 #define DeclareInterfaceID(name, major, minor) \
00025 static const InterfaceID &interfaceID(){ return iid::interfaceID(); } \
00026 typedef Gaudi::InterfaceId< name , major , minor > iid; \
00027 typedef iid::iids::type ext_iids
00028 #else
00029
00030 #define DeclareInterfaceID(name, major, minor) \
00031 static const InterfaceID &interfaceID(){ static InterfaceID xx(0UL,0UL,0UL); return xx; }
00032 #endif
00033
00034 #ifndef __GCCXML__
00035
00036 #define DeclareInterfaceIDMultiBase(name, major, minor) \
00037 static const InterfaceID &interfaceID(){ return iid::interfaceID(); } \
00038 typedef Gaudi::InterfaceId< name , major , minor > iid
00039 #else
00040
00041 #define DeclareInterfaceIDMultiBase(name, major, minor) \
00042 static const InterfaceID &interfaceID(){ static InterfaceID xx(0UL,0UL,0UL); return xx; }
00043 #endif
00044
00056 class GAUDI_API InterfaceID {
00057 public:
00058 #if defined(GAUDI_V20_COMPAT) && !defined(G21_NEW_INTERFACES)
00059
00060 InterfaceID( unsigned long lid ) : m_id( lid & 0xFFFF ),
00061 m_major_ver( (lid & 0xFF000000)>>24 ),
00062 m_minor_ver( (lid & 0xFF0000)>> 16 ) { }
00063 #endif
00064
00065 InterfaceID( unsigned long id, unsigned long major, unsigned long minor = 0)
00066 : m_id( id ), m_major_ver( major ), m_minor_ver( minor ) { }
00068 InterfaceID( const char* name, unsigned long major, unsigned long minor = 0)
00069 : m_id( hash32(name) ), m_major_ver( major ), m_minor_ver( minor ) { }
00071 ~InterfaceID() { }
00072 #if defined(GAUDI_V20_COMPAT) && !defined(G21_NEW_INTERFACES)
00073
00074 operator unsigned long() const {
00075 return (m_major_ver << 24) + (m_minor_ver << 16) + m_id;
00076 }
00077 #endif
00078
00079 unsigned long id() const { return m_id; }
00081 unsigned long majorVersion() const { return m_major_ver; }
00083 unsigned long minorVersion() const { return m_minor_ver; }
00087 bool versionMatch( const InterfaceID& iid ) const {
00088 return ( id() == iid.id() &&
00089 majorVersion() == iid.majorVersion() &&
00090 minorVersion() >= iid.minorVersion() );
00091 }
00093 bool fullMatch( const InterfaceID& iid ) const {
00094 return ( id() == iid.id() &&
00095 majorVersion() == iid.majorVersion() &&
00096 minorVersion() == iid.minorVersion() );
00097 }
00099 bool operator == (const InterfaceID& iid ) const { return fullMatch(iid); }
00101 static unsigned int hash32(const char* key) {
00102 unsigned int hash;
00103 const char* k;
00104 for (hash = 0, k = key; *k; k++) {
00105 hash += *k; hash += (hash << 10); hash ^= (hash >> 6);
00106 }
00107 hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15);
00108 return hash;
00109 }
00110
00111 private:
00112 unsigned long m_id;
00113 unsigned long m_major_ver;
00114 unsigned long m_minor_ver;
00115 };
00116
00117 namespace Gaudi {
00121 template <typename INTERFACE, unsigned long majVers, unsigned long minVers>
00122 class InterfaceId {
00123 public:
00125 typedef INTERFACE iface_type;
00126
00127 #ifndef __GCCXML__
00128
00129 typedef mpl::insert<typename iface_type::ext_iids, InterfaceId> iids;
00130 #endif
00131
00132 static inline std::string name() { return System::typeinfoName(typeid(INTERFACE)); }
00133
00134 static inline unsigned long majorVersion(){return majVers;}
00135 static inline unsigned long minorVersion(){return minVers;}
00136
00137 static inline const std::type_info &TypeInfo() {
00138 #ifndef __GCCXML__
00139 return typeid(typename iids::type);
00140 #else
00141 return typeid(INTERFACE);
00142 #endif
00143 }
00144
00145 static const InterfaceID& interfaceID()
00146 {
00147 static InterfaceID s_iid(name().c_str(),majVers,minVers);
00148 return s_iid;
00149 }
00150
00151 };
00152 }
00153
00161 class GAUDI_API IInterface {
00162 public:
00163 #ifndef __GCCXML__
00164
00165 typedef Gaudi::InterfaceId<IInterface,0,0> iid;
00166
00168 typedef mpl::set1<iid> ext_iids;
00169 #endif
00170
00172 static inline const InterfaceID &interfaceID(){
00173 #ifndef __GCCXML__
00174 return iid::interfaceID();
00175 #else
00176
00177 static InterfaceID xx(0UL,0UL,0UL);
00178 return xx;
00179 #endif
00180 }
00181
00183 virtual void *i_cast(const InterfaceID &) const
00184 #if defined(GAUDI_V20_COMPAT) && !defined(G21_NEW_INTERFACES)
00185 {return 0;}
00186 #else
00187 = 0;
00188 #endif
00189
00191 virtual std::vector<std::string> getInterfaceNames() const
00192 #if defined(GAUDI_V20_COMPAT) && !defined(G21_NEW_INTERFACES)
00193 {return std::vector<std::string>();}
00194 #else
00195 = 0;
00196 #endif
00197
00199 virtual unsigned long addRef() = 0;
00200
00202 virtual unsigned long release() = 0;
00203
00205 virtual unsigned long refCount() const
00206 #if defined(GAUDI_V20_COMPAT) && !defined(G21_NEW_INTERFACES)
00207 { IInterface* ths = const_cast<IInterface*>(this);
00208 ths->addRef();
00209 return ths->release(); }
00210 #else
00211 = 0;
00212 #endif
00213
00215 virtual StatusCode queryInterface(const InterfaceID &ti, void** pp) = 0;
00216
00218 enum Status {
00220 SUCCESS = 1,
00222 NO_INTERFACE,
00224 VERSMISMATCH,
00226 LAST_ERROR
00227 };
00228
00230 virtual ~IInterface() {}
00231 };
00232
00233 namespace Gaudi {
00235 template <typename TARGET>
00236 TARGET* Cast(IInterface *i){
00237 return reinterpret_cast<TARGET*>(i->i_cast(TARGET::interfaceID()));
00238 }
00241 template <typename TARGET>
00242 const TARGET* Cast(const IInterface *i){
00243 return reinterpret_cast<const TARGET*>(i->i_cast(TARGET::interfaceID()));
00244 }
00245 }
00246
00257 template <class I>
00258 bool isValidInterface( I* i) {
00259 void* ii;
00260 StatusCode sc = i->queryInterface( I::interfaceID(), &ii);
00261 return sc.isSuccess();
00262 }
00263
00264
00266 inline std::ostream& operator << ( std::ostream& s, const InterfaceID& id) {
00267 s << "IID_" << id.id();
00268 return s;
00269 }
00270
00271
00282 template <class DEST,class SRC>
00283 inline DEST** pp_cast(SRC** ptr){
00284 return reinterpret_cast<DEST**>(ptr);
00285 }
00286
00287 #include "GaudiKernel/extend_interfaces.h"
00288 #include "GaudiKernel/implements.h"
00289 #include "GaudiKernel/extends.h"
00290
00291 #endif // GAUDIKERNEL_IINTERFACE_H