ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
ScalarRegisterAccessor.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
6
7#include <type_traits>
8
9namespace ChimeraTK {
10
11 /********************************************************************************************************************/
12
24 template<user_type UserType, typename TAG = std::nullptr_t>
26 public:
33 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
35
43
45 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
46 operator UserType&() { return get()->accessData(0, 0); }
47
49 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
50 operator const UserType&() const { return get()->accessData(0, 0); }
51
56 template<typename OTHER_TAG>
57 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
59
64 template<typename OTHER_TAG>
65 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
67 return *this;
68 }
69
71 ScalarRegisterAccessor& operator=(UserType rightHandSide);
72
74 ScalarRegisterAccessor& operator++() { return operator=(get()->accessData(0, 0) + 1); }
75
77 ScalarRegisterAccessor& operator--() { return operator=(get()->accessData(0, 0) - 1); }
78
80 UserType operator++(int);
81
83 UserType operator--(int);
84
90 template<typename COOKED_TYPE>
91 COOKED_TYPE getAsCooked();
92
98 template<typename COOKED_TYPE>
99 void setAsCooked(COOKED_TYPE value);
100
106 void writeIfDifferent(UserType newValue, VersionNumber versionNumber = VersionNumber{nullptr},
107 DataValidity validity = DataValidity::ok);
108
113 void setAndWrite(UserType newValue, VersionNumber versionNumber = {});
114
118 UserType readAndGet();
119
120 friend class TransferGroup;
121
122 using NDRegisterAccessorAbstractor<UserType>::get;
123 };
124
125 /********************************************************************************************************************/
126
127 // Template specialisation for string. It does not have the ++ and -- operators
128 template<>
129 class ScalarRegisterAccessor<std::string> : public NDRegisterAccessorAbstractor<std::string> {
130 public:
131 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
133
135
136 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
137 operator std::string&();
138
139 ScalarRegisterAccessor<std::string>& operator=(std::string rightHandSide);
140
146 template<typename COOKED_TYPE>
147 COOKED_TYPE getAsCooked();
148
154 template<typename COOKED_TYPE>
155 void setAsCooked(COOKED_TYPE value);
156
162 void writeIfDifferent(const std::string& newValue, VersionNumber versionNumber = VersionNumber{nullptr},
164
169 void setAndWrite(const std::string& newValue, VersionNumber versionNumber = {});
170
174 std::string readAndGet();
175
176 friend class TransferGroup;
177 };
178
179 /********************************************************************************************************************/
180
185 template<>
187 : public ScalarRegisterAccessor<ChimeraTK::Boolean, void> {
188 public:
190 using ScalarRegisterAccessor<ChimeraTK::Boolean, void>::operator=;
191
195 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
196 operator const bool&() const { return get()->accessData(0, 0); }
197
201 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
202 operator bool&() { return get()->accessData(0, 0); }
203 };
204
205 /********************************************************************************************************************/
206 /********************************************************************************************************************/
207
208 template<user_type UserType, typename TAG>
210 : NDRegisterAccessorAbstractor<UserType>(impl) {
211 static_assert(!std::is_same<UserType, Void>::value,
212 "You cannot create ScalarRegisterAccessor<ChimeraTK::Void>! Use VoidRegisterAccessor instead.");
213 }
214
215 /********************************************************************************************************************/
216
217 template<user_type UserType, typename TAG>
219 static_assert(!std::is_same<UserType, Void>::value,
220 "You cannot create ScalarRegisterAccessor<ChimeraTK::Void>! Use VoidRegisterAccessor instead.");
221 }
222
223 /********************************************************************************************************************/
224
225 template<user_type UserType, typename TAG>
226 template<typename OTHER_TAG>
227 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
231
232 /********************************************************************************************************************/
233
234 template<user_type UserType, typename TAG>
236 get()->accessData(0, 0) = rightHandSide;
237 return *this;
238 }
239
240 /********************************************************************************************************************/
241
242 template<user_type UserType, typename TAG>
244 UserType v = get()->accessData(0, 0);
245 operator=(v + 1);
246 return v;
247 }
248
249 /********************************************************************************************************************/
250
251 template<user_type UserType, typename TAG>
253 UserType v = get()->accessData(0, 0);
254 operator=(v - 1);
255 return v;
256 }
257
258 /********************************************************************************************************************/
259
260 template<user_type UserType, typename TAG>
261 template<typename COOKED_TYPE>
263 return get()->template getAsCooked<COOKED_TYPE>(0, 0);
264 }
265
266 /********************************************************************************************************************/
267
268 template<user_type UserType, typename TAG>
269 template<typename COOKED_TYPE>
271 return get()->template setAsCooked<COOKED_TYPE>(0, 0, value);
272 }
273
274 /********************************************************************************************************************/
275
276 template<user_type UserType, typename TAG>
278 UserType newValue, VersionNumber versionNumber, DataValidity validity) {
279 if(get()->accessData(0, 0) != newValue || this->getVersionNumber() == VersionNumber(nullptr) ||
280 this->dataValidity() != validity) {
281 operator=(newValue);
282 if(versionNumber == VersionNumber{nullptr}) {
283 versionNumber = {};
284 }
285 this->setDataValidity(validity);
286 this->write(versionNumber);
287 }
288 }
289
290 /********************************************************************************************************************/
291
292 template<user_type UserType, typename TAG>
294 operator=(newValue);
295 this->write(versionNumber);
296 }
297
298 /********************************************************************************************************************/
299
300 template<user_type UserType, typename TAG>
302 this->read();
303 return get()->accessData(0, 0);
304 }
305
306 /********************************************************************************************************************/
307 /********************************************************************************************************************/
308
312
313 /********************************************************************************************************************/
314
316 return boost::static_pointer_cast<NDRegisterAccessor<std::string>>(_impl)->accessData(0, 0);
317 }
318
319 /********************************************************************************************************************/
320
322 std::string rightHandSide) {
323 boost::static_pointer_cast<NDRegisterAccessor<std::string>>(_impl)->accessData(0, 0) = std::move(rightHandSide);
324 return *this;
325 }
326
327 /********************************************************************************************************************/
328
329 template<typename COOKED_TYPE>
331 return get()->template getAsCooked<COOKED_TYPE>(0, 0);
332 }
333
334 /********************************************************************************************************************/
335
336 template<typename COOKED_TYPE>
338 return get()->template setAsCooked<COOKED_TYPE>(0, 0, value);
339 }
340
341 /********************************************************************************************************************/
342
344 const std::string& newValue, VersionNumber versionNumber, DataValidity validity) {
345 if(get()->accessData(0, 0) != newValue || this->getVersionNumber() == VersionNumber(nullptr) ||
346 this->dataValidity() != validity) {
347 operator=(newValue);
348 if(versionNumber == VersionNumber{nullptr}) versionNumber = {};
349 this->setDataValidity(validity);
350 this->write(versionNumber);
351 }
352 }
353
354 /********************************************************************************************************************/
355
357 const std::string& newValue, VersionNumber versionNumber) {
358 operator=(newValue);
359 this->write(versionNumber);
360 }
361
362 /********************************************************************************************************************/
363
365 this->read();
366 return get()->accessData(0, 0);
367 }
368
369 /********************************************************************************************************************/
370 // Do not declare the template for all user types as extern here.
371 // This could avoid optimisation of the inline code.
372
373} // namespace ChimeraTK
Wrapper Class to avoid vector<bool> problems.
Base class for the register accessor abstractors (ScalarRegisterAccessor, OneDRegisterAccessor and Tw...
N-dimensional register accessor.
Accessor class to read and write scalar registers transparently by using the accessor object like a v...
UserType readAndGet()
Convenience function to read and return a value of UserType.
UserType operator++(int)
Post-increment operator for the first element.
void writeIfDifferent(UserType newValue, VersionNumber versionNumber=VersionNumber{nullptr}, DataValidity validity=DataValidity::ok)
Convenience function to set and write new value if it differes from the current value.
ScalarRegisterAccessor & operator--()
Pre-decrement operator for the first element.
ScalarRegisterAccessor & operator=(UserType rightHandSide)
Assignment operator, assigns the first element.
ScalarRegisterAccessor(boost::shared_ptr< NDRegisterAccessor< UserType > > impl)
Create instance from pointer to implementation.
COOKED_TYPE getAsCooked()
Get the cooked values in case the accessor is a raw accessor (which does not do data conversion).
ScalarRegisterAccessor & operator++()
Pre-increment operator for the first element.
void setAsCooked(COOKED_TYPE value)
Set the cooked values in case the accessor is a raw accessor (which does not do data conversion).
ScalarRegisterAccessor()
Placeholder constructor, to allow late initialisation of the accessor, e.g.
UserType operator--(int)
Post-decrement operator for the first element.
void setAndWrite(UserType newValue, VersionNumber versionNumber={})
Convenience function to set and write new value.
DataValidity dataValidity() const
Return current validity of the data.
Group multiple data accessors to efficiently trigger data transfers on the whole group.
Class for generating and holding version numbers without exposing a numeric representation.
DataValidity
The current state of the data.
STL namespace.