Hashable.h
Go to the documentation of this file.
1 /*
2  * \file Hashable.h
3  * \brief Base class for supplying functionality for a hashed ID.
4  *
5  * Created on: \date Mar. 4, 2016
6  * Original author: \author J. Wolcott <jwolcott@fnal.gov>
7  *
8  */
9 
10 #ifndef FNEX_CORE_HASHABLE_H_
11 #define FNEX_CORE_HASHABLE_H_
12 
13 #include <bitset>
14 #include <memory>
15 #include <string>
16 
17 namespace fnex
18 {
19 
20  /// Base class for tracking a per-instance, hashed ID.
21  /// This class should be used via the so-called "curiously recurring template pattern" (CRTP):
22  /// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
23  /// See fnex::Cut, fnex::Shifter, fnex::Weighter for examples.
24  template <typename T>
25  class Hashable
26  {
27  public:
28 
29  /// Hashes will be std::bitset objects. Those need a compile-time constant for number of bits. 25 should be plenty?
30  static const std::size_t N_HASHES = 25;
31 
32  typedef std::bitset<N_HASHES> Hash;
33 
34  /// Constructor.
35  Hashable() : fID(1 << (sHashCounter++)) {};
36 
37  const Hash & GetID() const { return this->fID; };
38 
39  private:
40  static std::size_t sHashCounter;
41 
42  Hash fID;
43  };
44 
45 
46  /// special sorter type to make Hashable* a usable key type.
47  /// note that this ignores any other properties that a Hashable
48  /// derivative might have available to disambiguate, so if necessary
49  /// derived classes should further specialize the template.
50  template <typename T>
51  struct Hasher
52  {
53  /// Hash function (for unordered_map) for a bare pointer
54  std::size_t operator()(const fnex::Hashable<T>* h) const
55  {
56  if (!h)
57  return 0;
58 
59  return this->fStringHasher(h->GetID().to_string());
60  }
61 
62  /// Hash function (for unordered_map) for a shared_ptr; uses the bare pointer version
63  std::size_t operator()(const std::shared_ptr<const fnex::Hashable<T>> h) const
64  {
65  return this->operator()(h.get());
66  }
67 
68  /// Less-than operator (for a regular map) for bare pointer. Uses the hash function.
70  {
71  return this->operator()(h1) < this->operator()(h2);
72  }
73 
74  /// Less-than operator (for a regular map) for shared_ptrs. Uses the bare pointer version.
76  {
77  return this->operator()(h1.get()) < this->operator()(h2.get());
78  }
79 
80  private:
81  std::hash<std::string> fStringHasher; // in case N_HASHES gets big enough that the hash won't fit in a ullong
82  };
83 
84 } /* namespace fnex */
85 
86 #endif /* FNEX_CORE_HASHABLE_H_ */
const Hash & GetID() const
Definition: Hashable.h:37
std::bitset< N_HASHES > Hash
Definition: Hashable.h:32
Create a list of fnex::Events to be used in fits.
static const std::size_t N_HASHES
Hashes will be std::bitset objects. Those need a compile-time constant for number of bits...
Definition: Hashable.h:30
Hashable()
Constructor.
Definition: Hashable.h:35
static std::size_t sHashCounter
Definition: Hashable.h:37
std::shared_ptr< T > shared_ptr
Definition: memory.h:15
bool operator()(std::shared_ptr< const fnex::Hashable< T >> h1, std::shared_ptr< const fnex::Hashable< T >> h2)
Less-than operator (for a regular map) for shared_ptrs. Uses the bare pointer version.
Definition: Hashable.h:75
std::size_t operator()(const std::shared_ptr< const fnex::Hashable< T >> h) const
Hash function (for unordered_map) for a shared_ptr; uses the bare pointer version.
Definition: Hashable.h:63
TH1F * h2
Definition: plot.C:45
bool operator()(const fnex::Hashable< T > *h1, const fnex::Hashable< T > *h2)
Less-than operator (for a regular map) for bare pointer. Uses the hash function.
Definition: Hashable.h:69
TH1F * h1
std::hash< std::string > fStringHasher
Definition: Hashable.h:81
std::size_t operator()(const fnex::Hashable< T > *h) const
Hash function (for unordered_map) for a bare pointer.
Definition: Hashable.h:54