18#if __cpp_concepts >= 202002L && __cpp_deleted_function >= 202403L \
19 && __cpp_constexpr_exceptions >= 202411L
24#include <source_location>
32#define vir_lib_val_literal 202601L
43 using std::signed_integral;
44 using std::unsigned_integral;
45 using std::floating_point;
46 using std::source_location;
47 using std::type_identity_t;
48 using std::numeric_limits;
49 using std::u8string_view;
56 template <
typename _Tp>
57 concept __arithmetic = integral<_Tp> || floating_point<_Tp>;
75#if __cpp_impl_reflection >= 202506L
77 decltype(^^int) _M_poison;
80 source_location _M_where;
90 : _M_where{__where} {}
107#if __cpp_impl_reflection >= 202506L
114 {
return "conversion is not value-preserving"; }
121 consteval u8string_view
u8what() const noexcept
122 {
return u8
"conversion is not value-preserving"; }
129 consteval source_location
where() const noexcept {
return _M_where; }
138 struct _ConstBinaryOps
149 template <__arithmetic _Tp>
158 _ConvertTo(
const constinteger& __x)
166 _ConvertTo(
const constreal& __x)
174#define _GLIBCXX_CONVERTTO_OP(constraint, op) \
175 template <constraint _Tp> \
176 friend constexpr _Tp& \
177 operator op##=(_Tp& __a, _ConvertTo<type_identity_t<_Tp>> __b) noexcept \
178 { return __a += __b._M_value; } \
180 template <constraint _Tp> \
181 friend constexpr _Tp \
182 operator op(_Tp __a, _ConvertTo<type_identity_t<_Tp>> __b) noexcept \
183 { return __a op __b._M_value; } \
185 template <constraint _Tp> \
186 friend constexpr _Tp \
187 operator op(_ConvertTo<type_identity_t<_Tp>> __a, _Tp __b) noexcept \
188 { return __a._M_value op __b; }
190 _GLIBCXX_CONVERTTO_OP(__arithmetic, +)
191 _GLIBCXX_CONVERTTO_OP(__arithmetic, -)
192 _GLIBCXX_CONVERTTO_OP(__arithmetic, *)
193 _GLIBCXX_CONVERTTO_OP(__arithmetic, /)
194 _GLIBCXX_CONVERTTO_OP(integral, %)
195 _GLIBCXX_CONVERTTO_OP(integral, &)
196 _GLIBCXX_CONVERTTO_OP(integral, |)
197 _GLIBCXX_CONVERTTO_OP(integral, ^)
199#undef _GLIBCXX_CONVERTTO_OP
204#define _GLIBCXX_CONVERTTO_CMP(op) \
205 template <__arithmetic _Tp> \
206 friend constexpr bool \
207 operator op(_Tp __a, _ConvertTo<type_identity_t<_Tp>> __b) noexcept \
208 { return __a op __b._M_value; } \
210 template <__arithmetic _Tp> \
211 friend constexpr bool \
212 operator op(_ConvertTo<type_identity_t<_Tp>> __a, _Tp __b) noexcept \
213 { return __a._M_value op __b; }
215 _GLIBCXX_CONVERTTO_CMP(==)
216 _GLIBCXX_CONVERTTO_CMP(!=)
217 _GLIBCXX_CONVERTTO_CMP(<=)
218 _GLIBCXX_CONVERTTO_CMP(>=)
219 _GLIBCXX_CONVERTTO_CMP(<)
220 _GLIBCXX_CONVERTTO_CMP(>)
222#undef _GLIBCXX_CONVERTTO_CMP
236 unsigned long long _M_value;
239 bool _M_negative =
false;
249 {
return constinteger{{}, __v._M_value, !__v._M_negative}; }
267 =
delete(
"complement cannot be applied to value of unspecified width");
288 template <__arithmetic _Up>
292 using L = numeric_limits<_Up>;
293 if constexpr (floating_point<_Up>)
295 if (
static_cast<unsigned long long>(
static_cast<_Up
>(_M_value)) != _M_value)
297 _Up r =
static_cast<_Up
>(_M_value);
298 return _M_negative ? -r : r;
302 if ((_M_negative && _M_value > -
static_cast<unsigned long long>(L::lowest()))
303 || (!_M_negative && _M_value > L::max()))
305 return static_cast<_Up
>(_M_negative ? -_M_value : _M_value);
318 consteval constinteger
319 operator""_val(
unsigned long long __x)
noexcept
328 consteval constinteger
329 val(unsigned_integral
auto __x)
noexcept
338 consteval constinteger
339 val(signed_integral
auto __x)
noexcept
342 return constinteger{{},
static_cast<unsigned long long>(__x)};
344 return constinteger{{}, -
static_cast<unsigned long long>(__x),
true};
358 long double _M_value;
398 template <__arithmetic _Up>
402 using L = numeric_limits<_Up>;
403 if (_M_value > L::max() || _M_value < L::lowest())
405 if (
static_cast<long double>(
static_cast<_Up
>(_M_value)) != _M_value)
407 return static_cast<_Up
>(_M_value);
420 operator""_val(
long double __x)
noexcept
430 val(
long double __x)
noexcept
Exception thrown when conversion to arithmetic type would change value.
Definition val.h:73
consteval bad_value_preserving_cast & operator=(const bad_value_preserving_cast &)=default
Defaulted copy assignment.
consteval u8string_view u8what() const noexcept
Get UTF-8 error description.
Definition val.h:121
consteval const char * what() const noexcept override
Get error description.
Definition val.h:113
consteval bad_value_preserving_cast(source_location __where=source_location::current()) noexcept
Construct with source location.
Definition val.h:89
consteval bad_value_preserving_cast & operator=(bad_value_preserving_cast &&)=default
Defaulted move assignment.
consteval bad_value_preserving_cast(bad_value_preserving_cast &&)=default
Defaulted move constructor.
consteval bad_value_preserving_cast(const bad_value_preserving_cast &)=default
Defaulted copy constructor.
consteval source_location where() const noexcept
Get source location of the failed conversion.
Definition val.h:129
consteval constinteger val(unsigned_integral auto __x) noexcept
Create untyped constant from typed value / constant expression.
Definition val.h:329
Untyped integer literal type.
Definition val.h:234
friend consteval constinteger operator-(constinteger __v) noexcept
Unary negation operator.
Definition val.h:248
friend consteval constinteger operator~(constinteger)=delete("complement cannot be applied to value of unspecified width")
Bitwise complement operator (deleted)
friend consteval constinteger operator+(constinteger __v) noexcept
Unary plus operator (identity)
Definition val.h:257
friend consteval constinteger operator!(constinteger)=delete("explicitly write 1 or 0 instead")
Logical NOT operator (deleted)
Untyped real literal type.
Definition val.h:356
friend consteval constreal operator-(constreal __v) noexcept
Unary negation operator.
Definition val.h:367
friend consteval constreal operator+(constreal __v) noexcept
Unary plus operator (identity)
Definition val.h:376
friend consteval constreal operator~(constreal)=delete
Bitwise complement operator (deleted)
friend consteval constreal operator!(constreal)=delete("explicitly write 1 or 0 instead")
Logical NOT operator (deleted)