mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-12 21:07:13 +02:00
Moving headers into include/sls (#212)
This commit is contained in:
142
slsDetectorSoftware/include/sls/Result.h
Normal file
142
slsDetectorSoftware/include/sls/Result.h
Normal file
@ -0,0 +1,142 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file Result.h
|
||||
* Result is a thin wrapper around std::vector and used for returning values
|
||||
* from the detector. Since every module could have a different value, we need
|
||||
* to return a vector instead of just a single value.
|
||||
*
|
||||
* Easy conversions to single values are provided using the squash method.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/container_utils.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
/**
|
||||
* @tparam T type to store in the result
|
||||
* @tparam Allocator for the underlying vector, default
|
||||
*/
|
||||
template <class T, class Allocator = std::allocator<T>> class Result {
|
||||
/** wrapped vector */
|
||||
std::vector<T, Allocator> vec;
|
||||
|
||||
public:
|
||||
Result() = default;
|
||||
Result(std::initializer_list<T> list) : vec(list){};
|
||||
|
||||
/** Custom constructor from integer type to Result<ns> or Result<bool> */
|
||||
template <typename V, typename = typename std::enable_if<
|
||||
std::is_integral<V>::value &&
|
||||
(std::is_same<T, time::ns>::value ||
|
||||
std::is_same<T, bool>::value)>::type>
|
||||
Result(const Result<V> &from) {
|
||||
vec.reserve(from.size());
|
||||
for (const auto &item : from)
|
||||
vec.push_back(T(item));
|
||||
}
|
||||
|
||||
/** Custom constructor from integer type to Result<ns> or Result<bool> */
|
||||
template <typename V, typename = typename std::enable_if<
|
||||
std::is_integral<V>::value &&
|
||||
(std::is_same<T, time::ns>::value ||
|
||||
std::is_same<T, bool>::value)>::type>
|
||||
Result(Result<V> &from) {
|
||||
vec.reserve(from.size());
|
||||
for (const auto &item : from)
|
||||
vec.push_back(T(item));
|
||||
}
|
||||
|
||||
/** Custom constructor from integer type to Result<ns> or Result<bool> */
|
||||
template <typename V, typename = typename std::enable_if<
|
||||
std::is_integral<V>::value &&
|
||||
(std::is_same<T, time::ns>::value ||
|
||||
std::is_same<T, bool>::value)>::type>
|
||||
Result(Result<V> &&from) {
|
||||
vec.reserve(from.size());
|
||||
for (const auto &item : from)
|
||||
vec.push_back(T(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward arguments to the constructor of std::vector
|
||||
* @tparam Args template paramter pack to forward
|
||||
*/
|
||||
template <typename... Args>
|
||||
Result(Args &&... args) : vec(std::forward<Args>(args)...) {}
|
||||
|
||||
using value_type = typename std::vector<T>::value_type;
|
||||
using iterator = typename std::vector<T>::iterator;
|
||||
using const_iterator = typename std::vector<T>::const_iterator;
|
||||
using size_type = typename std::vector<T>::size_type;
|
||||
using reference = typename std::vector<T>::reference;
|
||||
using const_reference = typename std::vector<T>::const_reference;
|
||||
|
||||
auto begin() noexcept -> decltype(vec.begin()) { return vec.begin(); }
|
||||
auto begin() const noexcept -> decltype(vec.begin()) { return vec.begin(); }
|
||||
auto cbegin() const noexcept -> decltype(vec.cbegin()) {
|
||||
return vec.cbegin();
|
||||
}
|
||||
auto end() noexcept -> decltype(vec.end()) { return vec.end(); }
|
||||
auto end() const noexcept -> decltype(vec.end()) { return vec.end(); }
|
||||
auto cend() const noexcept -> decltype(vec.cend()) { return vec.cend(); }
|
||||
auto size() const noexcept -> decltype(vec.size()) { return vec.size(); }
|
||||
auto empty() const noexcept -> decltype(vec.empty()) { return vec.empty(); }
|
||||
auto front() -> decltype(vec.front()) { return vec.front(); }
|
||||
auto front() const -> decltype(vec.front()) { return vec.front(); }
|
||||
void reserve(size_type new_cap) { vec.reserve(new_cap); }
|
||||
|
||||
template <typename V>
|
||||
auto push_back(V value) -> decltype(vec.push_back(value)) {
|
||||
vec.push_back(std::forward<V>(value));
|
||||
}
|
||||
|
||||
auto operator[](size_type pos) -> decltype(vec[pos]) { return vec[pos]; }
|
||||
const_reference operator[](size_type pos) const { return vec[pos]; }
|
||||
|
||||
/**
|
||||
* If all elements are equal it returns the front value
|
||||
* otherwise a default constructed T
|
||||
*/
|
||||
T squash() const { return Squash(vec); }
|
||||
|
||||
/**
|
||||
* If all elements are equal it returns the front value
|
||||
* otherwise throws an exception with custom message provided
|
||||
*/
|
||||
T tsquash(const std::string &error_msg) {
|
||||
if (equal())
|
||||
return vec.front();
|
||||
else
|
||||
throw RuntimeError(error_msg);
|
||||
}
|
||||
/**
|
||||
* If all elements are equal return the front value, otherwise
|
||||
* return the supplied default value
|
||||
*/
|
||||
T squash(const T &default_value) const {
|
||||
return Squash(vec, default_value);
|
||||
}
|
||||
|
||||
/** Test whether all elements of the result are equal */
|
||||
bool equal() const noexcept { return allEqual(vec); }
|
||||
|
||||
/** Convert Result<T> to std::vector<T> */
|
||||
operator std::vector<T>() { return vec; }
|
||||
};
|
||||
|
||||
/**
|
||||
* operator << overload to print Result, uses ToString for the conversion
|
||||
* @tparam T type stored in the Result
|
||||
*/
|
||||
template <typename T>
|
||||
std::ostream &operator<<(std::ostream &os, const Result<T> &res) {
|
||||
return os << ToString(res);
|
||||
}
|
||||
|
||||
} // namespace sls
|
Reference in New Issue
Block a user