]> www.ginac.de Git - ginac.git/blob - ginac/expair.h
Fixed section chaining.
[ginac.git] / ginac / expair.h
1 /** @file expair.h
2  *
3  *  Definition of expression pairs (building blocks of expairseq). */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2004 Johannes Gutenberg University Mainz, Germany
7  *
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.
12  *
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.
17  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #ifndef __GINAC_EXPAIR_H__
24 #define __GINAC_EXPAIR_H__
25
26 #include "ex.h"
27 #include "numeric.h"
28 #include "print.h"
29
30 namespace GiNaC {
31
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. */
37 class expair
38 {
39 public:
40         expair() : rest(0), coeff(1) { }
41
42         /** Construct an expair from two ex. */
43         expair(const ex & r, const ex & c) : rest(r), coeff(c)
44         {
45                 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
46         }
47         
48         /** Member-wise check for canonical ordering equality. */
49         bool is_equal(const expair & other) const
50         {
51                 return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
52         }
53         
54         /** Member-wise check for canonical ordering lessness. */
55         bool is_less(const expair & other) const 
56         {
57                 int restcmp = rest.compare(other.rest);
58                 return ((restcmp<0) ||
59                         (!(restcmp>0) && (coeff.compare(other.coeff)<0)));
60         }
61         
62         /** Member-wise check for canonical ordering. */
63         int compare(const expair & other) const
64         {
65                 int restcmp = rest.compare(other.rest);
66                 if (restcmp!=0)
67                         return restcmp;
68                 else
69                         return coeff.compare(other.coeff);
70         }
71         
72         void print(std::ostream & os) const;
73         
74         /** True if this is of the form (numeric,ex(1)). */
75         bool is_canonical_numeric() const
76         {
77                 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
78                 return (is_exactly_a<numeric>(rest) && (coeff.is_equal(1)));
79         }
80
81         /** Swap contents with other expair. */
82         void swap(expair & other)
83         {
84                 rest.swap(other.rest);
85                 coeff.swap(other.coeff);
86         }
87
88         const expair conjugate() const;
89
90         ex rest;    ///< first member of pair, an arbitrary expression
91         ex coeff;   ///< second member of pair, must be numeric
92 };
93
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); }
97 };
98
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); }
105 };
106
107 struct expair_swap : public std::binary_function<expair, expair, void> {
108         void operator()(expair &lh, expair &rh) const { lh.swap(rh); }
109 };
110
111 inline void swap(expair & e1, expair & e2)
112 { e1.swap(e2); }
113
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)
116 { i1->swap(*i2); }
117
118 } // namespace GiNaC
119
120 #endif // ndef __GINAC_EXPAIR_H__