Slab.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines class Slab
6 
7 #pragma once
8 
9 #include <cstddef>
10 #include <functional>
11 #include <iosfwd>
12 #include <limits>
13 
14 #include "ErrorHandling/Assert.hpp"
15 
16 class Time;
17 class TimeDelta;
18 
19 namespace PUP {
20 class er;
21 } // namespace PUP
22 
23 /// \ingroup TimeGroup
24 ///
25 /// A chunk of time. Every element must reach slab boundaries
26 /// exactly, no matter how it actually takes time steps to get there.
27 /// The simulation can only be assumed to have global data available
28 /// at slab boundaries.
29 class Slab {
30  public:
31  /// Default constructor gives an invalid Slab.
32  Slab() noexcept
33  : start_(std::numeric_limits<double>::signaling_NaN()),
34  end_(std::numeric_limits<double>::signaling_NaN()) {}
35 
36  /// Construct a slab running between two times (exactly).
37  Slab(double start, double end) noexcept : start_(start), end_(end) {
38  ASSERT(start_ < end_, "Backwards Slab");
39  }
40 
41  /// Construct a slab with a given start time and duration. The
42  /// actual duration may differ by roundoff from the supplied value.
43  static Slab with_duration_from_start(double start, double duration) noexcept {
44  return {start, start + duration};
45  }
46 
47  /// Construct a slab with a given end time and duration. The
48  /// actual duration may differ by roundoff from the supplied value.
49  static Slab with_duration_to_end(double end, double duration) noexcept {
50  return {end - duration, end};
51  }
52 
53  Time start() const noexcept;
54  Time end() const noexcept;
55  TimeDelta duration() const noexcept;
56 
57  /// Create a new slab immediately following this one with the same
58  /// (up to roundoff) duration.
59  Slab advance() const noexcept { return {end_, end_ + (end_ - start_)}; }
60 
61  /// Create a new slab immediately preceeding this one with the same
62  /// (up to roundoff) duration.
63  Slab retreat() const noexcept { return {start_ - (end_ - start_), start_}; }
64 
65  /// Create a slab adjacent to this one in the direction indicated by
66  /// the argument, as with advance() or retreat().
67  Slab advance_towards(const TimeDelta& dt) const noexcept;
68 
69  /// Create a new slab with the same start time as this one with the
70  /// given duration (up to roundoff).
71  Slab with_duration_from_start(double duration) const noexcept {
72  return {start_, start_ + duration};
73  }
74 
75  /// Create a new slab with the same end time as this one with the
76  /// given duration (up to roundoff).
77  Slab with_duration_to_end(double duration) const noexcept {
78  return {end_ - duration, end_};
79  }
80 
81  /// Check if this slab is immediately followed by the other slab.
82  bool is_followed_by(const Slab& other) const noexcept {
83  return end_ == other.start_;
84  }
85 
86  /// Check if this slab is immediately preceeded by the other slab.
87  bool is_preceeded_by(const Slab& other) const noexcept {
88  return other.is_followed_by(*this);
89  }
90 
91  // clang-tidy: google-runtime-references
92  void pup(PUP::er& p) noexcept; // NOLINT
93 
94  private:
95  double start_;
96  double end_;
97 
98  friend class Time;
99  friend class TimeDelta;
100 
101  friend bool operator==(const Slab& a, const Slab& b) noexcept;
102  friend bool operator<(const Slab& a, const Slab& b) noexcept;
103  friend bool operator==(const Time& a, const Time& b) noexcept;
104 };
105 
106 inline bool operator==(const Slab& a, const Slab& b) noexcept {
107  return a.start_ == b.start_ and a.end_ == b.end_;
108 }
109 inline bool operator!=(const Slab& a, const Slab& b) noexcept {
110  return not(a == b);
111 }
112 
113 /// Slab comparison operators give the time ordering. Overlapping
114 /// unequal slabs should not be compared (and will trigger an
115 /// assertion).
116 //@{
117 inline bool operator<(const Slab& a, const Slab& b) noexcept {
118  ASSERT(a == b or a.end_ <= b.start_ or a.start_ >= b.end_,
119  "Cannot compare overlapping slabs");
120  return a.end_ <= b.start_;
121 }
122 inline bool operator>(const Slab& a, const Slab& b) noexcept {
123  return b < a;
124 }
125 inline bool operator<=(const Slab& a, const Slab& b) noexcept {
126  return not(a > b);
127 }
128 inline bool operator>=(const Slab& a, const Slab& b) noexcept {
129  return not(a < b);
130 }
131 //@}
132 
133 std::ostream& operator<<(std::ostream& os, const Slab& s) noexcept;
134 
135 size_t hash_value(const Slab& s) noexcept;
136 
137 namespace std {
138 template <>
139 struct hash<Slab> {
140  size_t operator()(const Slab& s) const noexcept;
141 };
142 } // namespace std
bool is_followed_by(const Slab &other) const noexcept
Check if this slab is immediately followed by the other slab.
Definition: Slab.hpp:82
Definition: Strahlkorper.hpp:14
Slab advance() const noexcept
Create a new slab immediately following this one with the same (up to roundoff) duration.
Definition: Slab.hpp:59
bool operator>(const Slab &a, const Slab &b) noexcept
Slab comparison operators give the time ordering. Overlapping unequal slabs should not be compared (a...
Definition: Slab.hpp:122
static Slab with_duration_to_end(double end, double duration) noexcept
Construct a slab with a given end time and duration. The actual duration may differ by roundoff from ...
Definition: Slab.hpp:49
The time in a simulation. Times can be safely compared for exact equality as long as they do not belo...
Definition: Time.hpp:31
static Slab with_duration_from_start(double start, double duration) noexcept
Construct a slab with a given start time and duration. The actual duration may differ by roundoff fro...
Definition: Slab.hpp:43
A chunk of time. Every element must reach slab boundaries exactly, no matter how it actually takes ti...
Definition: Slab.hpp:29
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:49
bool operator<=(const Slab &a, const Slab &b) noexcept
Slab comparison operators give the time ordering. Overlapping unequal slabs should not be compared (a...
Definition: Slab.hpp:125
Slab retreat() const noexcept
Create a new slab immediately preceeding this one with the same (up to roundoff) duration.
Definition: Slab.hpp:63
Represents an interval of time within a single slab.
Definition: Time.hpp:108
Slab(double start, double end) noexcept
Construct a slab running between two times (exactly).
Definition: Slab.hpp:37
Slab with_duration_to_end(double duration) const noexcept
Create a new slab with the same end time as this one with the given duration (up to roundoff)...
Definition: Slab.hpp:77
Defines macro ASSERT.
Slab with_duration_from_start(double duration) const noexcept
Create a new slab with the same start time as this one with the given duration (up to roundoff)...
Definition: Slab.hpp:71
Slab() noexcept
Default constructor gives an invalid Slab.
Definition: Slab.hpp:32
bool is_preceeded_by(const Slab &other) const noexcept
Check if this slab is immediately preceeded by the other slab.
Definition: Slab.hpp:87
bool operator>=(const Slab &a, const Slab &b) noexcept
Slab comparison operators give the time ordering. Overlapping unequal slabs should not be compared (a...
Definition: Slab.hpp:128
bool operator<(const Slab &a, const Slab &b) noexcept
Slab comparison operators give the time ordering. Overlapping unequal slabs should not be compared (a...
Definition: Slab.hpp:117