/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Reconstruction/MdcPatRec/ProxyDict/ProxyDict-00-00-01/ProxyDict/IfdKey.h

Go to the documentation of this file.
00001 #ifndef IfdKey_HH
00002 #define IfdKey_HH
00003 //--------------------------------------------------------------------------
00004 // File and Version Information:
00005 //    $Id: IfdKey.h,v 1.1.1.1 2005/04/21 01:18:05 zhangy Exp $
00006 //
00007 // Description:
00008 //    IfdKey is a Key, i.e., something that knows operator== and,
00009 //    maybe someday, operator<.  Subclasses, like IfdIntKey and IfdStrKey
00010 //    allow keys based on integer and string values.  Another derivative,
00011 //    IfdTypeKey<T> serves as mapping between C++ static classes and
00012 //    Keys.  Finally, IfdKey wroks with its derivative, IfdCompositeKey,
00013 //    to form a composite pattern that allows lists, trees, etc. of
00014 //    keys to be formed and yet have an op== defined on it.
00015 //
00016 //    Usage:  Keys do not know op=, i.e., assignemnt, and I have supressed
00017 //    the copy ctor.  You should pass them by reference or poiner.  There
00018 //    is a clone() method, so a consumer can effective copy a key.  Note
00019 //    that this means that the caller retains ownership of the key, and
00020 //    the "consumer" that takes a copy *owns* the copy.
00021 //
00022 // Author List:
00023 //    Ed Frank                        University of Pennsylvania
00024 //
00025 // History:
00026 //    Ed Frank      17 Nov 96         Creation of first version
00027 //
00028 // Bugs:
00029 //
00030 //------------------------------------------------------------------------
00031 
00032 //
00033 //  Reading IntIfdKey.hh after this is helpful.  Then tackle CompositeIfdKey.hh
00034 //
00035 
00036 
00037 #include <assert.h>
00038 #include <stdlib.h>
00039 class HepString;
00040 #if !(defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 95)) // BABAR_IOSTREAMS_MIGRATION
00041 #include <iosfwd>
00042 #else                                                               // BABAR_IOSTREAMS_MIGRATION
00043 class ostream;
00044 #endif                                                              // BABAR_IOSTREAMS_MIGRATION
00045 class IfdDictKey;
00046 //template<class T> class TypeKey;
00047 
00048 class IfdKey {
00049 public:
00050    virtual ~IfdKey();
00051 
00052    virtual int operator==( const IfdKey & ) const = 0;
00053    inline int operator!=( const IfdKey &k ) const;
00054 
00055 
00056    virtual void add( const IfdKey& );
00057 
00058    inline int cardinality(void) const;
00059       // For Composite keys, == # of added elements.  For Non-Composites, == 0;
00060 
00061 #if !(defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 95)) // BABAR_IOSTREAMS_MIGRATION
00062    virtual void print( std::ostream &o ) const = 0;
00063 #else                                                               // BABAR_IOSTREAMS_MIGRATION
00064    virtual void print( ostream &o ) const = 0;
00065 #endif                                                              // BABAR_IOSTREAMS_MIGRATION
00066 #if !(defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 95)) // BABAR_IOSTREAMS_MIGRATION
00067    friend std::ostream& operator<<( std::ostream& o, const IfdKey & k );
00068 #else                                                               // BABAR_IOSTREAMS_MIGRATION
00069    friend ostream& operator<<( ostream& o, const IfdKey & k );
00070 #endif                                                              // BABAR_IOSTREAMS_MIGRATION
00071 
00072    virtual IfdKey*    clone( void ) const = 0;
00073       // Clone makes an exact copy of an object.  It is crucial that
00074       // derivatives implement this in a way that places the created
00075       // object on the heap.
00076 
00077     virtual unsigned int hash( void ) const
00078         { return _hashVal;}
00079 
00080     unsigned int  _hashVal;     //$$  public (ick) for now.  clean later.
00081                                 
00082     static unsigned int nHashBuckets( void ) 
00083        { return _nHashBuckets; }
00084 
00085 protected:
00086    enum         { _nHashBuckets = 1031 }; // .33 msec/ev, not opt
00087 
00088    enum keyKind { intKey, strKey, compositeKey,
00089                    typeKey, odfTypeKey };
00090 
00091    IfdKey( keyKind kind );
00092       // IfdKey is a pure interface.  Prevent creation of them.  Only
00093       // derivatives can be created and this ctor requires them to
00094       // define their keykind at ctor time.   This could have been
00095       // a virtual getKeyKind, but that affected performance.  See below.
00096 
00097 
00098    inline IfdKey::keyKind getKeyKind( void ) const { return _myKeyKind; }
00099       // IfdKeys are things that understand operator==.  We have made
00100       // this machinery rather than a simple overloaded global op==
00101       // because we wanted CompositeKey's, i.e., IfdKeys with subfields.
00102       // The enum above allows the subfields to be of various kinds,
00103       // each of which understands operator==.  Thus we can have
00104       // a composite key in which the first field is a TypeKey and the
00105       // second is a string. Below is an anonymous
00106       // union that we use to store the actual token being compared.
00107       // The enum allows us to access the union correctly.  If we
00108       // were to put these data into the derivative classes, we
00109       // would end up having to cast the argument of operator==(IfdKey &k)
00110       // to a specific type before we could do the ==.  This seems
00111       // cleaner.  This is slightly gross, but (1) we really do gain
00112       // something (2) Once we've handled int,string, and TypeKeys,
00113       // we are basically done, i.e., we don't expect much extension
00114       // here.
00115 
00116    keyKind _myKeyKind;
00117       // Originally, getKeyKind was virtual.  But that was too slow.  It
00118       // is reasonable to consider this a difference in value rather than
00119       // difference in behavior, so I've made getKeyKind a non-virtual 
00120       // accessor to _myKeyKind and we set _myKeyKind in the ctors.
00121 
00122    int _myCardinality;
00123       // See accessor.
00124 
00125    union {
00126       int          intVal;
00127       unsigned int uintVal;
00128       char*        strVal;
00129    };
00130 
00131  
00132    friend class IfdIntKey;
00133    friend class IfdStrKey;
00134    friend class IfdTypeKeyIFace;
00135    friend class IfdCompositeKey;
00136    friend class BdbOdfIfdTypeKeyIFace;
00137       // We need to declare these classes as friends because, for
00138       // example, IntKey::op==( IfdKey& k) must get at k.intVal, which
00139       // is protected.  Even though all of the IfdKey derivatives inherit
00140       // from IfdKey, the rule is that you can only get at protected
00141       // data in your *own* class, so IntKey can not get at IfdKey::intVal,
00142       // only IntKey::intVal.
00143 
00144   friend unsigned ifdKeyHash(const IfdDictKey& k);
00145 
00146 private:
00147    virtual void make_vtab( void ) const;
00148 
00149    // Copy ctor and assignment op.
00150    //   Not sure what to do about these.  I think they may not
00151    //   make any sense, e.g., what if someone has IfdIntKey ik, IfdStrKey sk,
00152    //   and tries to do ik=sk?  That is nonsense.  It may be OK to do
00153    //   a copy ctor and implement it via clone; however, I will just turn
00154    //   off the copy ctor for now too.  If someone needs it, ask me
00155    //   and I'll think more about it.
00156    // 
00157 
00158    IfdKey( const IfdKey &) { ::abort(); }
00159    IfdKey& operator=( IfdKey &) { if ( this != 0 ) ::abort(); return *this; }
00160 };
00161 
00162 
00163 //*****************************************************************************
00164 inline
00165 int
00166 IfdKey::cardinality(void) const { 
00167 //*****************************************************************************
00168     return _myCardinality;
00169 }
00170 
00171 //*****************************************************************************
00172 //inline
00173 //IfdKey::keyKind
00174 //IfdKey::getKeyKind( void ) const {
00175 //*****************************************************************************
00176 //    return _myKeyKind;
00177 //}
00178 
00179 //*****************************************************************************
00180 inline
00181 int
00182 IfdKey::operator != ( const IfdKey &k ) const {
00183 //*****************************************************************************
00184 
00185     return ! ( *this == k );
00186 }
00187 
00188 
00189 #endif /* IFDKEY_HH */

Generated on Tue Nov 29 23:13:39 2016 for BOSS_7.0.2 by  doxygen 1.4.7