10 #if !defined(CNL_CONSTANT_H)
11 #define CNL_CONSTANT_H
15 #include "_impl/num_traits/digits.h"
16 #include "_impl/numbers/signedness.h"
17 #include "_impl/parse.h"
21 #include <type_traits>
24 #if defined(CNL_TEMPLATE_AUTO)
26 #define CNL_IMPL_CONSTANT_VALUE_TYPE auto // NOLINT(cppcoreguidelines-macro-usage)
29 #define CNL_IMPL_CONSTANT_VALUE_TYPE ::cnl::intmax_t // NOLINT(cppcoreguidelines-macro-usage)
43 template<CNL_IMPL_CONSTANT_VALUE_TYPE Value>
45 #if defined(CNL_TEMPLATE_AUTO)
46 using value_type = decltype(Value);
48 using value_type = CNL_IMPL_CONSTANT_VALUE_TYPE;
51 static constexpr value_type value = Value;
56 constexpr
explicit constant(S
const& init)
61 "initial value couldn't possibly represent value");
62 CNL_ASSERT(value == init);
65 #if defined(_MSC_VER) && _MSC_VER < 1924
67 [[nodiscard]] constexpr
operator auto()
const -> value_type
73 [[nodiscard]] constexpr
operator value_type()
const
84 #define CNL_IMPL_CONSTANT_UNARY(OPERATOR) \
85 template<CNL_IMPL_CONSTANT_VALUE_TYPE Value> \
86 [[nodiscard]] constexpr auto operator OPERATOR( \
87 constant<Value>) noexcept->constant<OPERATOR Value> \
89 return constant<OPERATOR Value>{}; \
93 #define CNL_IMPL_CONSTANT_BINARY(OPERATOR) \
94 template<CNL_IMPL_CONSTANT_VALUE_TYPE LhsValue, CNL_IMPL_CONSTANT_VALUE_TYPE RhsValue> \
95 [[nodiscard]] constexpr auto operator OPERATOR( \
97 constant<RhsValue>) noexcept->constant<(LhsValue OPERATOR RhsValue)> \
99 return constant<(LhsValue OPERATOR RhsValue)>{}; \
103 CNL_IMPL_CONSTANT_UNARY(+)
104 CNL_IMPL_CONSTANT_UNARY(-)
105 CNL_IMPL_CONSTANT_BINARY(+)
106 CNL_IMPL_CONSTANT_BINARY(-)
107 CNL_IMPL_CONSTANT_BINARY(*)
108 CNL_IMPL_CONSTANT_BINARY(/)
109 CNL_IMPL_CONSTANT_BINARY(%)
110 CNL_IMPL_CONSTANT_UNARY(~)
111 CNL_IMPL_CONSTANT_BINARY(&)
112 CNL_IMPL_CONSTANT_BINARY(|)
113 CNL_IMPL_CONSTANT_BINARY(^)
114 CNL_IMPL_CONSTANT_BINARY(<<)
115 CNL_IMPL_CONSTANT_BINARY(>>)
118 CNL_IMPL_CONSTANT_UNARY(!)
119 CNL_IMPL_CONSTANT_BINARY(&&)
120 CNL_IMPL_CONSTANT_BINARY(||)
123 CNL_IMPL_CONSTANT_BINARY(==)
124 CNL_IMPL_CONSTANT_BINARY(!=)
125 CNL_IMPL_CONSTANT_BINARY(<)
126 CNL_IMPL_CONSTANT_BINARY(>)
127 CNL_IMPL_CONSTANT_BINARY(<=)
128 CNL_IMPL_CONSTANT_BINARY(>=)
138 template<CNL_IMPL_CONSTANT_VALUE_TYPE Value>
143 inline constexpr
auto is_constant_v = is_constant<T>::value;
152 template<
char... Chars>
153 [[nodiscard]] constexpr
auto operator"" _c()
154 -> constant<_impl::parse<intmax_t, Chars...>()>
164 inline constexpr
int digits_v<constant<Value>> = _impl::used_digits((Value < 0) ? -Value : Value);
170 template<CNL_IMPL_CONSTANT_VALUE_TYPE Value>
171 struct signedness<constant<Value>> : signedness<decltype(Value)> {
178 template<CNL_IMPL_CONSTANT_VALUE_TYPE Value>
179 struct is_integer<constant<Value>> : is_integer<decltype(Value)> {
182 template<CNL_IMPL_CONSTANT_VALUE_TYPE Value>
183 struct is_integer<constant<Value> const> : is_integer<decltype(Value)> {
191 template<CNL_IMPL_CONSTANT_VALUE_TYPE Value>
192 struct numeric_limits<
cnl::constant<Value>>
193 : numeric_limits<typename cnl::constant<Value>::value_type> {
195 using value_type =
typename cnl::constant<Value>::value_type;
198 [[nodiscard]]
static constexpr
auto min()
203 [[nodiscard]]
static constexpr
auto max()
208 [[nodiscard]]
static constexpr
auto lowest()
215 #endif // CNL_CONSTANT_H