Skip to content

Commit

Permalink
Add functions to see if internal type can handle 32-bit and 64-bit in…
Browse files Browse the repository at this point in the history
…tegers

This can be confirmed at compile time and via a parsed expression.
#13
  • Loading branch information
Blake-Madden committed Mar 2, 2024
1 parent 8e3b67c commit 15761c5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/manual/functions.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ The following built-in functions are available:
| SIN(Number) | Sine of the angle *Number* in radians. |
| SINH(Number) | Hyperbolic sine of *Number*. |
| SQRT(Number) | Square root of *Number*. |
| SUPPORTS32BIT() | Returns true if 32-bit integers are supported. This will affect the supported range of values for bitwise operations. |
| SUPPORTS64BIT() | Returns true if 64-bit integers are supported. This will affect the supported range of values for bitwise operations. |
| TAN(Number) | Tangent of *Number*. |
| TGAMMA(Number) | Returns the gamma function of *Number*. |
| TRUNC(Number) | Discards the fractional part of *Number*.<br>\linebreak `TRUNC(-3.2)` = -3<br>\linebreak `TRUNC(3.2)` = 3 |
Expand Down
32 changes: 32 additions & 0 deletions tests/tetests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,38 @@ TEST_CASE("Zeros", "[zeros]")
CHECK(std::isnan(tep.evaluate("(1%0)%1")));
}

TEST_CASE("UINT support", "[uint]")
{
te_parser tep;

if constexpr(te_parser::supports_32bit())
{
INFO("Checking for handling of large value: " +
std::to_string(std::numeric_limits<uint32_t>::max()));
CHECK(tep.evaluate(std::to_string(std::numeric_limits<uint32_t>::max())) ==
std::numeric_limits<uint32_t>::max());
CHECK(tep.evaluate(
"(" + std::to_string(std::numeric_limits<uint32_t>::max()) + " - 100) + 100") ==
std::numeric_limits<uint32_t>::max());
CHECK(tep.evaluate(
std::to_string(std::numeric_limits<uint32_t>::max()) + " - 700") ==
std::numeric_limits<uint32_t>::max() - 700);
}

if constexpr(te_parser::supports_64bit())
{
INFO("Checking for handling of large value: " +
std::to_string(std::numeric_limits<uint64_t>::max()));
CHECK(tep.evaluate(std::to_string(std::numeric_limits<uint64_t>::max())) ==
std::numeric_limits<uint64_t>::max());
CHECK(tep.evaluate(
"(" + std::to_string(std::numeric_limits<uint64_t>::max()) + " - 100) + 100") ==
std::numeric_limits<uint64_t>::max());
CHECK(tep.evaluate(
std::to_string(std::numeric_limits<uint64_t>::max()) + " - 700") ==
std::numeric_limits<uint64_t>::max() - 700);
}
}

TEST_CASE("Braces", "[braces]")
{
Expand Down
14 changes: 14 additions & 0 deletions tinyexpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,18 @@ namespace te_builtins
return te_parser::te_max_value;
}

[[nodiscard]]
constexpr static te_type te_supports_32bit() noexcept
{
return te_parser::supports_32bit() ? 1.0 : 0.0;
}

[[nodiscard]]
constexpr static te_type te_supports_64bit() noexcept
{
return te_parser::supports_64bit() ? 1.0 : 0.0;
}

// cotangent
[[nodiscard]]
static te_type te_cot(te_type val) noexcept
Expand Down Expand Up @@ -986,6 +998,8 @@ const std::set<te_variable> te_parser::m_functions = { // NOLINT
{ "sqrt", static_cast<te_fun1>(te_builtins::te_sqrt), TE_PURE },
{ "sum", static_cast<te_fun7>(te_builtins::te_sum),
static_cast<te_variable_flags>(TE_PURE | TE_VARIADIC) },
{ "supports32bit", static_cast<te_fun0>(te_builtins::te_supports_32bit), TE_PURE },
{ "supports64bit", static_cast<te_fun0>(te_builtins::te_supports_64bit), TE_PURE },
{ "tan", static_cast<te_fun1>(te_builtins::te_tan), TE_PURE },
{ "tanh", static_cast<te_fun1>(te_builtins::te_tanh), TE_PURE },
{ "tgamma", static_cast<te_fun1>(te_builtins::te_tgamma), TE_PURE },
Expand Down
10 changes: 10 additions & 0 deletions tinyexpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ class te_parser
/// @brief No position, which is what get_last_error_position() returns
/// when there was no parsing error.
constexpr static int64_t npos = -1;
/// @returns @c true if the parser's internal type can hold `uint32_t` without truncation.
constexpr static bool supports_32bit() noexcept
{
return std::numeric_limits<te_type>::digits >= std::numeric_limits<uint32_t>::digits;
}
/// @returns @c true if the parser's internal type can hold `uint64_t` without truncation.
constexpr static bool supports_64bit() noexcept
{
return std::numeric_limits<te_type>::digits >= std::numeric_limits<uint64_t>::digits;
}
/** @brief Parses the input @c expression.
@param expression The formula to compile.
@returns Whether the expression compiled or not. (This can be checked
Expand Down

0 comments on commit 15761c5

Please sign in to comment.