3 * Definition of expression pairs (building blocks of expairseq). */
6 * GiNaC Copyright (C) 1999-2007 Johannes Gutenberg University Mainz, Germany
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #ifndef __GINAC_EXPAIR_H__
24 #define __GINAC_EXPAIR_H__
32 /** A pair of expressions.
33 * This is similar to STL's pair<>. It is slightly extended since we need to
34 * account for methods like .compare(). Also, since this is meant for use by
35 * class expairseq it must satisfy the invariance that the member coeff must
36 * be of type numeric. */
40 expair() : rest(0), coeff(1) { }
42 /** Construct an expair from two ex. */
43 expair(const ex & r, const ex & c) : rest(r), coeff(c)
45 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
48 /** Member-wise check for canonical ordering equality. */
49 bool is_equal(const expair & other) const
51 return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
54 /** Member-wise check for canonical ordering lessness. */
55 bool is_less(const expair & other) const
57 int restcmp = rest.compare(other.rest);
58 return ((restcmp<0) ||
59 (!(restcmp>0) && (coeff.compare(other.coeff)<0)));
62 /** Member-wise check for canonical ordering. */
63 int compare(const expair & other) const
65 int restcmp = rest.compare(other.rest);
69 return coeff.compare(other.coeff);
72 void print(std::ostream & os) const;
74 /** True if this is of the form (numeric,ex(1)). */
75 bool is_canonical_numeric() const
77 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
78 return (is_exactly_a<numeric>(rest) && (coeff.is_equal(1)));
81 /** Swap contents with other expair. */
82 void swap(expair & other)
84 rest.swap(other.rest);
85 coeff.swap(other.coeff);
88 const expair conjugate() const;
90 ex rest; ///< first member of pair, an arbitrary expression
91 ex coeff; ///< second member of pair, must be numeric
94 /** Function object for insertion into third argument of STL's sort() etc. */
95 struct expair_is_less : public std::binary_function<expair, expair, bool> {
96 bool operator()(const expair &lh, const expair &rh) const { return lh.is_less(rh); }
99 /** Function object not caring about the numerical coefficients for insertion
100 * into third argument of STL's sort(). Note that this does not define a
101 * strict weak ordering since for any symbol x we have neither 3*x<2*x or
102 * 2*x<3*x. Handle with care! */
103 struct expair_rest_is_less : public std::binary_function<expair, expair, bool> {
104 bool operator()(const expair &lh, const expair &rh) const { return (lh.rest.compare(rh.rest)<0); }
107 struct expair_swap : public std::binary_function<expair, expair, void> {
108 void operator()(expair &lh, expair &rh) const { lh.swap(rh); }
111 inline void swap(expair & e1, expair & e2)
114 // This makes STL algorithms use the more efficient swap operation for ex objects
115 inline void iter_swap(std::vector<expair>::iterator i1, std::vector<expair>::iterator i2)
120 #endif // ndef __GINAC_EXPAIR_H__