summaryrefslogtreecommitdiff
path: root/libs/cassowary/cassowary/ClSymbolicWeight.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cassowary/cassowary/ClSymbolicWeight.h')
-rw-r--r--libs/cassowary/cassowary/ClSymbolicWeight.h197
1 files changed, 197 insertions, 0 deletions
diff --git a/libs/cassowary/cassowary/ClSymbolicWeight.h b/libs/cassowary/cassowary/ClSymbolicWeight.h
new file mode 100644
index 0000000000..1c0339c887
--- /dev/null
+++ b/libs/cassowary/cassowary/ClSymbolicWeight.h
@@ -0,0 +1,197 @@
+// $Id$
+//
+// Cassowary Incremental Constraint Solver
+// Original Smalltalk Implementation by Alan Borning
+// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
+// http://www.cs.washington.edu/homes/gjb
+// (C) 1998, 1999 Greg J. Badros and Alan Borning
+// See ../LICENSE for legal details regarding this software
+//
+// ClSymbolicWeight.h
+
+#ifndef ClSymbolicWeight_H
+#define ClSymbolicWeight_H
+
+#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
+#include <cassowary/config-inline.h>
+#define CONFIG_INLINE_H_INCLUDED
+#endif
+
+#include "Cassowary.h"
+#include "ClErrors.h"
+#include <vector>
+#include <iostream>
+
+using std::vector;
+using std::ostream;
+
+class ClSymbolicWeight {
+ public:
+ ClSymbolicWeight(unsigned int CLevels = 3, Number value = 0.0);
+
+ ClSymbolicWeight(Number w1, Number w2, Number w3);
+
+ ClSymbolicWeight(const vector<Number> &weights);
+
+ static ClSymbolicWeight &Zero();
+
+ ClSymbolicWeight &negated();
+
+ ClSymbolicWeight &MultiplyMe(Number n);
+
+ ClSymbolicWeight Times(Number n) const
+ { ClSymbolicWeight cl = *this; cl.MultiplyMe(n); return cl; }
+
+ ClSymbolicWeight DivideBy(Number n) const;
+
+ ClSymbolicWeight &addtoMe(const ClSymbolicWeight &cl);
+
+ ClSymbolicWeight Add(const ClSymbolicWeight &cl) const
+ { ClSymbolicWeight clRet = *this; clRet.addtoMe(cl); return clRet; }
+
+ ClSymbolicWeight Subtract(const ClSymbolicWeight &cl) const;
+
+ ClSymbolicWeight operator*(const Number &n) const
+ { return Times(n); }
+
+ ClSymbolicWeight operator/(const Number &n) const
+ { return DivideBy(n); }
+
+ // FIXGJB: can we express this statically?
+ ClSymbolicWeight operator*(ClSymbolicWeight &w) const
+ { throw ExCLInternalError("Multiplication of symbolic weights encountered");
+ return w; }
+ ClSymbolicWeight &operator*=(ClSymbolicWeight &w)
+ { throw ExCLInternalError("Multiplicative assignment of symbolic weights encountered");
+ return w; }
+
+ // FIXGJB: can we express this statically?
+ ClSymbolicWeight operator-() const
+ { throw ExCLInternalError("Can not negate a symbolic weight");
+ return ClSymbolicWeight::Zero(); }
+
+ friend ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &);
+
+ ClSymbolicWeight &operator*=(const Number &n)
+ { return MultiplyMe(n); }
+
+ ClSymbolicWeight operator+(const ClSymbolicWeight &cl) const
+ { return Add(cl); }
+
+ ClSymbolicWeight operator+=(const ClSymbolicWeight &cl)
+ { return addtoMe(cl); }
+
+ ClSymbolicWeight operator*(const Number &n)
+ { ClSymbolicWeight answer(*this);
+ answer *= n;
+ return answer; }
+
+ bool lessThan(const ClSymbolicWeight &cl) const;
+ bool lessThanOrEqual(const ClSymbolicWeight &cl) const;
+ bool equal(const ClSymbolicWeight &cl) const;
+ bool greaterThan(const ClSymbolicWeight &cl) const;
+ bool greaterThanOrEqual(const ClSymbolicWeight &cl) const;
+ bool isNegative() const;
+
+ friend bool operator==(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
+ { return cl1.equal(cl2); }
+
+ friend bool operator!=(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
+ { return !(cl1 == cl2); }
+
+ friend bool operator<(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
+ { return cl1.lessThan(cl2); }
+
+ friend bool operator>(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
+ { return (cl2 < cl1); }
+
+ // function.h provides operator>, >=, <= from operator<
+
+ double AsDouble() const
+ {
+ vector<Number>::const_reverse_iterator i = _values.rbegin();
+ Number sum = 0;
+ Number factor = 1;
+ // A. Beurive' Wed Jul 7 11:07:47 CEST 1999
+ Number multiplier = 1000000;
+ for ( ; i != _values.rend(); ++i)
+ {
+ sum += *i * factor;
+ factor *= multiplier;
+ }
+ return sum;
+ }
+
+#ifndef CL_NO_IO
+ ostream &PrintOn(ostream &xo) const
+ {
+ vector<Number>::const_iterator i = _values.begin();
+ if (i == _values.end())
+ return xo;
+
+ xo << *i;
+ for (++i; i != _values.end(); ++i)
+ {
+ xo << "," << *i;
+ }
+ return xo;
+ }
+
+ // FIXGJB: use a template function to generate these automatically
+ friend ostream& operator<<(ostream &xos, const ClSymbolicWeight &clsw)
+ { clsw.PrintOn(xos); return xos; }
+#endif
+
+ int CLevels() const
+ { return _values.size(); }
+
+ friend bool ClApprox(const ClSymbolicWeight &cl, Number n);
+ friend bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2);
+
+ private:
+ vector<Number> _values;
+
+ void push_back(Number d)
+ { _values.push_back(d); }
+
+};
+
+inline bool ClApprox(const ClSymbolicWeight &cl, Number n)
+{
+ vector<Number>::const_iterator it = cl._values.begin();
+ if (!ClApprox(*it,n))
+ return false;
+
+ ++it;
+ for (; it != cl._values.end(); ++it)
+ {
+ if (!ClApprox(*it,0))
+ return false;
+ }
+
+ return true;
+}
+
+inline bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
+{
+ vector<Number>::const_iterator it1 = cl1._values.begin();
+ vector<Number>::const_iterator it2 = cl2._values.begin();
+
+ for (; it1 != cl1._values.end() && it2 != cl2._values.end();
+ ++it1, ++it2)
+ {
+ if (!ClApprox(*it1,*it2))
+ return false;
+ }
+
+ if (it1 == cl1._values.end() && it2 == cl2._values.end())
+ return true;
+
+ return false;
+}
+
+inline ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &)
+{ throw(ExCLInternalError("Cannot take ReciprocalOf symbolic weight"));
+ return ClSymbolicWeight::Zero(); }
+
+#endif