ChimeraTK-DeviceAccess  03.18.00
OneDRegisterAccessor.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 namespace ChimeraTK {
8 
9  /********************************************************************************************************************/
10 
19  template<typename UserType>
21  public:
28  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
29  OneDRegisterAccessor(boost::shared_ptr<NDRegisterAccessor<UserType>> impl);
30 
38 
46  UserType& operator[](unsigned int element) { return get()->accessData(0, element); }
47 
51  unsigned int getNElements() { return get()->getNumberOfSamples(); }
52 
53  /* Access data with std::vector-like iterators */
54  using iterator = typename std::vector<UserType>::iterator;
55  using const_iterator = typename std::vector<UserType>::const_iterator;
56  using reverse_iterator = typename std::vector<UserType>::reverse_iterator;
57  using const_reverse_iterator = typename std::vector<UserType>::const_reverse_iterator;
58  iterator begin() { return get()->accessChannel(0).begin(); }
59  const_iterator begin() const { return get()->accessChannel(0).cbegin(); }
60  const_iterator cbegin() const { return get()->accessChannel(0).cbegin(); }
61  iterator end() { return get()->accessChannel(0).end(); }
62  const_iterator end() const { return get()->accessChannel(0).cend(); }
63  const_iterator cend() const { return get()->accessChannel(0).cend(); }
64  reverse_iterator rbegin() { return get()->accessChannel(0).rbegin(); }
65  const_reverse_iterator rbegin() const { return get()->accessChannel(0).crbegin(); }
66  const_reverse_iterator crbegin() const { return get()->accessChannel(0).crbegin(); }
67  reverse_iterator rend() { return get()->accessChannel(0).rend(); }
68  const_reverse_iterator rend() const { return get()->accessChannel(0).crend(); }
69  const_reverse_iterator crend() const { return get()->accessChannel(0).crend(); }
70 
74  void swap(std::vector<UserType>& x) noexcept;
75 
79  OneDRegisterAccessor<UserType>& operator=(const std::vector<UserType>& x);
80 
86  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
87  operator const std::vector<UserType>&() { return get()->accessChannel(0); }
88 
96  UserType* data() { return get()->accessChannel(0).data(); }
97 
102  template<typename COOKED_TYPE>
103  COOKED_TYPE getAsCooked(unsigned int sample);
104 
109  template<typename COOKED_TYPE>
110  void setAsCooked(unsigned int sample, COOKED_TYPE value);
111 
117  void writeIfDifferent(const std::vector<UserType>& newValue, VersionNumber versionNumber = VersionNumber{nullptr},
118  DataValidity validity = DataValidity::ok);
119 
120  friend class TransferGroup;
121 
123  };
124 
125  /********************************************************************************************************************/
126  /********************************************************************************************************************/
127 
128  template<typename UserType>
130  : NDRegisterAccessorAbstractor<UserType>(impl) {
131  static_assert(!std::is_same<UserType, Void>::value,
132  "You cannot create OneDRegisterAccessor<ChimeraTK::Void>! Use VoidRegisterAccessor instead.");
133 
134  if(get()->getNumberOfChannels() != 1) {
135  throw ChimeraTK::logic_error(std::string("The OneDRegisterAccessor has a too low ") +
136  "dimension to access the register " + impl->getName());
137  }
138  }
139 
140  /********************************************************************************************************************/
141 
142  template<typename UserType>
144  static_assert(!std::is_same<UserType, Void>::value,
145  "You cannot create OneDRegisterAccessor<ChimeraTK::Void>! Use VoidRegisterAccessor instead.");
146  }
147 
148  /********************************************************************************************************************/
149 
153  template<typename UserType>
154  void OneDRegisterAccessor<UserType>::swap(std::vector<UserType>& x) noexcept {
155  if(x.size() != get()->accessChannel(0).size()) {
156  // Do not throw in swap() and rather terminated. See CPP core guidlines C.85
157  // https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c85-make-swap-noexcept
158  std::cerr << "Swapping with a buffer of a different size is not allowed." << std::endl;
159  std::exit(1);
160  }
161  get()->accessChannel(0).swap(x);
162  }
163 
164  /********************************************************************************************************************/
165 
169  template<typename UserType>
171  if(x.size() != get()->accessChannel(0).size()) {
172  throw ChimeraTK::logic_error("Copying in a buffer of a different size is not allowed.");
173  }
174  get()->accessChannel(0) = x;
175  return *this;
176  }
177 
178  /********************************************************************************************************************/
179 
184  template<typename UserType>
185  template<typename COOKED_TYPE>
186  COOKED_TYPE OneDRegisterAccessor<UserType>::getAsCooked(unsigned int sample) {
187  return get()->template getAsCooked<COOKED_TYPE>(0, sample);
188  }
189 
190  /********************************************************************************************************************/
191 
196  template<typename UserType>
197  template<typename COOKED_TYPE>
198  void OneDRegisterAccessor<UserType>::setAsCooked(unsigned int sample, COOKED_TYPE value) {
199  return get()->template setAsCooked<COOKED_TYPE>(0, sample, value);
200  }
201 
202  /********************************************************************************************************************/
203 
209  template<typename UserType>
211  const std::vector<UserType>& newValue, VersionNumber versionNumber, DataValidity validity) {
212  if(!std::equal(newValue.begin(), newValue.end(), get()->accessChannel(0).begin()) ||
213  this->getVersionNumber() == VersionNumber(nullptr) || this->dataValidity() != validity) {
214  operator=(newValue);
215  if(versionNumber == VersionNumber{nullptr}) versionNumber = {};
216  this->setDataValidity(validity);
217  this->write(versionNumber);
218  }
219  }
220 
221  /********************************************************************************************************************/
222 
223  // Do not declare the template for all user types as extern here.
224  // This could avoid optimisation of the inline code.
225 
226 } // namespace ChimeraTK
ChimeraTK::OneDRegisterAccessor::rend
reverse_iterator rend()
Definition: OneDRegisterAccessor.h:67
ChimeraTK::OneDRegisterAccessor::crend
const_reverse_iterator crend() const
Definition: OneDRegisterAccessor.h:69
ChimeraTK::OneDRegisterAccessor::rbegin
reverse_iterator rbegin()
Definition: OneDRegisterAccessor.h:64
NDRegisterAccessorAbstractor.h
ChimeraTK::OneDRegisterAccessor::end
const_iterator end() const
Definition: OneDRegisterAccessor.h:62
ChimeraTK::OneDRegisterAccessor< unsigned char >::reverse_iterator
typename std::vector< unsigned char >::reverse_iterator reverse_iterator
Definition: OneDRegisterAccessor.h:56
ChimeraTK::OneDRegisterAccessor::end
iterator end()
Definition: OneDRegisterAccessor.h:61
ChimeraTK::OneDRegisterAccessor::writeIfDifferent
void writeIfDifferent(const std::vector< 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: OneDRegisterAccessor.h:210
ChimeraTK::OneDRegisterAccessor::crbegin
const_reverse_iterator crbegin() const
Definition: OneDRegisterAccessor.h:66
ChimeraTK::OneDRegisterAccessor::cend
const_iterator cend() const
Definition: OneDRegisterAccessor.h:63
ChimeraTK::OneDRegisterAccessor::getNElements
unsigned int getNElements()
Return number of elements/samples in the register.
Definition: OneDRegisterAccessor.h:51
ChimeraTK::OneDRegisterAccessor< unsigned char >::iterator
typename std::vector< unsigned char >::iterator iterator
Definition: OneDRegisterAccessor.h:54
ChimeraTK::TransferGroup
Group multiple data accessors to efficiently trigger data transfers on the whole group.
Definition: TransferGroup.h:26
ChimeraTK::OneDRegisterAccessor< unsigned char >::const_iterator
typename std::vector< unsigned char >::const_iterator const_iterator
Definition: OneDRegisterAccessor.h:55
ChimeraTK::OneDRegisterAccessor
Accessor class to read and write registers transparently by using the accessor object like a vector o...
Definition: OneDRegisterAccessor.h:20
ChimeraTK::OneDRegisterAccessor::data
UserType * data()
Return a direct pointer to the memory buffer storng the elements.
Definition: OneDRegisterAccessor.h:96
ChimeraTK::DataValidity::ok
@ ok
ChimeraTK::DataValidity
DataValidity
The current state of the data.
Definition: TransferElement.h:41
ChimeraTK::OneDRegisterAccessor::begin
const_iterator begin() const
Definition: OneDRegisterAccessor.h:59
ChimeraTK::OneDRegisterAccessor::rend
const_reverse_iterator rend() const
Definition: OneDRegisterAccessor.h:68
ChimeraTK::NDRegisterAccessorAbstractor
Base class for the register accessor abstractors (ScalarRegisterAccessor, OneDRegisterAccessor and Tw...
Definition: NDRegisterAccessorAbstractor.h:19
ChimeraTK::OneDRegisterAccessor::rbegin
const_reverse_iterator rbegin() const
Definition: OneDRegisterAccessor.h:65
ChimeraTK::OneDRegisterAccessor::setAsCooked
void setAsCooked(unsigned int sample, COOKED_TYPE value)
Set the cooked values in case the accessor is a raw accessor (which does not do data conversion).
Definition: OneDRegisterAccessor.h:198
ChimeraTK::OneDRegisterAccessor::operator=
OneDRegisterAccessor< UserType > & operator=(const std::vector< UserType > &x)
Copy content of (cooked) buffer from std::vector.
Definition: OneDRegisterAccessor.h:170
ChimeraTK::TransferType::write
@ write
ChimeraTK::OneDRegisterAccessor::swap
void swap(std::vector< UserType > &x) noexcept
Swap content of (cooked) buffer with std::vector.
Definition: OneDRegisterAccessor.h:154
ChimeraTK::OneDRegisterAccessor::cbegin
const_iterator cbegin() const
Definition: OneDRegisterAccessor.h:60
ChimeraTK::NDRegisterAccessorAbstractor::get
NDRegisterAccessor< UserType > * get()
Definition: NDRegisterAccessorAbstractor.h:80
ChimeraTK::OneDRegisterAccessor::begin
iterator begin()
Definition: OneDRegisterAccessor.h:58
ChimeraTK::VersionNumber
Class for generating and holding version numbers without exposing a numeric representation.
Definition: VersionNumber.h:23
ChimeraTK::OneDRegisterAccessor::operator[]
UserType & operator[](unsigned int element)
Get or set buffer content by [] operator.
Definition: OneDRegisterAccessor.h:46
ChimeraTK::OneDRegisterAccessor::getAsCooked
COOKED_TYPE getAsCooked(unsigned int sample)
Get the cooked values in case the accessor is a raw accessor (which does not do data conversion).
Definition: OneDRegisterAccessor.h:186
ChimeraTK::OneDRegisterAccessor::OneDRegisterAccessor
OneDRegisterAccessor()
Placeholder constructer, to allow late initialisation of the accessor, e.g.
Definition: OneDRegisterAccessor.h:143
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::NDRegisterAccessor
N-dimensional register accessor.
Definition: ForwardDeclarations.h:17
ChimeraTK::logic_error
Exception thrown when a logic error has occured.
Definition: Exception.h:51
ChimeraTK::OneDRegisterAccessor< unsigned char >::const_reverse_iterator
typename std::vector< unsigned char >::const_reverse_iterator const_reverse_iterator
Definition: OneDRegisterAccessor.h:57