diff --git a/src/arithmetic/ibex_Interval.cpp b/src/arithmetic/ibex_Interval.cpp index b29f91962..491adb025 100644 --- a/src/arithmetic/ibex_Interval.cpp +++ b/src/arithmetic/ibex_Interval.cpp @@ -12,6 +12,8 @@ #include "ibex_Interval.h" #include #include +#include +#include #ifdef _IBEX_WITH_GAOL_ #include "ibex_Interval_gaol.cpp_" @@ -289,5 +291,66 @@ int Interval::diff(const Interval& y, Interval& c1, Interval& c2) const { return res; } +Interval::Interval(const std::string& s) { + if(s.find(EMPTY_SET) != std::string::npos) + *this = EMPTY_SET; + + else if(s.find(POS_REALS) != std::string::npos) + *this = POS_REALS; + + else if(s.find(NEG_REALS) != std::string::npos) + *this = NEG_REALS; + + else if(s.find(ALL_REALS) != std::string::npos) + *this = ALL_REALS; + + else { // string of the form "[lb, ub]" + // Removing unwanted spaces: + std::string clean_s = s; + clean_s.erase(std::remove(clean_s.begin(), clean_s.end(), ' '), clean_s.end()); + + std::string delimiter = ","; + size_t pos_delimiter = clean_s.find(','); + + assert(pos_delimiter != std::string::npos); + + std::string lb = clean_s.substr(1, clean_s.find(delimiter) - delimiter.length()); + std::string ub = clean_s.substr(lb.length() + 2, clean_s.length() - lb.length() - delimiter.length() - 2); + + *this = Interval(atof(lb.c_str()), atof(ub.c_str())); + } +} + +std::ostream& operator<<(std::ostream& os, const Interval& x) { + // A specific string has to be set for the following cases: + // (in order to not depend on the interval library) + if(x == Interval::EMPTY_SET) + os << "[ empty ]"; + + else if(x == Interval::POS_REALS) + os << "[ pos_reals ]"; + + else if(x == Interval::NEG_REALS) + os << "[ neg_reals ]"; + + else if(x == Interval::ALL_REALS) + os << "[ all_reals ]"; + + else + { + #ifdef _IBEX_WITH_FILIB_ + filib::interval::precision(os.precision()); + #endif + os << "[" << (double)x.lb() << ", " << (double)x.ub() << "]"; + } + + return os; +} + +Interval::operator std::string() const { + std::stringstream sstream; + sstream << *this; + return sstream.str(); +} } // end namespace diff --git a/src/arithmetic/ibex_Interval.h b/src/arithmetic/ibex_Interval.h index 87a0d91b0..722e6aabe 100644 --- a/src/arithmetic/ibex_Interval.h +++ b/src/arithmetic/ibex_Interval.h @@ -182,6 +182,16 @@ class Interval { /** \brief Create [a,a]. */ Interval(double a); + /** + * \brief Parses the std::string str, interpreting its content as + * an interval and instantiating the corresponding object. + * + * Note: unwanted spaces are removed before cast. + * + * \param str std::string, e.g.: "[-0.215,53.2]" or "[ empty ]" + */ + Interval(const std::string& str); + /** \brief True iff *this and x are exactly the same intervals. */ bool operator==(const Interval& x) const; @@ -528,6 +538,10 @@ class Interval { */ operator const ExprConstant&() const; + /** \brief Cast the interval into a const std::string + */ + operator std::string() const; + //private: #ifdef _IBEX_WITH_GAOL_ /* \brief Wrap the gaol-interval [x]. */ @@ -935,8 +949,6 @@ inline Interval& Interval::operator=(double x) { return *this; } - - inline Interval& Interval::operator=(const Interval& x) { itv = x.itv; return *this; @@ -953,7 +965,6 @@ inline Interval& Interval::inflate(double delta, double chi) { return *this; } - inline bool Interval::operator!=(const Interval& x) const { return !(*this==x); } @@ -1191,7 +1202,6 @@ inline bool bwd_atan(const Interval& y, Interval& x) { return !x.is_empty(); } - inline bool bwd_acosh(const Interval& y, Interval& x) { if (y.is_empty() || y.ub()<0.0) { x.set_empty(); return false; @@ -1520,6 +1530,14 @@ inline bool bwd_imod(Interval& x, Interval& y, const double& p) { return true; } +inline std::string operator+(const std::string& s, const Interval& x) { + return s + (std::string)x; +} + +inline std::string operator+(const Interval& x, const std::string& s) { + return (std::string)x + s; +} + } // end namespace ibex #endif // _IBEX_INTERVAL_H_ diff --git a/src/arithmetic/ibex_Interval_bias.cpp_ b/src/arithmetic/ibex_Interval_bias.cpp_ index 43284e5ef..f9cd0a72c 100644 --- a/src/arithmetic/ibex_Interval_bias.cpp_ +++ b/src/arithmetic/ibex_Interval_bias.cpp_ @@ -34,13 +34,5 @@ const Interval Interval::PI(3.14159265358979323846, Succ(3.14159265358979323846) const Interval Interval::TWO_PI = PI*2.0; const Interval Interval::HALF_PI = PI/2.0; -std::ostream& operator<<(std::ostream& os, const Interval& x) { - if (x.is_empty()) - return os << "[ empty ]"; - else - return os << "[" << x.lb() << "," << x.ub() << "]"; - //return os << x.itv; -} - } // end namespace diff --git a/src/arithmetic/ibex_Interval_direct.cpp_ b/src/arithmetic/ibex_Interval_direct.cpp_ index bf49a69da..dfe8f4098 100644 --- a/src/arithmetic/ibex_Interval_direct.cpp_ +++ b/src/arithmetic/ibex_Interval_direct.cpp_ @@ -23,13 +23,5 @@ const Interval Interval::PI(3.14159265358979323846); const Interval Interval::TWO_PI = PI*2; const Interval Interval::HALF_PI = PI/2; -std::ostream& operator<<(std::ostream& os, const Interval& x) { - if (x.is_empty()) - return os << "[ empty ]"; - else - return os << "[" << x.lb() << "," << x.ub() << "]"; - //return os << x.itv; -} - } // end namespace diff --git a/src/arithmetic/ibex_Interval_filib.cpp_ b/src/arithmetic/ibex_Interval_filib.cpp_ index f980e2b86..b466183ae 100644 --- a/src/arithmetic/ibex_Interval_filib.cpp_ +++ b/src/arithmetic/ibex_Interval_filib.cpp_ @@ -59,15 +59,5 @@ const Interval Interval::HALF_PI =(filib::interval: filib::fp_traits::upward_divides(filib::constructFromBitSet( "0:10000000000:1001001000011111101101010100010001000010110100011001"),2.0))); */ - - -std::ostream& operator<<(std::ostream& os, const Interval& x) { - if (x.is_empty()) - return os << "[ empty ]"; - else - filib::interval::precision(os.precision()); - return os << x.itv; -} - } // end namespace diff --git a/src/arithmetic/ibex_Interval_gaol.cpp_ b/src/arithmetic/ibex_Interval_gaol.cpp_ index 0707b6d66..1f100a6b6 100644 --- a/src/arithmetic/ibex_Interval_gaol.cpp_ +++ b/src/arithmetic/ibex_Interval_gaol.cpp_ @@ -47,8 +47,4 @@ const Interval Interval::PI(pi_dn,pi_up); const Interval Interval::TWO_PI(2.0*pi_dn,2.0*pi_up); const Interval Interval::HALF_PI(half_pi_dn,half_pi_up); -std::ostream& operator<<(std::ostream& os, const Interval& x) { - return os << x.itv; -} - } // end namespace diff --git a/src/tools/ibex_String.cpp b/src/tools/ibex_String.cpp index 0e44eab36..d33c9545f 100644 --- a/src/tools/ibex_String.cpp +++ b/src/tools/ibex_String.cpp @@ -1,11 +1,11 @@ //============================================================================ // I B E X // File : ibex_String.cpp -// Author : Gilles Chabert +// Author : Gilles Chabert, Simon Rohou // Copyright : Ecole des Mines de Nantes (France) // License : See the LICENSE file // Created : Jul 18, 2012 -// Last Update : Jul 18, 2012 +// Last Update : April 18, 2016 //============================================================================ #include "ibex_String.h" @@ -58,5 +58,4 @@ char* next_generated_func_name() { return next_generated_name(BASE_FUNC_NAME,generated_func_count++); } - } // end namespace ibex diff --git a/src/tools/ibex_String.h b/src/tools/ibex_String.h index 29c76f098..c8c67f6d0 100644 --- a/src/tools/ibex_String.h +++ b/src/tools/ibex_String.h @@ -1,11 +1,11 @@ //============================================================================ // I B E X // File : ibex_String.h -// Author : Gilles Chabert +// Author : Gilles Chabert, Simon Rohou // Copyright : Ecole des Mines de Nantes (France) // License : See the LICENSE file // Created : Jul 18, 2012 -// Last Update : Jul 18, 2012 +// Last Update : April 18, 2016 //============================================================================ #ifndef __IBEX_STRING_H_ @@ -14,6 +14,7 @@ #include #include #include +#include "ibex_Interval.h" namespace ibex { diff --git a/tests/TestString.cpp b/tests/TestString.cpp index 6e797d8f7..8e3054bd5 100644 --- a/tests/TestString.cpp +++ b/tests/TestString.cpp @@ -5,12 +5,13 @@ * License : This program can be distributed under the terms of the GNU LGPL. * See the file COPYING.LESSER. * - * Author(s) : Gilles Chabert + * Author(s) : Gilles Chabert, Simon Rohou * Created : Mar 2, 2012 + * Updated : April 18, 2016 * ---------------------------------------------------------------------------- */ +#include #include "TestString.h" -#include "ibex_String.h" using namespace std; @@ -30,4 +31,38 @@ void TestString::test02() { free(buf); } +bool TestString::testConversion(const Interval& intv, int precision) +{ + return testConversionString(intv) && testConversionOstream(intv, precision); +} + +bool TestString::testConversionString(const Interval& intv) +{ + Interval intv_parsed = Interval(" " + intv + " "); // adding unwanted spaces + return intv_parsed == intv || + fabs(intv_parsed.lb() - intv.lb()) < 1.0e-1 && fabs(intv_parsed.ub() - intv.ub()) < 1.0e-1; +} + +bool TestString::testConversionOstream(const Interval& intv, int precision) +{ + stringstream sstream; + sstream << setprecision(precision) << " " << intv << " "; // adding unwanted spaces + Interval intv_parsed = Interval(sstream.str()); + return intv_parsed == intv || + fabs(intv_parsed.lb() - intv.lb()) < 1.0e-1 && fabs(intv_parsed.ub() - intv.ub()) < 1.0e-1; +} + +void TestString::test03() { + CPPUNIT_ASSERT(testConversion(Interval(-6.3588151,2.864632), 4)); + CPPUNIT_ASSERT(testConversion(Interval(0,27885.5523), 15)); + CPPUNIT_ASSERT(testConversion(Interval(-99,-97), 7)); + CPPUNIT_ASSERT(testConversion(Interval::EMPTY_SET, 4)); + CPPUNIT_ASSERT(testConversion(Interval::ALL_REALS, 4)); + CPPUNIT_ASSERT(testConversion(Interval::ZERO, 4)); + CPPUNIT_ASSERT(testConversion(Interval::PI, 4)); + CPPUNIT_ASSERT(testConversion(Interval::ONE, 3)); + CPPUNIT_ASSERT(testConversion(Interval::POS_REALS, 3)); + CPPUNIT_ASSERT(testConversion(Interval::NEG_REALS, 3)); +} + } // end namespace diff --git a/tests/TestString.h b/tests/TestString.h index 42e2342a9..e40f77fa1 100644 --- a/tests/TestString.h +++ b/tests/TestString.h @@ -5,8 +5,9 @@ * License : This program can be distributed under the terms of the GNU LGPL. * See the file COPYING.LESSER. * - * Author(s) : Gilles Chabert + * Author(s) : Gilles Chabert, Simon Rohou * Created : Mar 2, 2012 + * Updated : April 18, 2016 * ---------------------------------------------------------------------------- */ #ifndef __TEST_STRING_H__ @@ -25,13 +26,21 @@ class TestString : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestString); - CPPUNIT_TEST(test01); CPPUNIT_TEST(test02); + CPPUNIT_TEST(test03); + CPPUNIT_TEST_SUITE_END(); void test01(); void test02(); + void test03(); + +protected: + + bool testConversion(const Interval& intv, int precision); + bool testConversionString(const Interval& intv); + bool testConversionOstream(const Interval& intv, int precision); }; CPPUNIT_TEST_SUITE_REGISTRATION(TestString);