3 // Cassowary Incremental Constraint Solver
4 // Original Smalltalk Implementation by Alan Borning
5 // This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
6 // http://www.cs.washington.edu/homes/gjb
7 // (C) 1998, 1999 Greg J. Badros and Alan Borning
8 // See ../LICENSE for legal details regarding this software
12 #ifndef ClSymbolicWeight_H
13 #define ClSymbolicWeight_H
15 #if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
16 #include <cassowary/config-inline.h>
17 #define CONFIG_INLINE_H_INCLUDED
20 #include "Cassowary.h"
28 class ClSymbolicWeight {
30 ClSymbolicWeight(unsigned int CLevels = 3, Number value = 0.0);
32 ClSymbolicWeight(Number w1, Number w2, Number w3);
34 ClSymbolicWeight(const vector<Number> &weights);
36 static ClSymbolicWeight &Zero();
38 ClSymbolicWeight &negated();
40 ClSymbolicWeight &MultiplyMe(Number n);
42 ClSymbolicWeight Times(Number n) const
43 { ClSymbolicWeight cl = *this; cl.MultiplyMe(n); return cl; }
45 ClSymbolicWeight DivideBy(Number n) const;
47 ClSymbolicWeight &addtoMe(const ClSymbolicWeight &cl);
49 ClSymbolicWeight Add(const ClSymbolicWeight &cl) const
50 { ClSymbolicWeight clRet = *this; clRet.addtoMe(cl); return clRet; }
52 ClSymbolicWeight Subtract(const ClSymbolicWeight &cl) const;
54 ClSymbolicWeight operator*(const Number &n) const
57 ClSymbolicWeight operator/(const Number &n) const
58 { return DivideBy(n); }
60 // FIXGJB: can we express this statically?
61 ClSymbolicWeight operator*(ClSymbolicWeight &w) const
62 { throw ExCLInternalError("Multiplication of symbolic weights encountered");
64 ClSymbolicWeight &operator*=(ClSymbolicWeight &w)
65 { throw ExCLInternalError("Multiplicative assignment of symbolic weights encountered");
68 // FIXGJB: can we express this statically?
69 ClSymbolicWeight operator-() const
70 { throw ExCLInternalError("Can not negate a symbolic weight");
71 return ClSymbolicWeight::Zero(); }
73 friend ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &);
75 ClSymbolicWeight &operator*=(const Number &n)
76 { return MultiplyMe(n); }
78 ClSymbolicWeight operator+(const ClSymbolicWeight &cl) const
81 ClSymbolicWeight operator+=(const ClSymbolicWeight &cl)
82 { return addtoMe(cl); }
84 ClSymbolicWeight operator*(const Number &n)
85 { ClSymbolicWeight answer(*this);
89 bool lessThan(const ClSymbolicWeight &cl) const;
90 bool lessThanOrEqual(const ClSymbolicWeight &cl) const;
91 bool equal(const ClSymbolicWeight &cl) const;
92 bool greaterThan(const ClSymbolicWeight &cl) const;
93 bool greaterThanOrEqual(const ClSymbolicWeight &cl) const;
94 bool isNegative() const;
96 friend bool operator==(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
97 { return cl1.equal(cl2); }
99 friend bool operator!=(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
100 { return !(cl1 == cl2); }
102 friend bool operator<(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
103 { return cl1.lessThan(cl2); }
105 friend bool operator>(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
106 { return (cl2 < cl1); }
108 // function.h provides operator>, >=, <= from operator<
110 double AsDouble() const
112 vector<Number>::const_reverse_iterator i = _values.rbegin();
115 // A. Beurive' Wed Jul 7 11:07:47 CEST 1999
116 Number multiplier = 1000000;
117 for ( ; i != _values.rend(); ++i)
120 factor *= multiplier;
126 ostream &PrintOn(ostream &xo) const
128 vector<Number>::const_iterator i = _values.begin();
129 if (i == _values.end())
133 for (++i; i != _values.end(); ++i)
140 // FIXGJB: use a template function to generate these automatically
141 friend ostream& operator<<(ostream &xos, const ClSymbolicWeight &clsw)
142 { clsw.PrintOn(xos); return xos; }
146 { return _values.size(); }
148 friend bool ClApprox(const ClSymbolicWeight &cl, Number n);
149 friend bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2);
152 vector<Number> _values;
154 void push_back(Number d)
155 { _values.push_back(d); }
159 inline bool ClApprox(const ClSymbolicWeight &cl, Number n)
161 vector<Number>::const_iterator it = cl._values.begin();
162 if (!ClApprox(*it,n))
166 for (; it != cl._values.end(); ++it)
168 if (!ClApprox(*it,0))
175 inline bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
177 vector<Number>::const_iterator it1 = cl1._values.begin();
178 vector<Number>::const_iterator it2 = cl2._values.begin();
180 for (; it1 != cl1._values.end() && it2 != cl2._values.end();
183 if (!ClApprox(*it1,*it2))
187 if (it1 == cl1._values.end() && it2 == cl2._values.end())
193 inline ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &)
194 { throw(ExCLInternalError("Cannot take ReciprocalOf symbolic weight"));
195 return ClSymbolicWeight::Zero(); }