]> www.ginac.de Git - ginac.git/commitdiff
* Apply safe-bool patch.
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sun, 27 Jan 2002 17:35:11 +0000 (17:35 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sun, 27 Jan 2002 17:35:11 +0000 (17:35 +0000)
configure.ac
ginac/relational.cpp
ginac/relational.h

index a964af10e775de3ea4904e54c00bf82dd06d7fbc..0c74e5dbc4efe5022662891699f3e007c981b040 100644 (file)
@@ -19,10 +19,10 @@ dnl autoconf sees "AC_MAJOR_VERSION" and complains about an undefined macro
 dnl (don't we all *love* M4?)...
 
 GINACLIB_MAJOR_VERSION=1
-GINACLIB_MINOR_VERSION=0
-GINACLIB_MICRO_VERSION=4
-GINACLIB_INTERFACE_AGE=2
-GINACLIB_BINARY_AGE=4
+GINACLIB_MINOR_VERSION=1
+GINACLIB_MICRO_VERSION=0
+GINACLIB_INTERFACE_AGE=0
+GINACLIB_BINARY_AGE=0
 GINACLIB_VERSION=$GINACLIB_MAJOR_VERSION.$GINACLIB_MINOR_VERSION.$GINACLIB_MICRO_VERSION
 
 AC_SUBST(GINACLIB_MAJOR_VERSION)
index 158c41617fc812f0bb7dab4529b86ed1857d0362..3482f9096cc574d870754ea90e467c8fd1266e98 100644 (file)
@@ -305,31 +305,36 @@ ex relational::rhs(void) const
 // non-virtual functions in this class
 //////////
 
-/** Cast the relational into a boolean, mainly for evaluation within an 
+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) == false does not imply (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
+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 ? true : false;
-       
+               return o==not_equal ? make_safe_bool(true) : make_safe_bool(false);
+
        switch (o) {
                case equal:
-                       return ex_to<numeric>(df).is_zero();
+                       return make_safe_bool(ex_to<numeric>(df).is_zero());
                case not_equal:
-                       return !ex_to<numeric>(df).is_zero();
+                       return make_safe_bool(!ex_to<numeric>(df).is_zero());
                case less:
-                       return ex_to<numeric>(df)<_num0;
+                       return make_safe_bool(ex_to<numeric>(df)<_num0);
                case less_or_equal:
-                       return ex_to<numeric>(df)<=_num0;
+                       return make_safe_bool(ex_to<numeric>(df)<=_num0);
                case greater:
-                       return ex_to<numeric>(df)>_num0;
+                       return make_safe_bool(ex_to<numeric>(df)>_num0);
                case greater_or_equal:
-                       return ex_to<numeric>(df)>=_num0;
+                       return make_safe_bool(ex_to<numeric>(df)>=_num0);
                default:
                        throw(std::logic_error("invalid relational operator"));
        }
index 089b931051d7167baaf09a1f8ed3b8ed2c573228..0062a753832be9cc13edccaa79b22f1f0917713f 100644 (file)
@@ -71,9 +71,23 @@ public:
        virtual ex rhs(void) const;
 
        // non-virtual functions in this class
-public:
-       operator bool(void) const;
+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:
@@ -90,6 +104,12 @@ template<> inline bool is_exactly_a<relational>(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<bool>(*this));
+}
+
 } // namespace GiNaC
 
 #endif // ndef __GINAC_RELATIONAL_H__