LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
Hash.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Provenance_Hash_h
2 #define canvas_Persistency_Provenance_Hash_h
3 // vim: set sw=2 expandtab :
4 
5 // ======================================================================
6 //
7 // Hash:
8 //
9 // Note: The call to 'fixup' in every member function is a temporary
10 // measure for backwards compatibility. It is necessary in every function
11 // because Root creates instances of the class *without* using the
12 // interface of the class, thus making it insufficient to assure that all
13 // constructors make corrected instances.
14 //
15 // ======================================================================
16 
18 
19 #include <ostream>
20 #include <string>
21 
22 namespace art {
23 
24  namespace detail {
25  // If hash is in the hexified 32 byte representation, make it be
26  // in the 16 byte unhexified representation.
27  void fixup(std::string& hash);
28  std::string hash_to_string(std::string const& hash);
29  // This string is in the 16 byte (non-printable) representation.
30  std::string const& InvalidHash();
31  } // namespace detail
32 
33  template <int I>
34  class Hash {
35  public:
36  using value_type = std::string;
37 
38  Hash();
39  explicit Hash(std::string const&);
40  Hash(Hash<I> const&);
41  Hash(Hash<I>&&);
42  Hash<I>& operator=(Hash<I> const&);
43  Hash<I>& operator=(Hash<I>&&);
44 
45  // For ROOT
46  static short Class_Version() noexcept;
47 
48  // For now, just check the most basic: a default constructed
49  // ParameterSetID is not valid. This is very crude: we are
50  // assuming that nobody created a ParameterSetID from an empty
51  // string, nor from any string that is not a valid string
52  // representation of an MD5 checksum.
53  bool isValid() const;
54  bool isCompactForm() const noexcept;
55  // Return the 16 byte (non-printable) string form.
56  std::string compactForm() const;
57  bool operator<(Hash<I> const&) const;
58  bool operator>(Hash<I> const&) const;
59  bool operator==(Hash<I> const&) const;
60  bool operator!=(Hash<I> const&) const;
61  std::ostream& print(std::ostream&) const;
62  void swap(Hash<I>&);
63 
64  private:
65  std::string hash_{};
66  };
67 
68  // MUST UPDATE WHEN CLASS IS CHANGED!
69  template <int I>
70  short
72  {
73  return 10;
74  }
75 
76  template <int I>
78  {
79  detail::fixup(hash_);
80  }
81 
82  template <int I>
83  Hash<I>::Hash(std::string const& s) : hash_{s}
84  {
86  }
87 
88  template <int I>
89  Hash<I>::Hash(Hash<I> const& rhs) : hash_{rhs.hash_}
90  {
92  }
93 
94  template <int I>
95  Hash<I>::Hash(Hash<I>&& rhs) : hash_{std::move(rhs.hash_)}
96  {
98  }
99 
100  template <int I>
101  Hash<I>&
103  {
104  if (this != &rhs) {
105  hash_ = rhs.hash_;
107  }
108  return *this;
109  }
110 
111  template <int I>
112  Hash<I>&
114  {
115  hash_ = std::move(rhs.hash_);
117  return *this;
118  }
119 
120  template <int I>
121  bool
123  {
124  if (isCompactForm()) {
125  return hash_ != art::detail::InvalidHash();
126  }
127  return !hash_.empty();
128  }
129 
130  template <int I>
131  bool
132  Hash<I>::operator<(Hash<I> const& rhs) const
133  {
134  if (isCompactForm() == rhs.isCompactForm()) {
135  return hash_ < rhs.hash_;
136  }
137  // Force both into compact form.
138  return Hash<I>{*this} < Hash<I>{rhs};
139  }
140 
141  template <int I>
142  bool
143  Hash<I>::operator>(Hash<I> const& rhs) const
144  {
145  if (isCompactForm() == rhs.isCompactForm()) {
146  return hash_ > rhs.hash_;
147  }
148  // Force both into compact form.
149  return Hash<I>{*this} > Hash<I>{rhs};
150  }
151 
152  template <int I>
153  bool
154  Hash<I>::operator==(Hash<I> const& rhs) const
155  {
156  if (isCompactForm() == rhs.isCompactForm()) {
157  return hash_ == rhs.hash_;
158  }
159  // Force both into compact form.
160  return Hash<I>{*this} == Hash<I>{rhs};
161  }
162 
163  template <int I>
164  bool
165  Hash<I>::operator!=(Hash<I> const& rhs) const
166  {
167  return !operator==(rhs);
168  }
169 
170  template <int I>
171  std::ostream&
172  Hash<I>::print(std::ostream& os) const
173  {
174  Hash<I> tMe{*this};
175  return os << detail::hash_to_string(tMe.hash_);
176  }
177 
178  template <int I>
179  void
181  {
183  hash_.swap(rhs.hash_);
185  }
186 
187  template <int I>
188  std::string
190  {
191  if (isCompactForm()) {
192  return hash_;
193  }
194  Hash<I> tMe(*this);
195  return tMe.compactForm();
196  }
197 
198  template <int I>
199  bool
200  Hash<I>::isCompactForm() const noexcept
201  {
202  return hash_.size() == 16;
203  }
204 
205  template <int I>
206  void
208  {
209  a.swap(b);
210  }
211 
212  template <int I>
213  std::ostream&
214  operator<<(std::ostream& os, Hash<I> const& h)
215  {
216  return h.print(os);
217  }
218 
219 } // namespace art
220 
221 #endif /* canvas_Persistency_Provenance_Hash_h */
222 
223 // Local Variables:
224 // mode: c++
225 // End:
std::string const & InvalidHash()
Definition: Hash.cc:43
std::string value_type
Definition: Hash.h:36
static short Class_Version() noexcept
Definition: Hash.h:71
STL namespace.
std::ostream & print(std::ostream &) const
Definition: Hash.h:172
Hash()
Definition: Hash.h:77
std::string hash_to_string(std::string const &hash)
Definition: Hash.cc:34
bool operator>(Hash< I > const &) const
Definition: Hash.h:143
void swap(Hash< I > &)
Definition: Hash.h:180
void swap(Handle< T > &a, Handle< T > &b)
std::string hash_
Definition: Hash.h:65
bool operator==(Hash< I > const &) const
Definition: Hash.h:154
bool isValid() const
Definition: Hash.h:122
bool operator<(Hash< I > const &) const
Definition: Hash.h:132
Hash< I > & operator=(Hash< I > const &)
Definition: Hash.h:102
bool isCompactForm() const noexcept
Definition: Hash.h:200
Definition: MVAAlg.h:12
void fixup(std::string &hash)
Definition: Hash.cc:12
std::string compactForm() const
Definition: Hash.h:189
Definition: Hash.h:34
bool operator!=(Hash< I > const &) const
Definition: Hash.h:165