RISC-V/V203/hello/utils.h

61 lines
2.2 KiB
C
Raw Normal View History

2024-08-17 14:27:07 +02:00
#ifndef UTILS_H
#define UTILS_H
typedef __SIZE_TYPE__ size_t;
template<class T, size_t N>constexpr size_t array_size (T (&) [N]) { return N; }
template<class T, const int N> class TABLE {
T data [N];
public:
/** @brief Konstruktor.
* @param f Ukazatel na constexpr funkci, která pak vytvoří tabulku.
* */
template<typename F> explicit constexpr TABLE (F f) noexcept {
for (int n=0; n<N; n++) data [n] = f (n);
}
/** operator[] vrátí konstantní odkaz na prvek pole, protože se předpokládá,
* že instance této třídy bude jako taková též konstantní
*/
const T & operator[] (const int index) const {
return data [index];
}
/** @class iterator
* @brief range-based for () */
class iterator {
const T * ptr;
public:
iterator(const T * _ptr) : ptr (_ptr) {}
iterator operator++ () { ++ptr; return * this; }
bool operator!= (const iterator & other) const { return ptr != other.ptr; }
const T & operator* () const { return * ptr; }
};
iterator begin () const { return iterator (data ); }
iterator end () const { return iterator (data + N); }
protected:
};
static constexpr double X_PI = 3.14159265358979323846;
static constexpr double D_PI = 2.0 * X_PI;
/* cmath nejde použít, tak si to mírně zjednodušíme, ale musí to fungovat */
static constexpr double dabs (const double a) { return a < 0.0 ? -a : +a; }
static constexpr int i_round (const double a) { return a < 0.0 ? int (a - 0.5) : int (a + 0.5); }
/* tahle divná funkce počítá sinus, pokud even=true i kosinus, pokud even=false */
static constexpr double sincos (const double x, const bool even) {
double result (0.0), element(1.0), divider(0.0);
if (even) { element *= x; divider += 1.0; }
constexpr double eps = 1.0e-9; // maximální chyba výpočtu
const double aa = - (x * x);
for (;;) {
result += element;
if (dabs (element) < eps) break;
divider += 1.0;
double fact = divider;
divider += 1.0;
fact *= divider;
element *= aa / fact;
}
return result;
}
#endif // UTILS_H