[PPL-devel] [GIT] ppl/ppl(master): New constructor explicit Interval::Interval( const char* s).
Roberto Bagnara
bagnara at cs.unipr.it
Thu Sep 24 16:24:43 CEST 2009
Module: ppl/ppl
Branch: master
Commit: e61defee29d0688a72fbe707157351a85c9a35a1
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=e61defee29d0688a72fbe707157351a85c9a35a1
Author: Roberto Bagnara <bagnara at 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
More information about the PPL-devel
mailing list