13#if !defined(ULTRA_INT_PRIMITIVE_H)
14#define ULTRA_INT_PRIMITIVE_H
38[[nodiscard]]
inline bool int_value_index(
const function *f,
43 for (std::size_t i(0); i < f->
arity(); ++i)
44 if (pars[i].index() != d_int)
60 return std::get<D_INT>(v);
69 explicit number(D_INT m = -128, D_INT s = 128,
71 :
terminal(
"INT", c), min_(m), sup_(s)
76 [[nodiscard]] D_INT min()
const noexcept {
return min_; }
77 [[nodiscard]] D_INT sup()
const noexcept {
return sup_; }
83 const D_INT min_, sup_;
90 :
terminal(std::to_string(v), c), val_(v)
114 Expects(internal::int_value_index(
this, pars));
116 const auto v0(
base(pars[0]));
117 const auto v1(
base(pars[1]));
119 if (v0 > 0 && v1 > 0 && (v0 > std::numeric_limits<D_INT>::max() - v1))
120 return std::numeric_limits<D_INT>::max();
121 if (v0 < 0 && v1 < 0 && (v0 < std::numeric_limits<D_INT>::min() - v1))
122 return std::numeric_limits<D_INT>::min();
137 Expects(pt.size() == 2);
147 Expects(internal::int_value_index(
this, pars));
149 const auto v0(
base(pars[0]));
150 const auto v1(
base(pars[1]));
152 if (v1 == 0 || (v0 == std::numeric_limits<D_INT>::min() && (v1 == -1)))
169 Expects(pt.size() == 4);
171 Expects(pt[0] == pt[1]);
172 Expects(pt[2] == pt[3]);
180 return "({2} if {0}=={1} else {3})";
182 return "({0}=={1} ? {2} : {3})";
188 Expects(internal::int_value_index(
this, pars));
190 const auto v0(
base(pars[0]));
191 const auto v1(
base(pars[1]));
193 return v0 == v1 ? pars[2] : pars[3];
207 Expects(pt.size() == 4);
209 Expects(pt[0] == pt[1]);
210 Expects(pt[2] == pt[3]);
217 case python_format:
return "({2} if {0}<{1} else {3})";
218 default:
return "({0}<{1} ? {2} : {3})";
224 Expects(internal::int_value_index(
this, pars));
226 const auto v0(
base(pars[0]));
227 const auto v1(
base(pars[1]));
229 return v0 < v1 ? pars[2] : pars[3];
242 Expects(pt.size() == 3);
244 Expects(pt[1] == pt[2]);
252 return "({1} if {0} == 0 else {2})";
254 return "({0} == 0 ? {1} : {2})";
260 Expects(internal::int_value_index(
this, pars));
262 return base(pars[0]) == 0 ? pars[1] : pars[2];
275 Expects(pt.size() == 2);
276 Expects(pt[0] == pt[1]);
286 Expects(internal::int_value_index(
this, pars));
288 const auto v0(
base(pars[0]));
289 const auto v1(
base(pars[1]));
291 if (v1 == 0 || (v0 == std::numeric_limits<D_INT>::min() && (v1 == -1)))
307 Expects(pt.size() == 2);
317 Expects(internal::int_value_index(
this, pars));
319 if constexpr (
sizeof(std::intmax_t) >= 2 *
sizeof(D_INT))
321 static_assert(
sizeof(std::intmax_t) >= 2 *
sizeof(D_INT),
322 "Unable to detect overflow after multiplication");
324 const std::intmax_t v0(
base(pars[0]));
325 const std::intmax_t v1(
base(pars[1]));
327 const auto tmp(v0 * v1);
328 if (tmp > std::numeric_limits<D_INT>::max())
329 return std::numeric_limits<D_INT>::max();
330 if (tmp < std::numeric_limits<D_INT>::min())
331 return std::numeric_limits<D_INT>::min();
333 return static_cast<D_INT
>(tmp);
337 const auto v0(
base(pars[0]));
338 const auto v1(
base(pars[1]));
346 assert(v0 > 0 && v1 > 0);
347 if (v0 > std::numeric_limits<D_INT>::max() / v1)
348 return std::numeric_limits<D_INT>::max();
352 assert(v0 > 0 && v1 <= 0);
353 if (v1 < std::numeric_limits<D_INT>::min() / v0)
354 return std::numeric_limits<D_INT>::min();
359 assert(v0 <= 0 && v1 > 0);
360 if (v0 < std::numeric_limits<D_INT>::min() / v1)
361 return std::numeric_limits<D_INT>::min();
365 assert(v0 <= 0 && v1 <= 0);
366 if (v0 != 0 && v1 < std::numeric_limits<D_INT>::max() / v0)
367 return std::numeric_limits<D_INT>::max();
384 return "({0} << {1})";
389 Expects(internal::int_value_index(
this, pars));
391 const auto v0(
base(pars[0]));
392 const auto v1(
base(pars[1]));
395 || v1 >=
static_cast<D_INT
>(
sizeof(D_INT) * CHAR_BIT)
396 || v0 > std::numeric_limits<D_INT>::max() >> v1)
417 Expects(internal::int_value_index(
this, pars));
419 const auto v0(
base(pars[0]));
420 const auto v1(
base(pars[1]));
422 if (v0 < 0 && v1 > 0 && (v0 < std::numeric_limits<D_INT>::min() + v1))
423 return std::numeric_limits<D_INT>::min();
424 if (v0 > 0 && v1 < 0 && (v0 > std::numeric_limits<D_INT>::max() + v1))
425 return std::numeric_limits<D_INT>::max();
Definition function.h:108
std::vector< category_t > param_data_types
Definition function.h:49
function(const std::string &, return_type, param_data_types)
Definition function.cc:27
category_t return_type
Type used to describe the return category of the function.
Definition function.h:52
std::size_t arity() const noexcept
Definition function.cc:55
value_t eval(const params &pars) const final
Definition integer.h:112
std::string to_string(format) const final
Definition integer.h:107
value_t eval(const params &pars) const final
Definition integer.h:145
std::string to_string(format) const final
Definition integer.h:140
value_t eval(const params &pars) const final
Definition integer.h:186
std::string to_string(format f) const final
Definition integer.h:175
std::string to_string(format f) const final
Definition integer.h:213
value_t eval(const params &pars) const final
Definition integer.h:222
std::string to_string(format f) const final
Definition integer.h:247
value_t eval(const params &pars) const final
Definition integer.h:258
value_t instance() const noexcept final
Definition integer.h:94
value_t eval(const params &pars) const final
Definition integer.h:284
std::string to_string(format) const final
Definition integer.h:279
std::string to_string(format) const final
Definition integer.h:310
value_t eval(const params &pars) const final
Definition integer.h:315
value_t instance() const final
Definition integer.h:79
value_t eval(const params &pars) const final
Definition integer.h:387
std::string to_string(format) const final
Definition integer.h:382
value_t eval(const params &pars) const final
Definition integer.h:415
std::string to_string(format) const final
Definition integer.h:410
format
Supported rendering formats for symbol stringification.
Definition symbol.h:72
unsigned category_t
Definition symbol.h:55
static constexpr category_t default_category
Default category assigned when typing is not used.
Definition symbol.h:58
D_INT base(const value_t &v)
Definition integer.h:58
std::variant< D_VOID, D_INT, D_DOUBLE, D_STRING, const D_NULLARY *, D_ADDRESS, const D_VARIABLE *, D_IVECTOR > value_t
Definition value.h:54
T between(T min, T sup)
Definition random.h:57