ChimeraTK-DeviceAccess  03.18.00
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 #include <type_traits>
7 
8 namespace ChimeraTK {
9 
10  /********************************************************************************************************************/
11 
23  template<typename UserType, typename TAG = std::nullptr_t>
25  public:
32  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
34 
42 
44  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
45  operator UserType&() { return get()->accessData(0, 0); }
46 
48  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
49  operator const UserType&() const { return get()->accessData(0, 0); }
50 
55  template<typename OTHER_TAG>
56  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
58 
63  template<typename OTHER_TAG>
64  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
66  return *this;
67  }
68 
70  ScalarRegisterAccessor& operator=(UserType rightHandSide);
71 
73  ScalarRegisterAccessor& operator++() { return operator=(get()->accessData(0, 0) + 1); }
74 
76  ScalarRegisterAccessor& operator--() { return operator=(get()->accessData(0, 0) - 1); }
77 
79  UserType operator++(int);
80 
82  UserType operator--(int);
83 
89  template<typename COOKED_TYPE>
90  COOKED_TYPE getAsCooked();
91 
97  template<typename COOKED_TYPE>
98  void setAsCooked(COOKED_TYPE value);
99 
105  void writeIfDifferent(UserType newValue, VersionNumber versionNumber = VersionNumber{nullptr},
106  DataValidity validity = DataValidity::ok);
107 
112  void setAndWrite(UserType newValue, VersionNumber versionNumber = {});
113 
117  UserType readAndGet();
118 
119  friend class TransferGroup;
120 
122  };
123 
124  /********************************************************************************************************************/
125 
126  // Template specialisation for string. It does not have the ++ and -- operators
127  template<>
128  class ScalarRegisterAccessor<std::string> : public NDRegisterAccessorAbstractor<std::string> {
129  public:
130  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
132 
133  ScalarRegisterAccessor() = default;
134 
135  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
136  operator std::string&();
137 
138  ScalarRegisterAccessor<std::string>& operator=(std::string rightHandSide);
139 
145  template<typename COOKED_TYPE>
146  COOKED_TYPE getAsCooked();
147 
153  template<typename COOKED_TYPE>
154  void setAsCooked(COOKED_TYPE value);
155 
161  void writeIfDifferent(const std::string& newValue, VersionNumber versionNumber = VersionNumber{nullptr},
163 
168  void setAndWrite(const std::string& newValue, VersionNumber versionNumber = {});
169 
173  std::string readAndGet();
174 
175  friend class TransferGroup;
176  };
177 
178  /********************************************************************************************************************/
179 
184  template<>
185  class ScalarRegisterAccessor<ChimeraTK::Boolean, std::nullptr_t>
186  : public ScalarRegisterAccessor<ChimeraTK::Boolean, void> {
187  public:
190 
194  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
195  operator const bool&() const { return get()->accessData(0, 0); }
196 
200  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
201  operator bool&() { return get()->accessData(0, 0); }
202  };
203 
204  /********************************************************************************************************************/
205  /********************************************************************************************************************/
206 
207  template<typename UserType, typename TAG>
209  : NDRegisterAccessorAbstractor<UserType>(impl) {
210  static_assert(!std::is_same<UserType, Void>::value,
211  "You cannot create ScalarRegisterAccessor<ChimeraTK::Void>! Use VoidRegisterAccessor instead.");
212  }
213 
214  /********************************************************************************************************************/
215 
216  template<typename UserType, typename TAG>
218  static_assert(!std::is_same<UserType, Void>::value,
219  "You cannot create ScalarRegisterAccessor<ChimeraTK::Void>! Use VoidRegisterAccessor instead.");
220  }
221 
222  /********************************************************************************************************************/
223 
224  template<typename UserType, typename TAG>
225  template<typename OTHER_TAG>
226  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
228  return *this;
229  }
230 
231  /********************************************************************************************************************/
232 
233  template<typename UserType, typename TAG>
235  get()->accessData(0, 0) = rightHandSide;
236  return *this;
237  }
238 
239  /********************************************************************************************************************/
240 
241  template<typename UserType, typename TAG>
243  UserType v = get()->accessData(0, 0);
244  operator=(v + 1);
245  return v;
246  }
247 
248  /********************************************************************************************************************/
249 
250  template<typename UserType, typename TAG>
252  UserType v = get()->accessData(0, 0);
253  operator=(v - 1);
254  return v;
255  }
256 
257  /********************************************************************************************************************/
258 
259  template<typename UserType, typename TAG>
260  template<typename COOKED_TYPE>
262  return get()->template getAsCooked<COOKED_TYPE>(0, 0);
263  }
264 
265  /********************************************************************************************************************/
266 
267  template<typename UserType, typename TAG>
268  template<typename COOKED_TYPE>
270  return get()->template setAsCooked<COOKED_TYPE>(0, 0, value);
271  }
272 
273  /********************************************************************************************************************/
274 
275  template<typename UserType, typename TAG>
277  UserType newValue, VersionNumber versionNumber, DataValidity validity) {
278  if(get()->accessData(0, 0) != newValue || this->getVersionNumber() == VersionNumber(nullptr) ||
279  this->dataValidity() != validity) {
280  operator=(newValue);
281  if(versionNumber == VersionNumber{nullptr}) {
282  versionNumber = {};
283  }
284  this->setDataValidity(validity);
285  this->write(versionNumber);
286  }
287  }
288 
289  /********************************************************************************************************************/
290 
291  template<typename UserType, typename TAG>
292  void ScalarRegisterAccessor<UserType, TAG>::setAndWrite(UserType newValue, VersionNumber versionNumber) {
293  operator=(newValue);
294  this->write(versionNumber);
295  }
296 
297  /********************************************************************************************************************/
298 
299  template<typename UserType, typename TAG>
301  this->read();
302  return get()->accessData(0, 0);
303  }
304 
305  /********************************************************************************************************************/
306  /********************************************************************************************************************/
307 
309  boost::shared_ptr<NDRegisterAccessor<std::string>> impl)
310  : NDRegisterAccessorAbstractor<std::string>(std::move(impl)) {}
311 
312  /********************************************************************************************************************/
313 
315  return boost::static_pointer_cast<NDRegisterAccessor<std::string>>(_impl)->accessData(0, 0);
316  }
317 
318  /********************************************************************************************************************/
319 
321  std::string rightHandSide) {
322  boost::static_pointer_cast<NDRegisterAccessor<std::string>>(_impl)->accessData(0, 0) = std::move(rightHandSide);
323  return *this;
324  }
325 
326  /********************************************************************************************************************/
327 
328  template<typename COOKED_TYPE>
330  return get()->template getAsCooked<COOKED_TYPE>(0, 0);
331  }
332 
333  /********************************************************************************************************************/
334 
335  template<typename COOKED_TYPE>
337  return get()->template setAsCooked<COOKED_TYPE>(0, 0, value);
338  }
339 
340  /********************************************************************************************************************/
341 
343  const std::string& newValue, VersionNumber versionNumber, DataValidity validity) {
344  if(get()->accessData(0, 0) != newValue || this->getVersionNumber() == VersionNumber(nullptr) ||
345  this->dataValidity() != validity) {
346  operator=(newValue);
347  if(versionNumber == VersionNumber{nullptr}) versionNumber = {};
348  this->setDataValidity(validity);
349  this->write(versionNumber);
350  }
351  }
352 
353  /********************************************************************************************************************/
354 
356  const std::string& newValue, VersionNumber versionNumber) {
357  operator=(newValue);
358  this->write(versionNumber);
359  }
360 
361  /********************************************************************************************************************/
362 
364  this->read();
365  return get()->accessData(0, 0);
366  }
367 
368  /********************************************************************************************************************/
369  // Do not declare the template for all user types as extern here.
370  // This could avoid optimisation of the inline code.
371 
372 } // namespace ChimeraTK
ChimeraTK::ScalarRegisterAccessor::setAsCooked
void setAsCooked(COOKED_TYPE value)
Set the cooked values in case the accessor is a raw accessor (which does not do data conversion).
Definition: ScalarRegisterAccessor.h:269
NDRegisterAccessorAbstractor.h
ChimeraTK::TransferElementAbstractor::dataValidity
DataValidity dataValidity() const
Return current validity of the data.
Definition: TransferElementAbstractor.h:202
ChimeraTK::ScalarRegisterAccessor::getAsCooked
COOKED_TYPE getAsCooked()
Get the cooked values in case the accessor is a raw accessor (which does not do data conversion).
Definition: ScalarRegisterAccessor.h:261
ChimeraTK::ScalarRegisterAccessor::operator++
ScalarRegisterAccessor & operator++()
Pre-increment operator for the first element.
Definition: ScalarRegisterAccessor.h:73
ChimeraTK::ScalarRegisterAccessor::setAndWrite
void setAndWrite(UserType newValue, VersionNumber versionNumber={})
Convenience function to set and write new value.
Definition: ScalarRegisterAccessor.h:292
ChimeraTK::ScalarRegisterAccessor::writeIfDifferent
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.
Definition: ScalarRegisterAccessor.h:276
ChimeraTK::ScalarRegisterAccessor::readAndGet
UserType readAndGet()
Convenience function to read and return a value of UserType.
Definition: ScalarRegisterAccessor.h:300
ChimeraTK::TransferElementAbstractor::setDataValidity
void setDataValidity(DataValidity valid=DataValidity::ok)
Set the current DataValidity for this TransferElement.
Definition: TransferElementAbstractor.h:197
ChimeraTK::ScalarRegisterAccessor
Accessor class to read and write scalar registers transparently by using the accessor object like a v...
Definition: ScalarRegisterAccessor.h:24
ChimeraTK::TransferGroup
Group multiple data accessors to efficiently trigger data transfers on the whole group.
Definition: TransferGroup.h:26
ChimeraTK::ScalarRegisterAccessor::operator=
ScalarRegisterAccessor & operator=(UserType rightHandSide)
Assignment operator, assigns the first element.
Definition: ScalarRegisterAccessor.h:234
ChimeraTK::DataValidity::ok
@ ok
ChimeraTK::DataValidity
DataValidity
The current state of the data.
Definition: TransferElement.h:41
ChimeraTK::ScalarRegisterAccessor::ScalarRegisterAccessor
ScalarRegisterAccessor()
Placeholder constructor, to allow late initialisation of the accessor, e.g.
Definition: ScalarRegisterAccessor.h:217
ChimeraTK::NDRegisterAccessorAbstractor
Base class for the register accessor abstractors (ScalarRegisterAccessor, OneDRegisterAccessor and Tw...
Definition: NDRegisterAccessorAbstractor.h:19
ChimeraTK::ScalarRegisterAccessor::operator--
ScalarRegisterAccessor & operator--()
Pre-decrement operator for the first element.
Definition: ScalarRegisterAccessor.h:76
ChimeraTK::TransferType::write
@ write
ChimeraTK::ScalarRegisterAccessor< std::string >
Definition: ScalarRegisterAccessor.h:128
ChimeraTK::NDRegisterAccessorAbstractor::get
NDRegisterAccessor< UserType > * get()
Definition: NDRegisterAccessorAbstractor.h:80
ChimeraTK::VersionNumber
Class for generating and holding version numbers without exposing a numeric representation.
Definition: VersionNumber.h:23
ChimeraTK::TransferElementAbstractor::_impl
boost::shared_ptr< TransferElement > _impl
Untyped pointer to implementation.
Definition: TransferElementAbstractor.h:225
ChimeraTK::TransferElementAbstractor::write
bool write(ChimeraTK::VersionNumber versionNumber={})
Write the data to device.
Definition: TransferElementAbstractor.h:89
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::TransferElementAbstractor::getVersionNumber
ChimeraTK::VersionNumber getVersionNumber() const
Returns the version number that is associated with the last transfer (i.e.
Definition: TransferElementAbstractor.h:83
ChimeraTK::TransferElementAbstractor::read
void read()
Read the data from the device.
Definition: TransferElementAbstractor.h:57
ChimeraTK::TransferType::read
@ read
ChimeraTK::Boolean
Wrapper Class to avoid vector<bool> problems.
Definition: SupportedUserTypes.h:21
ChimeraTK::NDRegisterAccessor
N-dimensional register accessor.
Definition: ForwardDeclarations.h:17