BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
Reconstruction/MdcPatRec/ProxyDict/include/ProxyDict/IfdKey.h
Go to the documentation of this file.
1#ifndef IfdKey_HH
2#define IfdKey_HH
3//--------------------------------------------------------------------------
4// File and Version Information:
5// $Id: IfdKey.h,v 1.1.1.1 2005/04/21 01:18:05 zhangy Exp $
6//
7// Description:
8// IfdKey is a Key, i.e., something that knows operator== and,
9// maybe someday, operator<. Subclasses, like IfdIntKey and IfdStrKey
10// allow keys based on integer and string values. Another derivative,
11// IfdTypeKey<T> serves as mapping between C++ static classes and
12// Keys. Finally, IfdKey wroks with its derivative, IfdCompositeKey,
13// to form a composite pattern that allows lists, trees, etc. of
14// keys to be formed and yet have an op== defined on it.
15//
16// Usage: Keys do not know op=, i.e., assignemnt, and I have supressed
17// the copy ctor. You should pass them by reference or poiner. There
18// is a clone() method, so a consumer can effective copy a key. Note
19// that this means that the caller retains ownership of the key, and
20// the "consumer" that takes a copy *owns* the copy.
21//
22// Author List:
23// Ed Frank University of Pennsylvania
24//
25// History:
26// Ed Frank 17 Nov 96 Creation of first version
27//
28// Bugs:
29//
30//------------------------------------------------------------------------
31
32//
33// Reading IntIfdKey.hh after this is helpful. Then tackle CompositeIfdKey.hh
34//
35
36#include <assert.h>
37#include <stdlib.h>
38class HepString;
39#if !( defined( __GNUC__ ) && ( __GNUC__ < 3 ) && \
40 ( __GNUC_MINOR__ < 95 ) ) // BABAR_IOSTREAMS_MIGRATION
41# include <iosfwd>
42#else // BABAR_IOSTREAMS_MIGRATION
43class ostream;
44#endif // BABAR_IOSTREAMS_MIGRATION
45class IfdDictKey;
46// template<class T> class TypeKey;
47
48class IfdKey {
49public:
50 virtual ~IfdKey();
51
52 virtual int operator==( const IfdKey& ) const = 0;
53 inline int operator!=( const IfdKey& k ) const;
54
55 virtual void add( const IfdKey& );
56
57 inline int cardinality( void ) const;
58 // For Composite keys, == # of added elements. For Non-Composites, == 0;
59
60#if !( defined( __GNUC__ ) && ( __GNUC__ < 3 ) && \
61 ( __GNUC_MINOR__ < 95 ) ) // BABAR_IOSTREAMS_MIGRATION
62 virtual void print( std::ostream& o ) const = 0;
63#else // BABAR_IOSTREAMS_MIGRATION
64 virtual void print( ostream& o ) const = 0;
65#endif // BABAR_IOSTREAMS_MIGRATION
66#if !( defined( __GNUC__ ) && ( __GNUC__ < 3 ) && \
67 ( __GNUC_MINOR__ < 95 ) ) // BABAR_IOSTREAMS_MIGRATION
68 friend std::ostream& operator<<( std::ostream& o, const IfdKey& k );
69#else // BABAR_IOSTREAMS_MIGRATION
70 friend ostream& operator<<( ostream& o, const IfdKey& k );
71#endif // BABAR_IOSTREAMS_MIGRATION
72
73 virtual IfdKey* clone( void ) const = 0;
74 // Clone makes an exact copy of an object. It is crucial that
75 // derivatives implement this in a way that places the created
76 // object on the heap.
77
78 virtual unsigned int hash( void ) const { return _hashVal; }
79
80 unsigned int _hashVal; //$$ public (ick) for now. clean later.
81
82 static unsigned int nHashBuckets( void ) { return _nHashBuckets; }
83
84protected:
85 enum { _nHashBuckets = 1031 }; // .33 msec/ev, not opt
86
88
89 IfdKey( keyKind kind );
90 // IfdKey is a pure interface. Prevent creation of them. Only
91 // derivatives can be created and this ctor requires them to
92 // define their keykind at ctor time. This could have been
93 // a virtual getKeyKind, but that affected performance. See below.
94
95 inline IfdKey::keyKind getKeyKind( void ) const { return _myKeyKind; }
96 // IfdKeys are things that understand operator==. We have made
97 // this machinery rather than a simple overloaded global op==
98 // because we wanted CompositeKey's, i.e., IfdKeys with subfields.
99 // The enum above allows the subfields to be of various kinds,
100 // each of which understands operator==. Thus we can have
101 // a composite key in which the first field is a TypeKey and the
102 // second is a string. Below is an anonymous
103 // union that we use to store the actual token being compared.
104 // The enum allows us to access the union correctly. If we
105 // were to put these data into the derivative classes, we
106 // would end up having to cast the argument of operator==(IfdKey &k)
107 // to a specific type before we could do the ==. This seems
108 // cleaner. This is slightly gross, but (1) we really do gain
109 // something (2) Once we've handled int,string, and TypeKeys,
110 // we are basically done, i.e., we don't expect much extension
111 // here.
112
114 // Originally, getKeyKind was virtual. But that was too slow. It
115 // is reasonable to consider this a difference in value rather than
116 // difference in behavior, so I've made getKeyKind a non-virtual
117 // accessor to _myKeyKind and we set _myKeyKind in the ctors.
118
119 int _myCardinality;
120 // See accessor.
121
122 union {
123 int intVal;
124 unsigned int uintVal;
125 char* strVal;
126 };
127
128 friend class IfdIntKey;
129 friend class IfdStrKey;
130 friend class IfdTypeKeyIFace;
131 friend class IfdCompositeKey;
132 friend class BdbOdfIfdTypeKeyIFace;
133 // We need to declare these classes as friends because, for
134 // example, IntKey::op==( IfdKey& k) must get at k.intVal, which
135 // is protected. Even though all of the IfdKey derivatives inherit
136 // from IfdKey, the rule is that you can only get at protected
137 // data in your *own* class, so IntKey can not get at IfdKey::intVal,
138 // only IntKey::intVal.
139
140 friend unsigned ifdKeyHash( const IfdDictKey& k );
141
142private:
143 virtual void make_vtab( void ) const;
144
145 // Copy ctor and assignment op.
146 // Not sure what to do about these. I think they may not
147 // make any sense, e.g., what if someone has IfdIntKey ik, IfdStrKey sk,
148 // and tries to do ik=sk? That is nonsense. It may be OK to do
149 // a copy ctor and implement it via clone; however, I will just turn
150 // off the copy ctor for now too. If someone needs it, ask me
151 // and I'll think more about it.
152 //
153
154 IfdKey( const IfdKey& ) { ::abort(); }
155 IfdKey& operator=( IfdKey& ) {
156 if ( this != 0 ) ::abort();
157 return *this;
158 }
159};
160
161//*****************************************************************************
162inline int IfdKey::cardinality( void ) const {
163 //*****************************************************************************
164 return _myCardinality;
165}
166
167//*****************************************************************************
168// inline
169// IfdKey::keyKind
170// IfdKey::getKeyKind( void ) const {
171//*****************************************************************************
172// return _myKeyKind;
173//}
174
175//*****************************************************************************
176inline int IfdKey::operator!=( const IfdKey& k ) const {
177 //*****************************************************************************
178
179 return !( *this == k );
180}
181
182#endif /* IFDKEY_HH */
virtual void add(const IfdKey &)
friend std::ostream & operator<<(std::ostream &o, const IfdKey &k)
virtual IfdKey * clone(void) const =0
virtual int operator==(const IfdKey &) const =0
IfdKey(keyKind kind)
Definition IfdKey.cxx:23
friend unsigned ifdKeyHash(const IfdDictKey &k)
virtual ~IfdKey()
int operator!=(const IfdKey &k) const
virtual void print(std::ostream &o) const =0
int cardinality(void) const