19#define STRCAT_INNER(a, b) a##b
20#define STRCAT(a, b) STRCAT_INNER(a, b)
23concept NUM = std::integral<X> || std::floating_point<X>;
27 CF
abs(
const CF &cf) {
28 auto i = cf.__get() > 0;
37 template<
typename T,
unsigned char BITS = sizeof(T) * 8,
unsigned char ALIGNMENT = alignof(T)>
requires std::is_floating_point_v<T>
38 class alignas(ALIGNMENT) CompressedFloat {
43 std::uint64_t byte_data;
47 static_assert(
sizeof(
T) * 8 >= BITS);
49 auto dataLocal = this->
data;
51 U.byte_data = dataLocal << (
sizeof(
T) * 8 - BITS);
52 auto float_data = U.float_data;
56 void __set(T float_data) {
58 std::uint64_t byte_data;
62 U.float_data = float_data;
63 this->
data = U.byte_data >> (
sizeof(
T) * 8 - BITS);
67 CompressedFloat() =
default;
69 CompressedFloat(
const CompressedFloat ©) =
default;
71 CompressedFloat(
const T &value) {
75 CompressedFloat &operator=(
const CompressedFloat &other) =
default;
78 CompressedFloat &operator=(
const X &value) {
79 this->__set((T) value);
83#define UNARY_PREFIX_OP(op) \
84 CompressedFloat &operator op() { \
85 auto f = this->__get(); \
94#define UNARY_POSTFIX_OP(op) \
95 const CompressedFloat operator op(std::int32_t) { \
96 auto oldThis = CompressedFloat(*this); \
97 this->operator op(); \
104 T operator -()
const {
105 return -this->__get();
108#undef UNARY_POSTFIX_OP
110#define ARITHMETIC_OP(op) \
112 CompressedFloat &operator STRCAT(op, =) (const X &scalar) { \
113 this->__set(this->__get() op scalar); \
118 T operator op (const X &scalar) const { \
119 return this->__get() op scalar; \
123 friend X& operator STRCAT(op, =) (X &scalar, const CompressedFloat cf) { \
124 scalar STRCAT(op, =) cf.__get(); \
129 friend X operator op (const X &scalar, const CompressedFloat cf) { \
130 return scalar op cf.__get(); \
140#define SELF_ARITHMETIC_OP(op) \
141 CompressedFloat &operator STRCAT(op, =) (const CompressedFloat &scalar) { \
142 this->__set(this->__get() op scalar.__get()); \
146 T operator op (const CompressedFloat &scalar) const { \
147 return this->__get() op scalar; \
150 SELF_ARITHMETIC_OP(+)
151 SELF_ARITHMETIC_OP(-)
152 SELF_ARITHMETIC_OP(*)
153 SELF_ARITHMETIC_OP(/)
155#undef SELF_ARITHMETIC_OP
157 bool operator !()
const {
161#define COMPARISON_OP(op) \
163 bool operator op (const X &scalar) const { \
164 return this->__get() op scalar; \
168 friend bool operator op (const X &scalar, const CompressedFloat &cf) { \
169 return scalar op cf.__get(); \
181#define SELF_COMPARISON_OP(op) \
182 bool operator op (const CompressedFloat &cf) const { \
183 return this->__get() op cf.__get(); \
186 SELF_COMPARISON_OP(<)
187 SELF_COMPARISON_OP(<=)
188 SELF_COMPARISON_OP(==)
189 SELF_COMPARISON_OP(!=)
190 SELF_COMPARISON_OP(>=)
191 SELF_COMPARISON_OP(>)
193#undef SELF_COMPARISON_OP
197 return (X) this->__get();
200 friend CompressedFloat std::abs(
const CompressedFloat &cf);
__attribute__((always_inline, const)) inline static double pow_gamma(double x)
Returns the argument to the power given by the adiabatic index.
double abs(double value)
Returns the absolute value of a type by redirecting to std::abs.
Have to include this header, as I need access to the SYCL_EXTERNAL keyword.