Files
CX9261API-C/cx9261A_api/utils.h
T
Gatsby 2fc5941f0f refactor: use standard integer types; remove <algorithm> dependency
- Replaced unsigned char,  int and long long with uint8_t int32_t and int64_t for platform independence
- Removed <algorithm> dependency, implemented custom alternatives
2024-11-07 14:13:37 +08:00

110 lines
2.9 KiB
C++

/**
* @file utils.h
*/
#ifndef CX9261ADRIVER_UTILS_H
#define CX9261ADRIVER_UTILS_H
#include <cstdint>
#include <bitset>
#include <cmath>
#include <string>
namespace CX9261A {
template <typename T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
if (v < lo) return lo;
if (v > hi) return hi;
return v;
}
template <typename Float>
std::int32_t round32(Float f) {
return static_cast<std::int32_t>(std::round(f));
}
template <typename Float>
std::int64_t round64(Float f) {
return static_cast<std::int64_t>(std::round(f));
}
template <typename Float>
std::int32_t floor32(Float f) {
return static_cast<std::int32_t>(std::floor(f));
}
template <typename Float>
std::int64_t floor64(Float f) {
return static_cast<std::int64_t>(std::floor(f));
}
template <typename Float>
std::int32_t ceil32(Float f) {
return static_cast<std::int32_t>(std::ceil(f));
}
template <typename Float>
std::int64_t ceil64(Float f) {
return static_cast<std::int64_t>(std::ceil(f));
}
template <typename T>
size_t search_first_ge(const std::vector<T>& arr, const T& value) {
size_t ret = arr.size(); // 如果搜索失败默认返回数组长度
for (size_t i = 0; i < arr.size(); ++i) {
if (arr[i] >= value) {
// 找到更小的元素时更新下标
if (ret == arr.size() || arr[i] < arr[ret]) {
ret = i;
}
}
}
return ret;
}
/**
* @brief Register类,提供方便的位操作函数
*/
class Register {
public:
template <typename T = int>
constexpr Register(const T value = 0) {
static_assert(std::is_integral_v<T>, "Register value must be integral!");
m_value = static_cast<unsigned long long>(value);
}
/**
* 以十进制返回寄存器值
*/
std::uint8_t value() const { return static_cast<std::uint8_t>(m_value.to_ulong()); }
/**
* 对寄存器值进行部分值的替换操作
* 例:replace(7, 4, 0b1111); 使寄存器的高四位为1
* @param start 起始位
* @param end 中止位
* @param after 要替换的值
*/
void replace(const std::uint8_t start, const std::uint8_t end, std::uint8_t after) {
for (auto i = end; i <= start; ++i) {
m_value[i] = (after >> (i - end)) & 0b1;
}
}
auto operator[](const size_t position) { return m_value[position]; }
template <typename Type>
operator Type() const {
static_assert(std::is_integral_v<Type>, "Type must be an integral");
return static_cast<Type>(m_value.to_ulong());
}
private:
std::bitset<8> m_value{};
};
template <int N>
std::string frac2bin(const double frac) {
const long double num = frac * (pow(2.0, N));
std::string ret = std::bitset<N>(std::floor(num)).to_string();
return ret;
}
} // namespace CX9261A
#endif // CX9261ADRIVER_UTILS_H