Merge branch 'developer' into MH01_debug

This commit is contained in:
2026-01-05 15:26:15 +01:00
55 changed files with 3924 additions and 1098 deletions

View File

@@ -11,6 +11,7 @@
#include "sls/TimeHelper.h"
#include "sls/TypeTraits.h"
#include "sls/bit_utils.h"
#include "sls/sls_detector_defs.h"
#include "sls/sls_detector_exceptions.h"
#include "sls/string_utils.h"
@@ -65,6 +66,7 @@ std::ostream &operator<<(std::ostream &os,
std::string ToString(const slsDetectorDefs::pedestalParameters &r);
std::ostream &operator<<(std::ostream &os,
const slsDetectorDefs::pedestalParameters &r);
const std::string &ToString(const std::string &s);
/** Convert std::chrono::duration with specified output unit */
@@ -324,6 +326,8 @@ template <> defs::gainMode StringTo(const std::string &s);
template <> defs::polarity StringTo(const std::string &s);
template <> defs::timingInfoDecoder StringTo(const std::string &s);
template <> defs::collectionMode StringTo(const std::string &s);
template <> RegisterAddress StringTo(const std::string &s);
template <> RegisterValue StringTo(const std::string &s);
template <> uint8_t StringTo(const std::string &s);
template <> uint16_t StringTo(const std::string &s);

View File

@@ -3,6 +3,7 @@
#pragma once
#include <bitset>
#include <cstdint>
#include <vector>
namespace sls {
template <typename T> std::vector<int> getSetBits(T val) {
@@ -18,4 +19,87 @@ template <typename T> std::vector<int> getSetBits(T val) {
}
return set_bits;
}
class RegisterAddress {
private:
uint32_t value_{0};
public:
constexpr RegisterAddress() noexcept = default;
constexpr explicit RegisterAddress(uint32_t value) : value_(value) {}
std::string str() const;
constexpr uint32_t value() const noexcept { return value_; }
constexpr bool operator==(const RegisterAddress &other) const {
return (value_ == other.value_);
}
constexpr bool operator!=(const RegisterAddress &other) const {
return (value_ != other.value_);
}
};
class BitAddress {
private:
RegisterAddress addr_{0};
uint32_t bitPos_{0};
public:
constexpr BitAddress() noexcept = default;
BitAddress(RegisterAddress address, uint32_t bitPosition);
std::string str() const;
constexpr RegisterAddress address() const noexcept { return addr_; }
constexpr uint32_t bitPosition() const noexcept { return bitPos_; }
constexpr bool operator==(const BitAddress &other) const {
return (addr_ == other.addr_ && bitPos_ == other.bitPos_);
}
constexpr bool operator!=(const BitAddress &other) const {
return !(*this == other);
}
};
class RegisterValue {
private:
uint32_t value_{0};
public:
constexpr RegisterValue() noexcept = default;
explicit constexpr RegisterValue(uint32_t value) noexcept : value_(value) {}
std::string str() const;
constexpr uint32_t value() const noexcept { return value_; }
constexpr RegisterValue &operator|=(const RegisterValue &rhs) noexcept {
value_ |= rhs.value();
return *this;
}
constexpr RegisterValue operator|(const RegisterValue &rhs) const noexcept {
RegisterValue tmp(*this);
tmp |= rhs;
return tmp;
}
constexpr RegisterValue &operator|=(uint32_t rhs) noexcept {
value_ |= rhs;
return *this;
}
constexpr RegisterValue operator|(uint32_t rhs) const noexcept {
RegisterValue tmp(*this);
tmp |= rhs;
return tmp;
}
constexpr bool operator==(const RegisterValue &other) const noexcept {
return value_ == other.value_;
}
constexpr bool operator!=(const RegisterValue &other) const noexcept {
return value_ != other.value_;
}
};
std::ostream &operator<<(std::ostream &os, const RegisterAddress &r);
std::ostream &operator<<(std::ostream &os, const BitAddress &r);
std::ostream &operator<<(std::ostream &os, const RegisterValue &r);
} // namespace sls

View File

@@ -181,20 +181,18 @@ typename std::enable_if<is_container<T>::value, bool>::type
stableRemoveDuplicates(T &c) {
auto containerSize = c.size();
std::set<typename T::value_type> seen;
c.erase(
std::remove_if(c.begin(), c.end(),
[&](const typename T::value_type& val) {
return !seen.insert(val).second; // erase if already seen
}),
c.end()
);
c.erase(std::remove_if(
c.begin(), c.end(),
[&](const typename T::value_type &val) {
return !seen.insert(val).second; // erase if already seen
}),
c.end());
if (c.size() != containerSize) {
return true;
}
return false;
}
} // namespace sls
#endif // CONTAINER_UTILS_H

View File

@@ -5,6 +5,7 @@
#include <cassert>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
@@ -33,6 +34,35 @@ void strcpy_safe(char (&destination)[array_size], const std::string &source) {
destination[array_size - 1] = '\0';
}
// Runtime-checked variant — throws if it won't fit
template <size_t array_size>
void strcpy_checked(char (&destination)[array_size], const char *source) {
if (!source)
throw std::runtime_error("Null source pointer in strcpy_checked");
size_t len = std::strlen(source);
if (len >= (array_size - 1)) {
throw std::runtime_error("String length (" + std::to_string(len) +
") should be less than " +
std::to_string(array_size - 1) + " chars");
}
std::strncpy(destination, source, array_size - 1);
destination[array_size - 1] = '\0';
}
template <size_t array_size>
void strcpy_checked(char (&destination)[array_size],
const std::string &source) {
if (source.size() >= (array_size - 1)) {
throw std::runtime_error("String length (" +
std::to_string(source.size()) +
") should be less than " +
std::to_string(array_size - 1) + " chars");
}
std::strncpy(destination, source.c_str(), array_size - 1);
destination[array_size - 1] = '\0';
}
/*
Removes all occurrences of the specified char from a c string
Templated on array size to ensure no access after buffer limits.
@@ -58,6 +88,8 @@ std::vector<std::string> split(const std::string &strToSplit, char delimeter);
std::string RemoveUnit(std::string &str);
bool is_int(const std::string &s);
/** '0x200' is also an int here */
bool is_hex_or_dec_uint(const std::string &s);
bool replace_first(std::string *s, const std::string &substr,
const std::string &repl);