EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Stamp.h
Go to the documentation of this file.
1#pragma once
2
10
11#include <type_traits>
12
14
15namespace Emrys::internal
16{
17
31class Stamp
32{
33public:
34
35 Stamp() = default;
36
38 Stamp(Stamp const &) noexcept {}
39
41 Stamp(Stamp && other) noexcept
42 {
43 other.touchShape();
44 }
45
47 Stamp &
48 operator=(Stamp const &) noexcept
49 {
50 touchShape();
51 return *this;
52 }
53
55 Stamp &
56 operator=(Stamp && other) noexcept
57 {
58 touchShape();
59 other.touchShape();
60 return *this;
61 }
62
64 void
65 touchValues() noexcept
66 {
67 ++m_values;
68 }
69
73 void
74 touchShape() noexcept
75 {
76 ++m_values;
77 ++m_shape;
78 }
79
81 [[nodiscard]] unsigned
82 values() const noexcept
83 {
84 return m_values;
85 }
86
88 [[nodiscard]] unsigned
89 shape() const noexcept
90 {
91 return m_shape;
92 }
93
94private:
95
96 unsigned m_values = 0;
97 unsigned m_shape = 0;
98};
99
106template <typename Source>
107class ValuesCheck
108{
109public:
110
112 explicit ValuesCheck(Source const & source)
113 : m_source{&source}
114 , m_seen{source.m_stamp.values()}
115 {}
116
118 [[nodiscard]] Source const &
119 get() const
120 {
121 EMRYS_FILTER_ASSERT(
122 m_source->m_stamp.values() == m_seen && "the parameters changed while a view of them was alive"
123 );
124 return *m_source;
125 }
126
127private:
128
129 Source const * m_source;
130 unsigned m_seen;
131};
132
138template <typename Source>
139class ShapeCheck
140{
141public:
142
144 explicit ShapeCheck(Source const & source)
145 : m_source{&source}
146 , m_seen{source.m_stamp.shape()}
147 {}
148
150 [[nodiscard]] Source const &
151 get() const
152 {
153 EMRYS_FILTER_ASSERT(
154 m_source->m_stamp.shape() == m_seen
155 && "the parameters changed size or structure while a marginal of them was alive"
156 );
157 return *m_source;
158 }
159
160private:
161
162 Source const * m_source;
163 unsigned m_seen;
164};
165
170class CallbackGuard
171{
172public:
173
175 explicit CallbackGuard(Stamp const & stamp) noexcept
176 : m_stamp{&stamp}
177 , m_seen{stamp.values()}
178 {}
179
181 void
182 check() const
183 {
184 EMRYS_FILTER_ASSERT(m_stamp->values() == m_seen && "the parameters changed inside their own callback");
185 }
186
187private:
188
189 [[maybe_unused]] Stamp const * m_stamp;
190 unsigned m_seen;
191};
192
194template <typename View>
195class ViewHolder
196{
197public:
198
200 explicit ViewHolder(View const & view)
201 : m_view{view}
202 {}
203
205 [[nodiscard]] View const &
206 get() const
207 {
208 return m_view;
209 }
210
211private:
212
213 View m_view;
214};
215
217template <typename Source>
218using HolderFor = std::conditional_t<Source::IsParams, ShapeCheck<Source>, ViewHolder<Source>>;
219
220} // namespace Emrys::internal
The macros every header includes first.