GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
boxed_number.hpp
Go to the documentation of this file.
1// This file is distributed under the BSD License.
2// See "license.txt" for details.
3// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
4// Copyright 2009-2017, Jason Turner (jason@emptycrate.com)
5// http://www.chaiscript.com
6
7// This is an open source non-commercial project. Dear PVS-Studio, please check it.
8// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
9
10#ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_
11#define CHAISCRIPT_BOXED_NUMERIC_HPP_
12
13#include <cstdint>
14#include <sstream>
15#include <string>
16
18#include "any.hpp"
19#include "boxed_cast.hpp"
20#include "boxed_cast_helper.hpp"
21#include "boxed_value.hpp"
22#include "type_info.hpp"
23
24namespace chaiscript {
26} // namespace chaiscript
27
28namespace chaiscript
29{
30 namespace exception
31 {
32 struct arithmetic_error : std::runtime_error
33 {
34 explicit arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {}
36 ~arithmetic_error() noexcept override = default;
37 };
38 }
39}
40
41namespace chaiscript
42{
43
44// Due to the nature of generating every possible arithmetic operation, there
45// are going to be warnings generated on every platform regarding size and sign,
46// this is OK, so we're disabling size/and sign type warnings
47#ifdef CHAISCRIPT_MSVC
48#pragma warning(push)
49#pragma warning(disable : 4244 4018 4389 4146 4365 4267 4242)
50#endif
51
52
53#ifdef __GNUC__
54#pragma GCC diagnostic push
55#pragma GCC diagnostic ignored "-Wunknown-pragmas"
56#pragma GCC diagnostic ignored "-Wpragmas"
57#pragma GCC diagnostic ignored "-Wsign-compare"
58#pragma GCC diagnostic ignored "-Wfloat-equal"
59#pragma GCC diagnostic ignored "-Wconversion"
60#pragma GCC diagnostic ignored "-Wsign-conversion"
61#pragma GCC diagnostic ignored "-Wfloat-conversion"
62#endif
63
66 {
67 private:
68 enum class Common_Types {
69 t_int32,
70 t_double,
71 t_uint8,
72 t_int8,
73 t_uint16,
74 t_int16,
75 t_uint32,
76 t_uint64,
77 t_int64,
78 t_float,
79 t_long_double
80 };
81
82 template<typename T>
83 static inline void check_divide_by_zero(T t, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr)
84 {
85#ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO
86 if (t == 0) {
87 throw chaiscript::exception::arithmetic_error("divide by zero");
88 }
89#endif
90 }
91
92 template<typename T>
93 static inline void check_divide_by_zero(T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr)
94 {
95 }
96
97 static constexpr Common_Types get_common_type(size_t t_size, bool t_signed)
98 {
99 return (t_size == 1 && t_signed)?(Common_Types::t_int8)
100 :(t_size == 1)?(Common_Types::t_uint8)
101 :(t_size == 2 && t_signed)?(Common_Types::t_int16)
102 :(t_size == 2)?(Common_Types::t_uint16)
103 :(t_size == 4 && t_signed)?(Common_Types::t_int32)
104 :(t_size == 4)?(Common_Types::t_uint32)
105 :(t_size == 8 && t_signed)?(Common_Types::t_int64)
106 :(Common_Types::t_uint64);
107 }
108
109
110 static Common_Types get_common_type(const Boxed_Value &t_bv)
111 {
112 const Type_Info &inp_ = t_bv.get_type_info();
113
114 if (inp_ == typeid(int)) {
115 return get_common_type(sizeof(int), true);
116 } else if (inp_ == typeid(double)) {
117 return Common_Types::t_double;
118 } else if (inp_ == typeid(long double)) {
119 return Common_Types::t_long_double;
120 } else if (inp_ == typeid(float)) {
121 return Common_Types::t_float;
122 } else if (inp_ == typeid(char)) {
123 return get_common_type(sizeof(char), std::is_signed<char>::value);
124 } else if (inp_ == typeid(unsigned char)) {
125 return get_common_type(sizeof(unsigned char), false);
126 } else if (inp_ == typeid(unsigned int)) {
127 return get_common_type(sizeof(unsigned int), false);
128 } else if (inp_ == typeid(long)) {
129 return get_common_type(sizeof(long), true);
130 } else if (inp_ == typeid(long long)) {
131 return get_common_type(sizeof(long long), true);
132 } else if (inp_ == typeid(unsigned long)) {
133 return get_common_type(sizeof(unsigned long), false);
134 } else if (inp_ == typeid(unsigned long long)) {
135 return get_common_type(sizeof(unsigned long long), false);
136 } else if (inp_ == typeid(std::int8_t)) {
137 return Common_Types::t_int8;
138 } else if (inp_ == typeid(std::int16_t)) {
139 return Common_Types::t_int16;
140 } else if (inp_ == typeid(std::int32_t)) {
141 return Common_Types::t_int32;
142 } else if (inp_ == typeid(std::int64_t)) {
143 return Common_Types::t_int64;
144 } else if (inp_ == typeid(std::uint8_t)) {
145 return Common_Types::t_uint8;
146 } else if (inp_ == typeid(std::uint16_t)) {
147 return Common_Types::t_uint16;
148 } else if (inp_ == typeid(std::uint32_t)) {
149 return Common_Types::t_uint32;
150 } else if (inp_ == typeid(std::uint64_t)) {
151 return Common_Types::t_uint64;
152 } else if (inp_ == typeid(wchar_t)) {
153 return get_common_type(sizeof(wchar_t), std::is_signed<wchar_t>::value);
154 } else if (inp_ == typeid(char16_t)) {
155 return get_common_type(sizeof(char16_t), std::is_signed<char16_t>::value);
156 } else if (inp_ == typeid(char32_t)) {
157 return get_common_type(sizeof(char32_t), std::is_signed<char32_t>::value);
158 } else {
160 }
161 }
162
163 template<typename T>
164 static Boxed_Value boolean_go(Operators::Opers t_oper, const T &t, const T &u)
165 {
166 switch (t_oper)
167 {
169 return const_var(t == u);
171 return const_var(t < u);
173 return const_var(t > u);
175 return const_var(t <= u);
177 return const_var(t >= u);
179 return const_var(t != u);
180 default:
182 }
183 }
184
185 template<typename T>
186 static Boxed_Value unary_go(Operators::Opers t_oper, T &t, const Boxed_Value &t_lhs)
187 {
188 switch (t_oper)
189 {
191 ++t;
192 break;
194 --t;
195 break;
196 default:
198 }
199
200 return t_lhs;
201 }
202
203 template<typename T, typename U>
204 static Boxed_Value binary_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs)
205 {
206 switch (t_oper)
207 {
209 t = u;
210 break;
212 t *= u;
213 break;
215 t += u;
216 break;
218 check_divide_by_zero(u);
219 t /= u;
220 break;
222 t -= u;
223 break;
224 default:
226 }
227
228 return t_lhs;
229 }
230
231 template<typename T, typename U>
232 static Boxed_Value binary_int_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs)
233 {
234 switch (t_oper)
235 {
237 t &= u;
238 break;
240 t |= u;
241 break;
243 t <<= u;
244 break;
246 t >>= u;
247 break;
249 check_divide_by_zero(u);
250 t %= u;
251 break;
253 t ^= u;
254 break;
255 default:
257 }
258 return t_lhs;
259 }
260
261 template<typename T>
262 static Boxed_Value const_unary_int_go(Operators::Opers t_oper, const T &t)
263 {
264 switch (t_oper)
265 {
267 return const_var(~t);
268 default:
270 }
271 }
272
273 template<typename T>
274 static Boxed_Value const_binary_int_go(Operators::Opers t_oper, const T &t, const T &u)
275 {
276 switch (t_oper)
277 {
279 return const_var(t << u);
281 return const_var(t >> u);
283 check_divide_by_zero(u);
284 return const_var(t % u);
286 return const_var(t & u);
288 return const_var(t | u);
290 return const_var(t ^ u);
291 default:
293 }
294 }
295
296 template<typename T>
297 static Boxed_Value const_unary_go(Operators::Opers t_oper, const T &t)
298 {
299 switch (t_oper)
300 {
302 return const_var(-t);
304 return const_var(+t);
305 default:
307 }
308 }
309
310 template<typename T>
311 static Boxed_Value const_binary_go(Operators::Opers t_oper, const T &t, const T &u)
312 {
313 switch (t_oper)
314 {
316 return const_var(t + u);
318 check_divide_by_zero(u);
319 return const_var(t / u);
321 return const_var(t * u);
323 return const_var(t - u);
324 default:
326 }
327 }
328
329 template<typename LHS, typename RHS>
330 static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
331 -> typename std::enable_if<!std::is_floating_point<LHS>::value && !std::is_floating_point<RHS>::value, Boxed_Value>::type
332 {
333 typedef typename std::common_type<LHS, RHS>::type common_type;
335 {
336 return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
337 } else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
338 return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
339 } else if (t_oper > Operators::Opers::non_const_int_flag && t_oper < Operators::Opers::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
340 return binary_int_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
341 } else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) {
342 return const_binary_int_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
343 } else if (t_oper > Operators::Opers::const_flag) {
344 return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
345 } else {
347 }
348 }
349
350 template<typename LHS, typename RHS>
351 static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
352 -> typename std::enable_if<std::is_floating_point<LHS>::value || std::is_floating_point<RHS>::value, Boxed_Value>::type
353 {
354 typedef typename std::common_type<LHS, RHS>::type common_type;
356 {
357 return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
358 } else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
359 return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
360 } else if (t_oper > Operators::Opers::const_flag) {
361 return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
362 } else {
364 }
365 }
366
367 // Unary
368 template<typename LHS>
369 static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
370 -> typename std::enable_if<!std::is_floating_point<LHS>::value, Boxed_Value>::type
371 {
373 return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs);
374 } else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) {
375 return const_unary_int_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
376 } else if (t_oper > Operators::Opers::const_flag) {
377 return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
378 } else {
380 }
381 }
382
383 template<typename LHS>
384 static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
385 -> typename std::enable_if<std::is_floating_point<LHS>::value, Boxed_Value>::type
386 {
388 return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs);
389 } else if (t_oper > Operators::Opers::const_flag) {
390 return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
391 } else {
393 }
394 }
395
396 template<typename LHS>
397 inline static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
398 {
399 switch (get_common_type(t_rhs)) {
400 case Common_Types::t_int32:
401 return go<LHS, int32_t>(t_oper, t_lhs, t_rhs);
402 case Common_Types::t_uint8:
403 return go<LHS, uint8_t>(t_oper, t_lhs, t_rhs);
404 case Common_Types::t_int8:
405 return go<LHS, int8_t>(t_oper, t_lhs, t_rhs);
406 case Common_Types::t_uint16:
407 return go<LHS, uint16_t>(t_oper, t_lhs, t_rhs);
408 case Common_Types::t_int16:
409 return go<LHS, int16_t>(t_oper, t_lhs, t_rhs);
410 case Common_Types::t_uint32:
411 return go<LHS, uint32_t>(t_oper, t_lhs, t_rhs);
412 case Common_Types::t_uint64:
413 return go<LHS, uint64_t>(t_oper, t_lhs, t_rhs);
414 case Common_Types::t_int64:
415 return go<LHS, int64_t>(t_oper, t_lhs, t_rhs);
416 case Common_Types::t_double:
417 return go<LHS, double>(t_oper, t_lhs, t_rhs);
418 case Common_Types::t_float:
419 return go<LHS, float>(t_oper, t_lhs, t_rhs);
420 case Common_Types::t_long_double:
421 return go<LHS, long double>(t_oper, t_lhs, t_rhs);
422 }
423
425 }
426
427 inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs)
428 {
429 switch (get_common_type(t_lhs)) {
430 case Common_Types::t_int32:
431 return go<int32_t>(t_oper, t_lhs);
432 case Common_Types::t_uint8:
433 return go<uint8_t>(t_oper, t_lhs);
434 case Common_Types::t_int8:
435 return go<int8_t>(t_oper, t_lhs);
436 case Common_Types::t_uint16:
437 return go<uint16_t>(t_oper, t_lhs);
438 case Common_Types::t_int16:
439 return go<int16_t>(t_oper, t_lhs);
440 case Common_Types::t_uint32:
441 return go<uint32_t>(t_oper, t_lhs);
442 case Common_Types::t_uint64:
443 return go<uint64_t>(t_oper, t_lhs);
444 case Common_Types::t_int64:
445 return go<int64_t>(t_oper, t_lhs);
446 case Common_Types::t_double:
447 return go<double>(t_oper, t_lhs);
448 case Common_Types::t_float:
449 return go<float>(t_oper, t_lhs);
450 case Common_Types::t_long_double:
451 return go<long double>(t_oper, t_lhs);
452 }
453
455 }
456
457
458 inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
459 {
460 switch (get_common_type(t_lhs)) {
461 case Common_Types::t_int32:
462 return oper_rhs<int32_t>(t_oper, t_lhs, t_rhs);
463 case Common_Types::t_uint8:
464 return oper_rhs<uint8_t>(t_oper, t_lhs, t_rhs);
465 case Common_Types::t_int8:
466 return oper_rhs<int8_t>(t_oper, t_lhs, t_rhs);
467 case Common_Types::t_uint16:
468 return oper_rhs<uint16_t>(t_oper, t_lhs, t_rhs);
469 case Common_Types::t_int16:
470 return oper_rhs<int16_t>(t_oper, t_lhs, t_rhs);
471 case Common_Types::t_uint32:
472 return oper_rhs<uint32_t>(t_oper, t_lhs, t_rhs);
473 case Common_Types::t_uint64:
474 return oper_rhs<uint64_t>(t_oper, t_lhs, t_rhs);
475 case Common_Types::t_int64:
476 return oper_rhs<int64_t>(t_oper, t_lhs, t_rhs);
477 case Common_Types::t_double:
478 return oper_rhs<double>(t_oper, t_lhs, t_rhs);
479 case Common_Types::t_float:
480 return oper_rhs<float>(t_oper, t_lhs, t_rhs);
481 case Common_Types::t_long_double:
482 return oper_rhs<long double>(t_oper, t_lhs, t_rhs);
483 }
484
486 }
487
488 template<typename Target, typename Source>
489 static inline Target get_as_aux(const Boxed_Value &t_bv)
490 {
491 return static_cast<Target>(*static_cast<const Source *>(t_bv.get_const_ptr()));
492 }
493
494 template<typename Source>
495 static std::string to_string_aux(const Boxed_Value &v)
496 {
497 std::ostringstream oss;
498 oss << *static_cast<const Source *>(v.get_const_ptr());
499 return oss.str();
500 }
501
502 public:
504 : bv(Boxed_Value(0))
505 {
506 }
507
509 : bv(std::move(v))
510 {
512 }
513
514 Boxed_Number(const Boxed_Number &) = default;
517
518 template<typename T> explicit Boxed_Number(T t)
519 : bv(Boxed_Value(t))
520 {
522 }
523
524 static Boxed_Value clone(const Boxed_Value &t_bv) {
525 return Boxed_Number(t_bv).get_as(t_bv.get_type_info()).bv;
526 }
527
528 static bool is_floating_point(const Boxed_Value &t_bv)
529 {
530 const Type_Info &inp_ = t_bv.get_type_info();
531
532 if (inp_ == typeid(double)) {
533 return true;
534 } else if (inp_ == typeid(long double)) {
535 return true;
536 } else if (inp_ == typeid(float)) {
537 return true;
538 } else {
539 return false;
540 }
541 }
542
543 Boxed_Number get_as(const Type_Info &inp_) const
544 {
545 if (inp_.bare_equal_type_info(typeid(int))) {
546 return Boxed_Number(get_as<int>());
547 } else if (inp_.bare_equal_type_info(typeid(double))) {
549 } else if (inp_.bare_equal_type_info(typeid(float))) {
550 return Boxed_Number(get_as<float>());
551 } else if (inp_.bare_equal_type_info(typeid(long double))) {
553 } else if (inp_.bare_equal_type_info(typeid(char))) {
554 return Boxed_Number(get_as<char>());
555 } else if (inp_.bare_equal_type_info(typeid(unsigned char))) {
557 } else if (inp_.bare_equal_type_info(typeid(wchar_t))) {
559 } else if (inp_.bare_equal_type_info(typeid(char16_t))) {
561 } else if (inp_.bare_equal_type_info(typeid(char32_t))) {
563 } else if (inp_.bare_equal_type_info(typeid(unsigned int))) {
565 } else if (inp_.bare_equal_type_info(typeid(long))) {
566 return Boxed_Number(get_as<long>());
567 } else if (inp_.bare_equal_type_info(typeid(long long))) {
569 } else if (inp_.bare_equal_type_info(typeid(unsigned long))) {
571 } else if (inp_.bare_equal_type_info(typeid(unsigned long long))) {
573 } else if (inp_.bare_equal_type_info(typeid(int8_t))) {
575 } else if (inp_.bare_equal_type_info(typeid(int16_t))) {
577 } else if (inp_.bare_equal_type_info(typeid(int32_t))) {
579 } else if (inp_.bare_equal_type_info(typeid(int64_t))) {
581 } else if (inp_.bare_equal_type_info(typeid(uint8_t))) {
583 } else if (inp_.bare_equal_type_info(typeid(uint16_t))) {
585 } else if (inp_.bare_equal_type_info(typeid(uint32_t))) {
587 } else if (inp_.bare_equal_type_info(typeid(uint64_t))) {
589 } else {
591 }
592
593 }
594
595 template<typename Source, typename Target>
596 static void check_type()
597 {
598#ifdef CHAISCRIPT_MSVC
599// MSVC complains about this being redundant / tautologica l
600#pragma warning(push)
601#pragma warning(disable : 4127 6287)
602#endif
603 if (sizeof(Source) != sizeof(Target)
604 || std::is_signed<Source>() != std::is_signed<Target>()
605 || std::is_floating_point<Source>() != std::is_floating_point<Target>())
606 {
608 }
609#ifdef CHAISCRIPT_MSVC
610#pragma warning(pop)
611#endif
612 }
613
614 template<typename Target> Target get_as_checked() const
615 {
616 switch (get_common_type(bv)) {
617 case Common_Types::t_int32:
619 return get_as_aux<Target, int32_t>(bv);
620 case Common_Types::t_uint8:
622 return get_as_aux<Target, uint8_t>(bv);
623 case Common_Types::t_int8:
625 return get_as_aux<Target, int8_t>(bv);
626 case Common_Types::t_uint16:
628 return get_as_aux<Target, uint16_t>(bv);
629 case Common_Types::t_int16:
631 return get_as_aux<Target, int16_t>(bv);
632 case Common_Types::t_uint32:
634 return get_as_aux<Target, uint32_t>(bv);
635 case Common_Types::t_uint64:
637 return get_as_aux<Target, uint64_t>(bv);
638 case Common_Types::t_int64:
640 return get_as_aux<Target, int64_t>(bv);
641 case Common_Types::t_double:
643 return get_as_aux<Target, double>(bv);
644 case Common_Types::t_float:
646 return get_as_aux<Target, float>(bv);
647 case Common_Types::t_long_double:
649 return get_as_aux<Target, long double>(bv);
650 }
651
653 }
654
655
656 template<typename Target> Target get_as() const
657 {
658 switch (get_common_type(bv)) {
659 case Common_Types::t_int32:
660 return get_as_aux<Target, int32_t>(bv);
661 case Common_Types::t_uint8:
662 return get_as_aux<Target, uint8_t>(bv);
663 case Common_Types::t_int8:
664 return get_as_aux<Target, int8_t>(bv);
665 case Common_Types::t_uint16:
666 return get_as_aux<Target, uint16_t>(bv);
667 case Common_Types::t_int16:
668 return get_as_aux<Target, int16_t>(bv);
669 case Common_Types::t_uint32:
670 return get_as_aux<Target, uint32_t>(bv);
671 case Common_Types::t_uint64:
672 return get_as_aux<Target, uint64_t>(bv);
673 case Common_Types::t_int64:
674 return get_as_aux<Target, int64_t>(bv);
675 case Common_Types::t_double:
676 return get_as_aux<Target, double>(bv);
677 case Common_Types::t_float:
678 return get_as_aux<Target, float>(bv);
679 case Common_Types::t_long_double:
680 return get_as_aux<Target, long double>(bv);
681 }
682
684 }
685
686 std::string to_string() const
687 {
688 switch (get_common_type(bv)) {
689 case Common_Types::t_int32:
690 return std::to_string(get_as<int32_t>());
691 case Common_Types::t_uint8:
692 return std::to_string(get_as<uint32_t>());
693 case Common_Types::t_int8:
694 return std::to_string(get_as<int32_t>());
695 case Common_Types::t_uint16:
696 return std::to_string(get_as<uint16_t>());
697 case Common_Types::t_int16:
698 return std::to_string(get_as<int16_t>());
699 case Common_Types::t_uint32:
700 return std::to_string(get_as<uint32_t>());
701 case Common_Types::t_uint64:
702 return std::to_string(get_as<uint64_t>());
703 case Common_Types::t_int64:
704 return std::to_string(get_as<int64_t>());
705 case Common_Types::t_double:
706 return to_string_aux<double>(bv);
707 case Common_Types::t_float:
708 return to_string_aux<float>(bv);
709 case Common_Types::t_long_double:
710 return to_string_aux<long double>(bv);
711 }
712
714 }
715
716 static void validate_boxed_number(const Boxed_Value &v)
717 {
718 const Type_Info &inp_ = v.get_type_info();
719 if (inp_ == typeid(bool))
720 {
722 }
723
724 if (!inp_.is_arithmetic())
725 {
727 }
728 }
729
730
731
732 static bool equals(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
733 {
734 return boxed_cast<bool>(oper(Operators::Opers::equals, t_lhs.bv, t_rhs.bv));
735 }
736
737 static bool less_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
738 {
739 return boxed_cast<bool>(oper(Operators::Opers::less_than, t_lhs.bv, t_rhs.bv));
740 }
741
742 static bool greater_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
743 {
744 return boxed_cast<bool>(oper(Operators::Opers::greater_than, t_lhs.bv, t_rhs.bv));
745 }
746
747 static bool greater_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
748 {
750 }
751
752 static bool less_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
753 {
754 return boxed_cast<bool>(oper(Operators::Opers::less_than_equal, t_lhs.bv, t_rhs.bv));
755 }
756
757 static bool not_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
758 {
759 return boxed_cast<bool>(oper(Operators::Opers::not_equal, t_lhs.bv, t_rhs.bv));
760 }
761
763 {
765 }
766
768 {
770 }
771
772 static const Boxed_Number sum(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
773 {
774 return Boxed_Number(oper(Operators::Opers::sum, t_lhs.bv, t_rhs.bv));
775 }
776
777 static const Boxed_Number unary_plus(const Boxed_Number &t_lhs)
778 {
779 return Boxed_Number(oper(Operators::Opers::unary_plus, t_lhs.bv));
780 }
781
782 static const Boxed_Number unary_minus(const Boxed_Number &t_lhs)
783 {
784 return Boxed_Number(oper(Operators::Opers::unary_minus, t_lhs.bv));
785 }
786
787 static const Boxed_Number difference(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
788 {
789 return Boxed_Number(oper(Operators::Opers::difference, t_lhs.bv, t_rhs.bv));
790 }
791
793 {
794 return Boxed_Number(oper(Operators::Opers::assign_bitwise_and, t_lhs.bv, t_rhs.bv));
795 }
796
797 static Boxed_Number assign(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
798 {
799 return Boxed_Number(oper(Operators::Opers::assign, t_lhs.bv, t_rhs.bv));
800 }
801
803 {
804 return Boxed_Number(oper(Operators::Opers::assign_bitwise_or, t_lhs.bv, t_rhs.bv));
805 }
806
808 {
809 return Boxed_Number(oper(Operators::Opers::assign_bitwise_xor, t_lhs.bv, t_rhs.bv));
810 }
811
813 {
814 return Boxed_Number(oper(Operators::Opers::assign_remainder, t_lhs.bv, t_rhs.bv));
815 }
816
818 {
819 return Boxed_Number(oper(Operators::Opers::assign_shift_left, t_lhs.bv, t_rhs.bv));
820 }
821
823 {
824 return Boxed_Number(oper(Operators::Opers::assign_shift_right, t_lhs.bv, t_rhs.bv));
825 }
826
827 static const Boxed_Number bitwise_and(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
828 {
829 return Boxed_Number(oper(Operators::Opers::bitwise_and, t_lhs.bv, t_rhs.bv));
830 }
831
833 {
835 }
836
837 static const Boxed_Number bitwise_xor(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
838 {
839 return Boxed_Number(oper(Operators::Opers::bitwise_xor, t_lhs.bv, t_rhs.bv));
840 }
841
842 static const Boxed_Number bitwise_or(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
843 {
844 return Boxed_Number(oper(Operators::Opers::bitwise_or, t_lhs.bv, t_rhs.bv));
845 }
846
848 {
849 return Boxed_Number(oper(Operators::Opers::assign_product, t_lhs.bv, t_rhs.bv));
850 }
851
853 {
854 return Boxed_Number(oper(Operators::Opers::assign_quotient, t_lhs.bv, t_rhs.bv));
855 }
856
858 {
859 return Boxed_Number(oper(Operators::Opers::assign_sum, t_lhs.bv, t_rhs.bv));
860 }
862 {
863 return Boxed_Number(oper(Operators::Opers::assign_difference, t_lhs.bv, t_rhs.bv));
864 }
865
866 static const Boxed_Number quotient(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
867 {
868 return Boxed_Number(oper(Operators::Opers::quotient, t_lhs.bv, t_rhs.bv));
869 }
870
871 static const Boxed_Number shift_left(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
872 {
873 return Boxed_Number(oper(Operators::Opers::shift_left, t_lhs.bv, t_rhs.bv));
874 }
875
876 static const Boxed_Number product(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
877 {
878 return Boxed_Number(oper(Operators::Opers::product, t_lhs.bv, t_rhs.bv));
879 }
880
881 static const Boxed_Number remainder(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
882 {
883 return Boxed_Number(oper(Operators::Opers::remainder, t_lhs.bv, t_rhs.bv));
884 }
885
886 static const Boxed_Number shift_right(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
887 {
888 return Boxed_Number(oper(Operators::Opers::shift_right, t_lhs.bv, t_rhs.bv));
889 }
890
891
892
893 static Boxed_Value do_oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
894 {
895 return oper(t_oper, t_lhs, t_rhs);
896 }
897
898 static Boxed_Value do_oper(Operators::Opers t_oper, const Boxed_Value &t_lhs)
899 {
900 return oper(t_oper, t_lhs);
901 }
902
903
904
906 };
907
908 namespace detail
909 {
911 template<>
913 {
915 {
916 return Boxed_Number(ob);
917 }
918 };
919
921 template<>
923 {
924 };
925
927 template<>
928 struct Cast_Helper<const Boxed_Number> : Cast_Helper<Boxed_Number>
929 {
930 };
931 }
932
933#ifdef __GNUC__
934#pragma GCC diagnostic pop
935#endif
936
937#ifdef CHAISCRIPT_MSVC
938#pragma warning(pop)
939#endif
940
941}
942
943
944
945#endif
946
Represents any numeric type, generically. Used internally for generic operations between POD values.
Definition boxed_number.hpp:66
static bool not_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:757
static Boxed_Value clone(const Boxed_Value &t_bv)
Definition boxed_number.hpp:524
static Boxed_Number assign(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:797
static const Boxed_Number bitwise_complement(const Boxed_Number &t_lhs)
Definition boxed_number.hpp:832
static Boxed_Number assign_bitwise_and(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:792
Boxed_Number & operator=(Boxed_Number &&)=default
Boxed_Number(Boxed_Value v)
Definition boxed_number.hpp:508
static const Boxed_Number shift_left(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:871
static Boxed_Number pre_increment(Boxed_Number t_lhs)
Definition boxed_number.hpp:767
static Boxed_Number pre_decrement(Boxed_Number t_lhs)
Definition boxed_number.hpp:762
static Boxed_Number assign_product(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:847
static bool greater_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:742
static bool less_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:737
static const Boxed_Number bitwise_or(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:842
static const Boxed_Number unary_plus(const Boxed_Number &t_lhs)
Definition boxed_number.hpp:777
static const Boxed_Number quotient(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:866
static const Boxed_Number unary_minus(const Boxed_Number &t_lhs)
Definition boxed_number.hpp:782
static const Boxed_Number sum(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:772
std::string to_string() const
Definition boxed_number.hpp:686
Target get_as() const
Definition boxed_number.hpp:656
static Boxed_Number assign_shift_left(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:817
static Boxed_Number assign_bitwise_xor(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:807
static void validate_boxed_number(const Boxed_Value &v)
Definition boxed_number.hpp:716
static Boxed_Number assign_difference(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:861
Boxed_Number(T t)
Definition boxed_number.hpp:518
static const Boxed_Number bitwise_xor(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:837
static const Boxed_Number shift_right(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:886
static Boxed_Number assign_remainder(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:812
static Boxed_Value do_oper(Operators::Opers t_oper, const Boxed_Value &t_lhs)
Definition boxed_number.hpp:898
static bool greater_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:747
static const Boxed_Number bitwise_and(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:827
Target get_as_checked() const
Definition boxed_number.hpp:614
static const Boxed_Number remainder(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:881
static Boxed_Number assign_sum(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:857
Boxed_Number()
Definition boxed_number.hpp:503
static const Boxed_Number product(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:876
static Boxed_Number assign_bitwise_or(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:802
static void check_type()
Definition boxed_number.hpp:596
Boxed_Number(const Boxed_Number &)=default
static Boxed_Number assign_quotient(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:852
static Boxed_Number assign_shift_right(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:822
static Boxed_Value do_oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
Definition boxed_number.hpp:893
static bool equals(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:732
static bool less_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:752
static const Boxed_Number difference(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
Definition boxed_number.hpp:787
static bool is_floating_point(const Boxed_Value &t_bv)
Definition boxed_number.hpp:528
Boxed_Number get_as(const Type_Info &inp_) const
Definition boxed_number.hpp:543
Boxed_Value bv
Definition boxed_number.hpp:905
Boxed_Number(Boxed_Number &&)=default
A wrapper for holding any valid C++ type. All types in ChaiScript are Boxed_Value objects.
Definition boxed_value.hpp:28
void * get_ptr() const noexcept
Definition boxed_value.hpp:311
const void * get_const_ptr() const noexcept
Definition boxed_value.hpp:316
bool is_const() const noexcept
Definition boxed_value.hpp:235
const Type_Info & get_type_info() const noexcept
Definition boxed_value.hpp:224
bool is_return_value() const noexcept
Definition boxed_value.hpp:296
Definition type_conversions.hpp:512
Definition type_conversions.hpp:321
Compile time deduced information about a type.
Definition type_info.hpp:34
constexpr bool bare_equal_type_info(const std::type_info &ti) const noexcept
Definition type_info.hpp:81
constexpr bool is_arithmetic() const noexcept
Definition type_info.hpp:89
Thrown in the event that an Any cannot be cast to the desired type.
Definition any.hpp:22
Classes and functions reserved for internal use. Items in this namespace are not supported.
Classes which may be thrown during error cases when ChaiScript is executing.
Definition bad_boxed_cast.hpp:27
Namespace chaiscript contains every API call that the average user will be concerned with.
decltype(auto) boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions=nullptr)
Function for extracting a value stored in a Boxed_Value object.
Definition boxed_cast.hpp:76
Boxed_Value const_var(const T &t)
Takes an object and returns an immutable Boxed_Value. If the object is a std::reference or pointer ty...
Definition boxed_value.hpp:461
STL namespace.
Definition GameApi.h:42
Opers
Definition chaiscript_algebraic.hpp:23
@ shift_right
Definition chaiscript_algebraic.hpp:33
@ pre_increment
Definition chaiscript_algebraic.hpp:27
@ non_const_int_flag
Definition chaiscript_algebraic.hpp:29
@ sum
Definition chaiscript_algebraic.hpp:35
@ pre_decrement
Definition chaiscript_algebraic.hpp:27
@ less_than_equal
Definition chaiscript_algebraic.hpp:25
@ boolean_flag
Definition chaiscript_algebraic.hpp:24
@ bitwise_and
Definition chaiscript_algebraic.hpp:33
@ bitwise_xor
Definition chaiscript_algebraic.hpp:33
@ assign_bitwise_or
Definition chaiscript_algebraic.hpp:30
@ unary_minus
Definition chaiscript_algebraic.hpp:35
@ assign
Definition chaiscript_algebraic.hpp:27
@ const_flag
Definition chaiscript_algebraic.hpp:34
@ equals
Definition chaiscript_algebraic.hpp:25
@ assign_shift_left
Definition chaiscript_algebraic.hpp:30
@ bitwise_complement
Definition chaiscript_algebraic.hpp:33
@ assign_sum
Definition chaiscript_algebraic.hpp:27
@ assign_product
Definition chaiscript_algebraic.hpp:27
@ less_than
Definition chaiscript_algebraic.hpp:25
@ assign_remainder
Definition chaiscript_algebraic.hpp:31
@ quotient
Definition chaiscript_algebraic.hpp:35
@ assign_bitwise_xor
Definition chaiscript_algebraic.hpp:31
@ remainder
Definition chaiscript_algebraic.hpp:33
@ assign_bitwise_and
Definition chaiscript_algebraic.hpp:30
@ assign_difference
Definition chaiscript_algebraic.hpp:28
@ difference
Definition chaiscript_algebraic.hpp:35
@ not_equal
Definition chaiscript_algebraic.hpp:25
@ const_int_flag
Definition chaiscript_algebraic.hpp:32
@ assign_quotient
Definition chaiscript_algebraic.hpp:28
@ greater_than_equal
Definition chaiscript_algebraic.hpp:25
@ shift_left
Definition chaiscript_algebraic.hpp:33
@ unary_plus
Definition chaiscript_algebraic.hpp:35
@ non_const_flag
Definition chaiscript_algebraic.hpp:26
@ bitwise_or
Definition chaiscript_algebraic.hpp:33
@ product
Definition chaiscript_algebraic.hpp:35
@ assign_shift_right
Definition chaiscript_algebraic.hpp:30
@ greater_than
Definition chaiscript_algebraic.hpp:25
static Boxed_Number cast(const Boxed_Value &ob, const Type_Conversions_State *)
Definition boxed_number.hpp:914
The exposed Cast_Helper object that by default just calls the Cast_Helper_Inner.
Definition boxed_cast_helper.hpp:313
Definition boxed_number.hpp:33
~arithmetic_error() noexcept override=default
arithmetic_error(const arithmetic_error &)=default
arithmetic_error(const std::string &reason)
Definition boxed_number.hpp:34