1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
#ifndef DataFormats_Provenance_Hash_h
#define DataFormats_Provenance_Hash_h
#include <string>
#include <functional>
/*----------------------------------------------------------------------
Hash:
Note: The call to 'fixup' in every member function is a temporary
measure for backwards compatibility. It is necessary in every function
because Root creates instances of the class *without* using the
interface of the class, thus making it insufficient to assure that
all constructors make corrected instances.
----------------------------------------------------------------------*/
namespace cms {
class Digest;
}
namespace edm {
namespace detail {
// This string is the 16-byte, non-printable version.
std::string const& InvalidHash();
} // namespace detail
namespace hash_detail {
typedef std::string value_type;
value_type compactForm_(value_type const& hash);
void fixup_(value_type& hash);
bool isCompactForm_(value_type const& hash);
bool isValid_(value_type const& hash);
void throwIfIllFormed(value_type const& hash);
void toString_(std::string& result, value_type const& hash);
void toDigest_(cms::Digest& digest, value_type const& hash);
std::ostream& print_(std::ostream& os, value_type const& hash);
size_t smallHash_(value_type const& hash);
} // namespace hash_detail
template <int I>
class Hash {
public:
typedef hash_detail::value_type value_type;
Hash();
explicit Hash(value_type const& v);
Hash(Hash<I> const&);
Hash<I>& operator=(Hash<I> const& iRHS);
Hash(Hash<I>&&) = default;
Hash<I>& operator=(Hash<I>&&) = default;
void reset();
// For now, just check the most basic: a default constructed
// ParameterSetID is not valid. This is very crude: we are
// assuming that nobody created a ParameterSetID from an empty
// string, nor from any string that is not a valid string
// representation of an MD5 checksum.
bool isValid() const;
bool operator<(Hash<I> const& other) const;
bool operator>(Hash<I> const& other) const;
bool operator==(Hash<I> const& other) const;
bool operator!=(Hash<I> const& other) const;
std::ostream& print(std::ostream& os) const;
void toString(std::string& result) const;
void toDigest(cms::Digest& digest) const;
void swap(Hash<I>& other);
// Return the 16-byte (non-printable) string form.
value_type compactForm() const;
bool isCompactForm() const;
///returns a short hash which can be used with hashing containers
size_t smallHash() const;
//Used by ROOT storage
// CMS_CLASS_VERSION(11) // This macro is not defined here, so expand it.
static short Class_Version() { return 11; }
private:
/// Hexified version of data *must* contain a multiple of 2
/// bytes. If it does not, throw an exception.
void throwIfIllFormed() const;
template <typename Op>
bool compareUsing(Hash<I> const& iOther, Op op) const {
bool meCF = hash_detail::isCompactForm_(hash_);
bool otherCF = hash_detail::isCompactForm_(iOther.hash_);
if (meCF == otherCF) {
return op(this->hash_, iOther.hash_);
}
//copy constructor will do compact form conversion
if (meCF) {
Hash<I> temp(iOther); // NOLINT(performance-unnecessary-copy-initialization)
return op(this->hash_, temp.hash_);
}
Hash<I> temp(*this);
return op(temp.hash_, iOther.hash_);
}
value_type hash_;
};
//--------------------------------------------------------------------
//
// Implementation details follow...
//--------------------------------------------------------------------
template <int I>
inline Hash<I>::Hash() : hash_(detail::InvalidHash()) {}
template <int I>
inline Hash<I>::Hash(typename Hash<I>::value_type const& v) : hash_(v) {
hash_detail::fixup_(hash_);
}
template <int I>
inline Hash<I>::Hash(Hash<I> const& iOther) : hash_(iOther.hash_) {
hash_detail::fixup_(hash_);
}
template <int I>
inline Hash<I>& Hash<I>::operator=(Hash<I> const& iRHS) {
hash_ = iRHS.hash_;
hash_detail::fixup_(hash_);
return *this;
}
template <int I>
inline void Hash<I>::reset() {
hash_ = detail::InvalidHash();
}
template <int I>
inline bool Hash<I>::isValid() const {
return hash_detail::isValid_(hash_);
}
template <int I>
inline bool Hash<I>::operator<(Hash<I> const& other) const {
return this->compareUsing(other, std::less<std::string>());
}
template <int I>
inline bool Hash<I>::operator>(Hash<I> const& other) const {
return this->compareUsing(other, std::greater<std::string>());
}
template <int I>
inline bool Hash<I>::operator==(Hash<I> const& other) const {
return this->compareUsing(other, std::equal_to<std::string>());
}
template <int I>
inline bool Hash<I>::operator!=(Hash<I> const& other) const {
return this->compareUsing(other, std::not_equal_to<std::string>());
}
template <int I>
inline std::ostream& Hash<I>::print(std::ostream& os) const {
return hash_detail::print_(os, hash_);
}
template <int I>
inline void Hash<I>::toString(std::string& result) const {
hash_detail::toString_(result, hash_);
}
template <int I>
inline void Hash<I>::toDigest(cms::Digest& digest) const {
hash_detail::toDigest_(digest, hash_);
}
template <int I>
inline void Hash<I>::swap(Hash<I>& other) {
hash_.swap(other.hash_);
}
template <int I>
inline typename Hash<I>::value_type Hash<I>::compactForm() const {
return hash_detail::compactForm_(hash_);
}
template <int I>
inline size_t Hash<I>::smallHash() const {
return hash_detail::smallHash_(hash_);
}
// Note: this template is not declared 'inline' because of the
// switch statement.
template <int I>
inline bool Hash<I>::isCompactForm() const {
return hash_detail::isCompactForm_(hash_);
}
// Free swap function
template <int I>
inline void swap(Hash<I>& a, Hash<I>& b) {
a.swap(b);
}
template <int I>
inline std::ostream& operator<<(std::ostream& os, Hash<I> const& h) {
return h.print(os);
}
} // namespace edm
#endif
|