Есть ли какая-либо возможность явно вызвать оператор встроенного литерала?
Например, хочется определить свой литерал для binary128 ISO/IEC 60559 (в GCC 14 появилась частичная поддержка для всех платформ, а не только для AArch64/POWER/SPARC).
Пробую сделать так:
#define __STDC_WANT_IEC_60559_EXT__ (1)
#include <cassert>
#include <cfloat>
#include <ranges>
#if __has_include(<stdfloat>)
#include <stdfloat>
#endif
#define MY128_LIT (1)
#if 113 == LDBL_MANT_DIG
using my128_t = long double;
#define MY128_T(x) x##L
my128_t operator ""_my128(long double x) {
return x;
}
#elif defined(__STDCPP_FLOAT128_T__)
using my128_t = std::float128_t;
#define MY128_T(x) x##f128
#if 0
my128_t operator ""_my128(const char* s) {
return (operator ""f128)(s);
// error: 'operator""f128' was not declared in this scope
}
#endif
#ifdef MY128_LIT
my128_t operator ""_my128(std::float128_t x) {
// error: 'my128_t operator""_my128(std::float128_t)' has invalid argument list
return x;
}
#endif
#else
#error "Нет binary128 (ни long double, ни float128_t)"
#endif
#ifdef MY128_LIT
my128_t tc2[] = {
0x7fffffffffffffff.8p0_my128,
0x8000000000000000.0p0_my128,
0x8000000000000000.8p0_my128,
};
#endif
my128_t tc1[] = {
MY128_T(0x7fffffffffffffff.8p0),
MY128_T(0x8000000000000000.0p0),
MY128_T(0x8000000000000000.8p0),
};
int main() {
assert(tc1[0] < tc1[1]);
assert(tc1[1] < tc1[2]);
#ifdef MY128_LIT
for (const auto [t1, t2] : std::views::zip(tc1, tc2)) {
assert(t1 == t2);
}
#endif
return 0;
}
На AArch64, где у GCC 113 == LDBL_MANT_DIG, естественно, работает. Но на i386/x86-64, увы, нет.