Skip to content

Commit f7008cc

Browse files
committed
Updates to ExprTk
1 parent 6d19525 commit f7008cc

File tree

2 files changed

+96
-56
lines changed

2 files changed

+96
-56
lines changed

exprtk/exprtk.hpp

Lines changed: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -812,34 +812,23 @@ namespace exprtk
812812
#undef exprtk_register_int_type_tag
813813

814814
template <typename T>
815-
struct epsilon_type
816-
{
817-
static inline T value()
818-
{
819-
const T epsilon = T(0.0000000001);
820-
return epsilon;
821-
}
822-
};
815+
struct epsilon_type {};
823816

824-
template <>
825-
struct epsilon_type <float>
826-
{
827-
static inline float value()
828-
{
829-
const float epsilon = float(0.000001f);
830-
return epsilon;
831-
}
832-
};
817+
#define exprtk_define_epsilon_type(Type, Epsilon) \
818+
template <> struct epsilon_type<Type> \
819+
{ \
820+
static inline Type value() \
821+
{ \
822+
const Type epsilon = static_cast<Type>(Epsilon); \
823+
return epsilon; \
824+
} \
825+
}; \
833826

834-
template <>
835-
struct epsilon_type <long double>
836-
{
837-
static inline long double value()
838-
{
839-
const long double epsilon = static_cast<long double>(0.000000000001);
840-
return epsilon;
841-
}
842-
};
827+
exprtk_define_epsilon_type(float , 0.000001f)
828+
exprtk_define_epsilon_type(double , 0.0000000001)
829+
exprtk_define_epsilon_type(long double, 0.000000000001)
830+
831+
#undef exprtk_define_epsilon_type
843832

844833
template <typename T>
845834
inline bool is_nan_impl(const T v, real_type_tag)
@@ -1839,8 +1828,8 @@ namespace exprtk
18391828
template <typename T>
18401829
inline bool valid_exponent(const int exponent, numeric::details::real_type_tag)
18411830
{
1842-
return (std::numeric_limits<T>::min_exponent10 <= exponent) &&
1843-
(exponent <= std::numeric_limits<T>::max_exponent10) ;
1831+
using namespace details::numeric;
1832+
return (numeric_info<T>::min_exp <= exponent) && (exponent <= numeric_info<T>::max_exp);
18441833
}
18451834

18461835
template <typename Iterator, typename T>
@@ -1885,14 +1874,7 @@ namespace exprtk
18851874

18861875
while (end != itr)
18871876
{
1888-
// Note: For 'physical' superscalar architectures it
1889-
// is advised that the following loop be: 4xPD1 and 1xPD2
18901877
unsigned int digit;
1891-
1892-
#ifdef exprtk_enable_superscalar
1893-
parse_digit_1(d)
1894-
parse_digit_1(d)
1895-
#endif
18961878
parse_digit_1(d)
18971879
parse_digit_1(d)
18981880
parse_digit_2(d)
@@ -1913,12 +1895,6 @@ namespace exprtk
19131895
while (end != itr)
19141896
{
19151897
unsigned int digit;
1916-
1917-
#ifdef exprtk_enable_superscalar
1918-
parse_digit_1(tmp_d)
1919-
parse_digit_1(tmp_d)
1920-
parse_digit_1(tmp_d)
1921-
#endif
19221898
parse_digit_1(tmp_d)
19231899
parse_digit_1(tmp_d)
19241900
parse_digit_2(tmp_d)
@@ -1928,12 +1904,12 @@ namespace exprtk
19281904
{
19291905
instate = true;
19301906

1931-
const int exponent = static_cast<int>(-std::distance(curr, itr));
1907+
const int frac_exponent = static_cast<int>(-std::distance(curr, itr));
19321908

1933-
if (!valid_exponent<T>(exponent, numeric::details::real_type_tag()))
1909+
if (!valid_exponent<T>(frac_exponent, numeric::details::real_type_tag()))
19341910
return false;
19351911

1936-
d += compute_pow10(tmp_d, exponent);
1912+
d += compute_pow10(tmp_d, frac_exponent);
19371913
}
19381914

19391915
#undef parse_digit_1
@@ -4404,7 +4380,7 @@ namespace exprtk
44044380
{
44054381
public:
44064382

4407-
parameter_list(std::vector<type_store>& pl)
4383+
explicit parameter_list(std::vector<type_store>& pl)
44084384
: parameter_list_(pl)
44094385
{}
44104386

@@ -4461,12 +4437,12 @@ namespace exprtk
44614437
typedef type_store<T> type_store_t;
44624438
typedef ViewType value_t;
44634439

4464-
type_view(type_store_t& ts)
4440+
explicit type_view(type_store_t& ts)
44654441
: ts_(ts),
44664442
data_(reinterpret_cast<value_t*>(ts_.data))
44674443
{}
44684444

4469-
type_view(const type_store_t& ts)
4445+
explicit type_view(const type_store_t& ts)
44704446
: ts_(const_cast<type_store_t&>(ts)),
44714447
data_(reinterpret_cast<value_t*>(ts_.data))
44724448
{}
@@ -4511,11 +4487,11 @@ namespace exprtk
45114487
typedef type_store<T> type_store_t;
45124488
typedef T value_t;
45134489

4514-
scalar_view(type_store_t& ts)
4490+
explicit scalar_view(type_store_t& ts)
45154491
: v_(*reinterpret_cast<value_t*>(ts.data))
45164492
{}
45174493

4518-
scalar_view(const type_store_t& ts)
4494+
explicit scalar_view(const type_store_t& ts)
45194495
: v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
45204496
{}
45214497

@@ -4802,7 +4778,7 @@ namespace exprtk
48024778
destruct (true)
48034779
{}
48044780

4805-
control_block(const std::size_t& dsize)
4781+
explicit control_block(const std::size_t& dsize)
48064782
: ref_count(1 ),
48074783
size (dsize),
48084784
data (0 ),
@@ -4880,7 +4856,7 @@ namespace exprtk
48804856
: control_block_(control_block::create(0))
48814857
{}
48824858

4883-
vec_data_store(const std::size_t& size)
4859+
explicit vec_data_store(const std::size_t& size)
48844860
: control_block_(control_block::create(size,reinterpret_cast<data_t>(0),true))
48854861
{}
48864862

@@ -6651,7 +6627,7 @@ namespace exprtk
66516627
{
66526628
public:
66536629

6654-
break_exception(const T& v)
6630+
explicit break_exception(const T& v)
66556631
: value(v)
66566632
{}
66576633

@@ -7559,13 +7535,13 @@ namespace exprtk
75597535
const std::size_t r1,
75607536
const std::size_t size) const
75617537
{
7562-
if ((r0 < 0) || (r0 >= size))
7538+
if (r0 >= size)
75637539
{
75647540
throw std::runtime_error("range error: (r0 < 0) || (r0 >= size)");
75657541
return false;
75667542
}
75677543

7568-
if ((r1 < 0) || (r1 >= size))
7544+
if (r1 >= size)
75697545
{
75707546
throw std::runtime_error("range error: (r1 < 0) || (r1 >= size)");
75717547
return false;
@@ -37500,8 +37476,16 @@ namespace exprtk
3750037476
template <typename BaseFuncType>
3750137477
struct scoped_bft
3750237478
{
37503-
scoped_bft(BaseFuncType& bft) : bft_(bft) { bft_.pre (); }
37504-
~scoped_bft() { bft_.post(); }
37479+
explicit scoped_bft(BaseFuncType& bft)
37480+
: bft_(bft)
37481+
{
37482+
bft_.pre ();
37483+
}
37484+
37485+
~scoped_bft()
37486+
{
37487+
bft_.post();
37488+
}
3750537489

3750637490
BaseFuncType& bft_;
3750737491

exprtk/exprtk_test.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,43 @@ inline bool test_expression(const std::string& expression_string, const T& expec
11771177
return true;
11781178
}
11791179

1180+
template <typename T>
1181+
struct edge_cases {};
1182+
1183+
template <>
1184+
struct edge_cases<float>
1185+
{
1186+
static inline std::vector<test_t> test_cases()
1187+
{
1188+
std::vector<test_t> cases;
1189+
cases.push_back(test_t(" 1.175494350822287508e-38", 1.175494350822287508e-38));
1190+
cases.push_back(test_t(" 3.402823466385288598e+38", 3.402823466385288598e+38));
1191+
cases.push_back(test_t("+1.175494350822287508e-38", +1.175494350822287508e-38));
1192+
cases.push_back(test_t("+3.402823466385288598e+38", +3.402823466385288598e+38));
1193+
cases.push_back(test_t("-1.175494350822287508e-38", -1.175494350822287508e-38));
1194+
cases.push_back(test_t("-3.402823466385288598e+38", -3.402823466385288598e+38));
1195+
1196+
return cases;
1197+
}
1198+
};
1199+
1200+
template <>
1201+
struct edge_cases<double>
1202+
{
1203+
static inline std::vector<test_t> test_cases()
1204+
{
1205+
std::vector<test_t> cases;
1206+
cases.push_back(test_t(" 2.2250738585072013831e-308", 2.2250738585072013831e-308));
1207+
cases.push_back(test_t(" 1.7976931348623157081e+308", 1.7976931348623157081e+308));
1208+
cases.push_back(test_t("+2.2250738585072013831e-308", +2.2250738585072013831e-308));
1209+
cases.push_back(test_t("+1.7976931348623157081e+308", +1.7976931348623157081e+308));
1210+
cases.push_back(test_t("-2.2250738585072013831e-308", -2.2250738585072013831e-308));
1211+
cases.push_back(test_t("-1.7976931348623157081e+308", -1.7976931348623157081e+308));
1212+
1213+
return cases;
1214+
}
1215+
};
1216+
11801217
template <typename T>
11811218
inline bool run_test00()
11821219
{
@@ -1198,6 +1235,25 @@ inline bool run_test00()
11981235
}
11991236
}
12001237

1238+
{
1239+
const std::vector<test_t> tests = edge_cases<T>::test_cases();
1240+
1241+
bool result = true;
1242+
1243+
for (std::size_t i = 0; i < tests.size(); ++i)
1244+
{
1245+
if (!test_expression<T>(tests[i].first,T(tests[i].second)))
1246+
{
1247+
result = false;
1248+
}
1249+
}
1250+
1251+
if (!result)
1252+
{
1253+
return false;
1254+
}
1255+
}
1256+
12011257
return true;
12021258
}
12031259

0 commit comments

Comments
 (0)