| # Gaudi Framework, version v21r10p1 |

Home |  | Generated: 29 Jul 2010

# 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__
    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__
    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)
    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
    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)
    00074   operator unsigned long() const {
    00075     return (m_major_ver << 24) + (m_minor_ver << 16) + m_id;
    00076   }
    00077 #endif
    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; }
    00084
    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__
    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__
    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 std::type_info &) 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(typeid(typename TARGET::iid::iids::type)));
    00238   }
    00241   template <typename TARGET>
    00242   const TARGET* Cast(const IInterface *i){
    00243     return reinterpret_cast<const TARGET*>(i->i_cast(typeid(typename TARGET::iid::iids::type)));
    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