CaVM/include/Utils/Utils.h
2024-08-19 20:05:06 -04:00

138 lines
2.5 KiB
C++

#ifndef __CAVM_UTILS_UTILS_H
#define __CAVM_UTILS_UTILS_H
#include <Config.h>
#include <SpecTypes.h>
#include <cassert>
#include <cstdint>
#include <stdexcept>
#include <typeinfo>
#include <vector>
#define TYPE(x) typeid(x).name()
#define VEC_ELEM_TYPE(x) x.type().name()
#ifdef CAVM_RUNTIME_CHECK_SUPPORT
#define ASSERT(x) assert(x)
#else
#define ASSERT(x)
#endif
namespace Utils
{
template <typename T, typename X> ALWAYS_INLINE T M_POW(T x, X power)
{
T ret = 1;
if (power == 0)
return 1;
for (int i = 0; i < power; i++)
{
ret *= x;
}
if (power < 0)
{
for (int i = (int)power; i > 0; i++)
{
ret *= 1 / x;
}
}
return ret;
}
template <typename T = unsigned int> ALWAYS_INLINE T Hex2Int(T x)
{
T ret = 0;
int digits = 0;
while (x != 0)
{
T a = x % 10;
ret += a * M_POW(16, digits);
x = (int)(x / 10);
digits += 1;
}
return ret;
}
template <typename T> ALWAYS_INLINE const char *Int2Hex(T x)
{
constexpr const char *digits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
std::vector<char> ret;
while (x != 0)
{
T rem = x % 16;
x = (int)(x / 16);
ret.push_back(digits[rem]);
}
for (int i = 0; i < ret.size() / 2; i++)
{
char tmp = ret[i];
ret[i] = ret[ret.size() - i];
ret[ret.size() - i] = tmp;
}
const char *data = ret.data();
return data;
}
template <typename T> ALWAYS_INLINE std::vector<T> Read(std::vector<T> &vec, int start, int end)
{
std::vector<T> ret;
for (int i = start; i < end; i++)
{
ret.push_back(vec.at(i));
}
return ret;
}
template <typename T> ALWAYS_INLINE std::vector<T> ReadFromStart(std::vector<T> &vec, int end)
{
std::vector<T> ret = Read(vec, 0, end);
for (int i = 0; i < end; i++)
vec.erase(vec.begin());
return ret;
}
template <typename T, typename vec_type = uint8_t> ALWAYS_INLINE T vecToVal(std::vector<vec_type> &vec)
{
if (vec.size() > sizeof(T))
{
throw std::out_of_range("Provided vector larger than type to convert to.");
}
T ret = 0;
for (int i = vec.size() - 1; i >= 0; i--)
{
ret |= vec.at(i) << (i * 8);
}
return ret;
}
template <typename T, typename vec_type> ALWAYS_INLINE T ReadFromStartIntoVal(std::vector<vec_type> &vec, int end)
{
std::vector<uint8_t> val = ReadFromStart<vec_type>(vec, end);
return vecToVal<T>(val);
}
template <typename T, typename vec_type> ALWAYS_INLINE T ReadFromStartIntoVal(std::vector<vec_type> &vec)
{
std::vector<uint8_t> val = ReadFromStart<vec_type>(vec, sizeof(T));
return vecToVal<T>(val);
}
} // namespace Utils
#endif