Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011

IInterface.h

Go to the documentation of this file.
00001 // $Id: IInterface.h,v 1.14 2008/01/29 08:28:14 marcocle Exp $
00002 #ifndef GAUDIKERNEL_IINTERFACE_H
00003 #define GAUDIKERNEL_IINTERFACE_H
00004 
00005 // Include files
00006 #include "GaudiKernel/Kernel.h"
00007 #include "GaudiKernel/System.h"
00008 #include "GaudiKernel/StatusCode.h"
00009 #include <ostream>
00010 
00011 #ifndef __GCCXML__
00012 // Meta Programming Library (MPL) headers
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 // GCCXML work-around
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 // GCCXML work-around
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); // avoid compilation errors
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     // GCCXML work-around
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(); } // new method, so we need a default implementation for v20 compatibility
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 //#ifdef GAUDI_V20_COMPAT
00266 inline std::ostream& operator << ( std::ostream& s, const InterfaceID& id) {
00267     s << "IID_" << id.id();
00268     return s;
00269 }
00270 //#endif
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Fri Sep 2 2011 16:24:23 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004