ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
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
7namespace ChimeraTK {
8
9 /********************************************************************************************************************/
10
19 template<user_type UserType>
21 public:
28 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
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
122 using NDRegisterAccessorAbstractor<UserType>::get;
123 };
124
125 /********************************************************************************************************************/
126 /********************************************************************************************************************/
127
128 template<user_type 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<user_type 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<user_type 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<user_type 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<user_type 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<user_type 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<user_type 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
Base class for the register accessor abstractors (ScalarRegisterAccessor, OneDRegisterAccessor and Tw...
N-dimensional register accessor.
Accessor class to read and write registers transparently by using the accessor object like a vector o...
OneDRegisterAccessor()
Placeholder constructer, to allow late initialisation of the accessor, e.g.
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.
typename std::vector< UserType >::const_reverse_iterator const_reverse_iterator
OneDRegisterAccessor(boost::shared_ptr< NDRegisterAccessor< UserType > > impl)
Create accessor from pointer to implementation.
UserType * data()
Return a direct pointer to the memory buffer storng the elements.
UserType & operator[](unsigned int element)
Get or set buffer content by [] operator.
const_reverse_iterator rbegin() const
const_reverse_iterator crbegin() const
typename std::vector< UserType >::iterator iterator
void swap(std::vector< UserType > &x) noexcept
Swap content of (cooked) buffer with std::vector.
unsigned int getNElements()
Return number of elements/samples in the register.
COOKED_TYPE getAsCooked(unsigned int sample)
Get the cooked values in case the accessor is a raw accessor (which does not do data conversion).
OneDRegisterAccessor< UserType > & operator=(const std::vector< UserType > &x)
Copy content of (cooked) buffer from std::vector.
typename std::vector< UserType >::reverse_iterator reverse_iterator
const_reverse_iterator crend() const
typename std::vector< UserType >::const_iterator const_iterator
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).
const_reverse_iterator rend() const
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.
Exception thrown when a logic error has occured.
Definition Exception.h:51
DataValidity
The current state of the data.