[GIT] ppl/ppl(master): New constructor explicit Interval::Interval( const char* s).

Module: ppl/ppl Branch: master Commit: e61defee29d0688a72fbe707157351a85c9a35a1 URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=e61defee29d06...
Author: Roberto Bagnara bagnara@cs.unipr.it Date: Thu Sep 24 16:23:44 2009 +0200
New constructor explicit Interval::Interval(const char* s).
---
src/Interval.defs.hh | 12 ++++-- src/Interval.templates.hh | 94 +++++++++++++++++++++++++++++++++++++++++++- tests/Box/interval1.cc | 11 +++++ 3 files changed, 110 insertions(+), 7 deletions(-)
diff --git a/src/Interval.defs.hh b/src/Interval.defs.hh index d39505a..4fe0463 100644 --- a/src/Interval.defs.hh +++ b/src/Interval.defs.hh @@ -664,16 +664,20 @@ public: return true; }
- Interval() - { + Interval() { }
template <typename T> - explicit Interval(const T& x) - { + explicit Interval(const T& x) { assign(x); }
+ /*! \brief + Builds the smallest interval containing the number whose textual + representation is contained in \p s. + */ + explicit Interval(const char* s); + template <typename T> typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, bool>::type diff --git a/src/Interval.templates.hh b/src/Interval.templates.hh index ec5cfcf..1e0b3f8 100644 --- a/src/Interval.templates.hh +++ b/src/Interval.templates.hh @@ -75,6 +75,92 @@ Interval<Boundary, Info>::CC76_widening_assign(const From& y, }
template <typename Boundary, typename Info> +Interval<Boundary, Info>::Interval(const char* s) { + // Get the lower bound. + Boundary lower_bound; + Result lower_r = assign_r(lower_bound, s, ROUND_DOWN); + if (lower_r == V_CVT_STR_UNK || lower_r == V_NAN) { + throw std::invalid_argument("PPL::Interval(const char* s)" + " with s invalid"); + } + lower_r = result_relation_class(lower_r); + + // Get the upper bound. + Boundary upper_bound; + Result upper_r = assign_r(upper_bound, s, ROUND_UP); + assert(upper_r != V_CVT_STR_UNK && upper_r != V_NAN); + upper_r = result_relation_class(upper_r); + + // Buld the interval. + bool lower_open = false; + bool upper_open = false; + bool lower_boundary_infinity = false; + bool upper_boundary_infinity = false; + switch (lower_r) { + case V_EQ: + case V_GE: + break; + case V_GT: + lower_open = true; + break; + case V_EQ_MINUS_INFINITY: + case V_GT_MINUS_INFINITY: + lower_boundary_infinity = true; + break; + case V_EQ_PLUS_INFINITY: + case V_LT_PLUS_INFINITY: + if (upper_r == V_EQ_PLUS_INFINITY || upper_r == V_LT_PLUS_INFINITY) + assign(UNIVERSE); + else + assign(EMPTY); + break; + default: + std::cerr << "lower_r = " << lower_r << std::endl; + PPL_ASSERT(false); + } + switch (upper_r) { + case V_EQ: + case V_LE: + break; + case V_LT: + upper_open = true; + break; + case V_EQ_MINUS_INFINITY: + case V_GT_MINUS_INFINITY: + if (lower_r == V_EQ_MINUS_INFINITY || lower_r == V_GT_MINUS_INFINITY) + assign(UNIVERSE); + else + assign(EMPTY); + break; + case V_EQ_PLUS_INFINITY: + case V_LT_PLUS_INFINITY: + upper_boundary_infinity = true; + break; + default: + PPL_ASSERT(false); + } + + if (!lower_boundary_infinity + && !upper_boundary_infinity + && (lower_bound > upper_bound + || (lower_open && lower_bound == upper_bound))) + assign(EMPTY); + else { + if (lower_boundary_infinity) + special_set_boundary_infinity(LOWER, lower(), info()); + else + Boundary_NS::assign(LOWER, lower(), info(), + LOWER, lower_bound, SCALAR_INFO, lower_open); + if (upper_boundary_infinity) + special_set_boundary_infinity(UPPER, upper(), info()); + else + Boundary_NS::assign(UPPER, upper(), info(), + UPPER, upper_bound, SCALAR_INFO, upper_open); + } +} + + +template <typename Boundary, typename Info> inline std::istream& operator>>(std::istream& is, Interval<Boundary, Info>& x) { // Eat leading white space. @@ -105,7 +191,7 @@ operator>>(std::istream& is, Interval<Boundary, Info>& x) {
// Get the lower bound. Boundary lower_bound; - Result lower_r = input(lower_bound, is, ROUND_DOWN); + Result lower_r = input(lower_bound, is, ROUND_DOWN); if (lower_r == V_CVT_STR_UNK || lower_r == V_NAN) { is.setstate(std::ios_base::failbit); return is; @@ -197,11 +283,13 @@ operator>>(std::istream& is, Interval<Boundary, Info>& x) { if (lower_boundary_infinity) special_set_boundary_infinity(LOWER, x.lower(), x.info()); else - assign(LOWER, x.lower(), x.info(), LOWER, lower_bound, SCALAR_INFO, lower_open); + assign(LOWER, x.lower(), x.info(), + LOWER, lower_bound, SCALAR_INFO, lower_open); if (upper_boundary_infinity) special_set_boundary_infinity(UPPER, x.upper(), x.info()); else - assign(UPPER, x.upper(), x.info(), UPPER, upper_bound, SCALAR_INFO, upper_open); + assign(UPPER, x.upper(), x.info(), + UPPER, upper_bound, SCALAR_INFO, upper_open); } return is; } diff --git a/tests/Box/interval1.cc b/tests/Box/interval1.cc index a4342bc..1dd786a 100644 --- a/tests/Box/interval1.cc +++ b/tests/Box/interval1.cc @@ -178,6 +178,14 @@ bool test04() { return true; }
+template<typename F> +bool +test05() { + typename My_Interval<F>::interval_type x("123.00123"); + nout << "x = " << x << endl; + return true; +} + } // namespace
BEGIN_MAIN @@ -187,6 +195,7 @@ BEGIN_MAIN DO_TEST(test02<float>); DO_TEST(test03<float>); DO_TEST(test04<float>); + DO_TEST(test05<float>); #endif // PPL_SUPPORTED_FLOAT
#if PPL_SUPPORTED_DOUBLE @@ -194,6 +203,7 @@ BEGIN_MAIN DO_TEST(test02<double>); DO_TEST(test03<double>); DO_TEST(test04<double>); + DO_TEST(test05<double>); #endif // PPL_SUPPORTED_DOUBLE
#if PPL_SUPPORTED_LONG_DOUBLE @@ -201,6 +211,7 @@ BEGIN_MAIN DO_TEST(test02<long double>); DO_TEST(test03<long double>); DO_TEST(test04<long double>); + DO_TEST(test05<long double>); #endif // PPL_SUPPORTED_LONG_DOUBLE
END_MAIN
participants (1)
-
Roberto Bagnara