BioCMAMC-ST
traits.hpp
1#ifndef __COMMON_TRAITS_HPP__
2#define __COMMON_TRAITS_HPP__
3#include <cmath>
4#include <type_traits>
5
6#if defined __GNUC__
7# define LIKELY(EXPR) __builtin_expect(!!(EXPR), 1)
8#else
9# define LIKELY(EXPR) (!!(EXPR))
10#endif
11
12#if defined NDEBUG
13# define X_ASSERT(CHECK) void(0)
14#else
15# define X_ASSERT(CHECK) \
16 (LIKELY(CHECK) ? void(0) : [] { assert(!(#CHECK)); }())
17#endif
18
19template <typename T>
20concept FloatingPointType = std::is_floating_point_v<std::remove_cvref_t<T>>;
21
22static_assert(FloatingPointType<double>, "double ok");
23static_assert(FloatingPointType<float>, "float ok");
24static_assert(!FloatingPointType<int>, "int ok");
25
26constexpr double tolerance_equality_float = 1e-15;
27
28template <typename T>
29concept IntegerType = requires(T n) {
30 requires std::is_integral_v<std::remove_cvref_t<T>>;
31 requires !std::is_same_v<std::remove_cvref_t<T>, bool>;
32 requires std::is_arithmetic_v<decltype(n + 1)>;
33 requires !std::is_pointer_v<std::remove_cvref_t<T>>;
34};
35
36template <typename T>
38
39// General case: by value
40template <NumberType T>
41inline bool almost_equal(T val, T val2, T tolerance = tolerance_equality_float)
42{
43 using CommonT = std::common_type_t<T, T>;
44 return std::abs(static_cast<CommonT>(val) - static_cast<CommonT>(val2)) <
45 static_cast<CommonT>(tolerance);
46}
47
48// Overload for references
49template <NumberType T>
50inline bool almost_equal(const T& val,
51 const T& val2,
52 T tolerance = tolerance_equality_float)
53{
54 using CommonT = std::common_type_t<T, T>;
55 return std::abs(static_cast<CommonT>(val) - static_cast<CommonT>(val2)) <
56 static_cast<CommonT>(tolerance);
57}
58
59// Overload for pointers
60template <NumberType T>
61inline bool almost_equal(const T* val,
62 const T* val2,
63 T tolerance = tolerance_equality_float)
64{
65 if (!val || !val2)
66 {
67 return false; // Null pointer check
68 }
69 using CommonT = std::common_type_t<T, T>;
70 return std::abs(static_cast<CommonT>(*val) - static_cast<CommonT>(*val2)) <
71 static_cast<CommonT>(tolerance);
72}
73
74// Overload for rvalue references
75template <NumberType T>
76inline bool
77almost_equal(T&& val, T&& val2, T tolerance = tolerance_equality_float)
78{
79 using CommonT = std::common_type_t<T, T>;
80 return std::abs(static_cast<CommonT>(val) - static_cast<CommonT>(val2)) <
81 static_cast<CommonT>(tolerance);
82}
83
84#endif
Definition traits.hpp:20
Definition traits.hpp:29
Definition traits.hpp:37