? GiNaC.spec ? Makefile ? Makefile.in ? aclocal.m4 ? config.h ? config.h.in ? config.log ? config.status ? configure ? ginac-config ? ginac-config.1 ? libtool ? stamp-h ? stamp-h.in ? stamp-h1 ? check/.deps ? check/.libs ? check/Makefile ? check/Makefile.in ? check/checks ? check/checks.out ? check/exam.gar ? check/exams ? check/exams.out ? check/times ? check/times.out ? doc/Makefile ? doc/Makefile.in ? doc/reference/Makefile ? doc/reference/Makefile.in ? doc/tutorial/Makefile ? doc/tutorial/Makefile.in ? ginac/.deps ? ginac/.libs ? ginac/Makefile ? ginac/Makefile.in ? ginac/exprseq.cpp ? ginac/exprseq.h ? ginac/function.cpp ? ginac/function.h ? ginac/input_lexer.cc ? ginac/input_parser.cc ? ginac/input_parser.h ? ginac/libginac.la ? ginac/lst.cpp ? ginac/lst.h ? ginac/version.h ? ginsh/.deps ? ginsh/Makefile ? ginsh/Makefile.in ? ginsh/ginsh.1 ? ginsh/ginsh_fcn_help.h ? ginsh/ginsh_op_help.h ? ginsh/ginsh_parser.cc ? ginsh/ginsh_parser.h ? tools/.deps ? tools/Makefile ? tools/Makefile.in ? tools/viewgar.1 Index: ginac/relational.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/relational.cpp,v retrieving revision 1.40 diff -c -3 -p -r1.40 relational.cpp *** ginac/relational.cpp 2001/10/27 16:18:57 1.40 --- ginac/relational.cpp 2001/11/14 17:39:56 *************** ex relational::rhs(void) const *** 233,263 **** // non-virtual functions in this class ////////// /** Cast the relational into a boolean, mainly for evaluation within an * if-statement. Note that (a=b) == true in * the general symbolic case. A false result means the comparison is either * false or undecidable (except of course for !=, where true means either * unequal or undecidable). */ ! relational::operator bool() const { const ex df = lh-rh; if (!is_ex_exactly_of_type(df,numeric)) // cannot decide on non-numerical results ! return o==not_equal ? true : false; switch (o) { case equal: ! return ex_to(df).is_zero(); case not_equal: ! return !ex_to(df).is_zero(); case less: ! return ex_to(df)<_num0; case less_or_equal: ! return ex_to(df)<=_num0; case greater: ! return ex_to(df)>_num0; case greater_or_equal: ! return ex_to(df)>=_num0; default: throw(std::logic_error("invalid relational operator")); } --- 233,270 ---- // non-virtual functions in this class ////////// + relational::safe_bool relational::make_safe_bool(bool cond) const + { + return cond? &safe_bool_helper::nonnull + : 0; + } + /** Cast the relational into a boolean, mainly for evaluation within an * if-statement. Note that (a=b) == true in * the general symbolic case. A false result means the comparison is either * false or undecidable (except of course for !=, where true means either * unequal or undecidable). */ ! relational::operator relational::safe_bool() const { const ex df = lh-rh; if (!is_ex_exactly_of_type(df,numeric)) // cannot decide on non-numerical results ! return o==not_equal ? make_safe_bool(true) ! : make_safe_bool(false); switch (o) { case equal: ! return make_safe_bool(ex_to(df).is_zero()); case not_equal: ! return make_safe_bool(!ex_to(df).is_zero()); case less: ! return make_safe_bool(ex_to(df)<_num0); case less_or_equal: ! return make_safe_bool(ex_to(df)<=_num0); case greater: ! return make_safe_bool(ex_to(df)>_num0); case greater_or_equal: ! return make_safe_bool(ex_to(df)>=_num0); default: throw(std::logic_error("invalid relational operator")); } Index: ginac/relational.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/relational.h,v retrieving revision 1.33 diff -c -3 -p -r1.33 relational.h *** ginac/relational.h 2001/08/22 16:11:51 1.33 --- ginac/relational.h 2001/11/14 17:39:56 *************** public: *** 70,78 **** virtual ex rhs(void) const; // non-virtual functions in this class public: ! operator bool(void) const; ! // member variables protected: --- 70,93 ---- virtual ex rhs(void) const; // non-virtual functions in this class + + private: + // for conversions to boolean, as would be used in an if conditional, + // implicit conversions from bool to int have a large number of + // undesirable side effects. The following safe_bool type enables + // use of relational objects in conditionals without those side effects + struct safe_bool_helper { + void nonnull() {}; + }; + + typedef void (safe_bool_helper::*safe_bool)(); + + safe_bool make_safe_bool(bool) const; + public: ! operator safe_bool(void) const; ! safe_bool operator!(void) const; ! // member variables protected: *************** protected: *** 87,92 **** --- 102,113 ---- template<> inline bool is_exactly_a(const basic & obj) { return obj.tinfo()==TINFO_relational; + } + + // inlined functions for efficiency + inline relational::safe_bool relational::operator!() const + { + return make_safe_bool(!static_cast(*this)); } } // namespace GiNaC