ObservationId.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <boost/functional/hash.hpp>
7 #include <cstddef>
8 #include <functional>
9 #include <iosfwd>
10 #include <string>
11 
12 #include "Utilities/PrettyType.hpp"
13 
14 /// \cond
15 namespace PUP {
16 class er;
17 } // namespace PUP
18 /// \endcond
19 
20 namespace observers {
21 /*!
22  * \ingroup ObserversGroup
23  * \brief A type-erased identifier that combines the identifier's type
24  * and hash used to uniquely identify an observation inside of a
25  * `h5::File::SUB_FILE`.
26  *
27  * The ObservationId is used to uniquely identify an observation inside our H5
28  * subfiles that can be agreed upon across the system. That is, it does not
29  * depend on hardware rounding of floating points because it is an integral. One
30  * example would be a `Time` for output observed every `N` steps in a global
31  * time stepping evolution. Another example could be having a counter class for
32  * dense output observations that increments the counter for each observation
33  * but has a value equal to the physical time.
34  *
35  * The identifier must have a `value()` method that returns a double
36  * representing the current "time" at which we are observing. For an evolution
37  * this could be the physical time, while for an elliptic solve this could be a
38  * combination of nonlinear and linear iteration.
39  *
40  * A specialization of `std::hash` is provided to allow using `ObservationId`
41  * as a key in associative containers.
42  */
44  public:
45  ObservationId() = default;
46 
47  /*!
48  * \brief Construct from an ID of type `Id`
49  */
50  template <typename Id>
51  explicit ObservationId(const Id& t) noexcept;
52 
53  size_t hash() const noexcept { return combined_hash_; }
54 
55  double value() const noexcept { return value_; }
56 
57  // NOLINTNEXTLINE(google-runtime-references)
58  void pup(PUP::er& p) noexcept;
59 
60  private:
61  size_t combined_hash_;
62  double value_;
63 };
64 
65 template <typename Id>
66 ObservationId::ObservationId(const Id& t) noexcept
67  : combined_hash_([&t]() {
68  size_t combined = std::hash<std::string>{}(pretty_type::get_name<Id>());
69  boost::hash_combine(combined, t);
70  return combined;
71  }()),
72  value_(t.value()) {}
73 
74 bool operator==(const ObservationId& lhs, const ObservationId& rhs) noexcept;
75 bool operator!=(const ObservationId& lhs, const ObservationId& rhs) noexcept;
76 
77 std::ostream& operator<<(std::ostream& os, const ObservationId& t) noexcept;
78 } // namespace observers
79 
80 namespace std {
81 template <>
82 struct hash<observers::ObservationId> {
83  size_t operator()(const observers::ObservationId& t) const noexcept {
84  return t.hash();
85  }
86 };
87 } // namespace std
Definition: Actions.hpp:20
Definition: Strahlkorper.hpp:14
Contains a pretty_type library to write types in a "pretty" format.
A type-erased identifier that combines the identifier&#39;s type and hash used to uniquely identify an ob...
Definition: ObservationId.hpp:43