9#include <boost/circular_buffer.hpp>
10#include <boost/fusion/container.hpp>
93 template<
typename... ACCESSORTYPES>
95 const std::string& errorMessage,
const std::function<
bool(
void)>& isValidFunction, ACCESSORTYPES&... accessors);
101 template<std::ranges::input_range R>
103 void add(
const std::string& errorMessage,
const std::function<
bool(
void)>& isValidFunction,
const R& accessors);
113 template<
typename UserType,
template<
typename>
typename Accessor>
114 void setFallback(Accessor<UserType>& accessor, UserType value);
116 template<
typename UserType,
template<
typename>
typename Accessor>
117 void setFallback(Accessor<UserType>& accessor, std::vector<UserType> value);
124 void setErrorFunction(
const std::function<
void(
const std::string&)>& errorFunction);
141 bool validate(
const ChimeraTK::TransferElementID& change);
186 template<
typename UserType,
template<
typename>
typename Accessor>
199 template<
typename UserType,
template<
typename>
typename Accessor>
233 Validator*
addValidator(
const std::function<
bool(
void)>& isValidFunction,
const std::string& errorMessage);
235 template<
typename UserType,
template<
typename>
typename Accessor>
242 std::map<ChimeraTK::TransferElementID, std::shared_ptr<VariableBase>>
_variableMap;
245 std::map<ChimeraTK::TransferElementID, std::vector<Validator*>>
_validatorMap;
261 template<
typename UserType,
template<
typename>
typename Accessor>
269 template<
typename... ACCESSORTYPES>
271 const std::string& errorMessage,
const std::function<
bool(
void)>& isValidFunction, ACCESSORTYPES&... accessors) {
272 boost::fusion::list<ACCESSORTYPES&...> accessorList{accessors...};
273 static_assert(boost::fusion::size(accessorList) > 0,
"Must specify at least one accessor!");
274 assert(isValidFunction !=
nullptr);
276 auto* validator =
addValidator(isValidFunction, errorMessage);
284 template<std::ranges::input_range R>
287 const std::string& errorMessage,
const std::function<
bool(
void)>& isValidFunction,
const R& accessors) {
288 assert(isValidFunction !=
nullptr);
291 _validators.emplace_back(isValidFunction, errorMessage);
294 for(
auto& accessor : accessors) {
302 template<
typename UserType,
template<
typename>
typename Accessor>
305 auto pv = std::dynamic_pointer_cast<Variable<UserType, Accessor>>(
_variableMap.at(accessor.getId()));
306 assert(pv !=
nullptr);
307 if(pv->fallbackValue.size() != 1) {
308 throw ChimeraTK::logic_error(
309 "UserInputValidator::setFallback() with scalar value called for array-typed accessor '" + accessor.getName() +
312 pv->fallbackValue[0] = value;
317 template<
typename UserType,
template<
typename>
typename Accessor>
320 auto pv = std::dynamic_pointer_cast<Variable<UserType, Accessor>>(
_variableMap.at(accessor.getId()));
321 assert(pv !=
nullptr);
322 if(pv->fallbackValue.size() != value.size()) {
323 throw ChimeraTK::logic_error(
324 "UserInputValidator::setFallback() with called with mismatching array length for accessor '" +
325 accessor.getName() +
"'.");
327 pv->fallbackValue = value;
331 template<
typename UserType,
template<
typename>
typename Accessor>
338 _variableMap[accessor.getId()] = std::make_shared<Variable<UserType, Accessor>>(accessor);
341 auto hook = boost::dynamic_pointer_cast<AccessorHook>(accessor.getImpl());
343 hook->onAddValidator(*
this);
349 template<
typename UserType,
template<
typename>
typename Accessor>
351 : accessor(validatedAccessor) {
355 throw ChimeraTK::logic_error(
"UserInputValidator can only be used with push-type inputs.");
369 template<
typename UserType,
template<
typename>
typename Accessor>
371 if(type == RejectionType::downstream && !lastAcceptedValue.empty()) {
372 lastAcceptedValue.pop_back();
375 if(lastAcceptedValue.empty()) {
376 accessor = fallbackValue[0];
379 accessor = lastAcceptedValue.back()[0];
383 if(lastAcceptedValue.empty()) {
384 accessor = fallbackValue;
387 accessor = lastAcceptedValue.back();
392 auto hook = boost::dynamic_pointer_cast<AccessorHook>(accessor.getImpl());
397 if(accessor.isWriteable()) {
403 template<
typename UserType,
template<
typename>
typename Accessor>
406 auto savedValue = std::vector<UserType>(1);
407 savedValue[0] = accessor;
408 lastAcceptedValue.push_back(savedValue);
411 auto savedValue = std::vector<UserType>(accessor.getNElements());
412 savedValue = accessor;
413 lastAcceptedValue.push_back(savedValue);
417 auto hook = boost::dynamic_pointer_cast<AccessorHook>(accessor.getImpl());
424 template<
typename UserType,
template<
typename>
typename Accessor>
426 historyLength = 3 * size;
427 lastAcceptedValue.set_capacity(historyLength);
void addTag(const std::string &tag)
Add a tag to all Application-type nodes inside this group.
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
Accessor for scalar variables (i.e.
Class describing a node of a variable network.
InvalidityTracer application module.
Logger::StreamProxy logger(Logger::Severity severity, std::string context)
Convenience function to obtain the logger stream.