documentation update
[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-2002 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         ~expair() { }
42         expair(const expair & other) : rest(other.rest), coeff(other.coeff)
43         {
44                 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
45         }
46         const expair & operator=(const expair & other)
47         {
48                 if (this != &other) {
49                         rest = other.rest;
50                         coeff = other.coeff;
51                 }
52                 return *this;
53         }
54         
55         /** Construct an expair from two ex. */
56         expair(const ex & r, const ex & c) : rest(r), coeff(c)
57         {
58                 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
59         }
60         
61         /** Member-wise check for canonical ordering equality. */
62         bool is_equal(const expair & other) const
63         {
64                 return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
65         }
66         
67         /** Member-wise check for canonical ordering lessness. */
68         bool is_less(const expair & other) const 
69         {
70                 int restcmp = rest.compare(other.rest);
71                 return ((restcmp<0) ||
72                         (!(restcmp>0) && (coeff.compare(other.coeff)<0)));
73         }
74         
75         /** Member-wise check for canonical ordering. */
76         int compare(const expair & other) const
77         {
78                 int restcmp = rest.compare(other.rest);
79                 if (restcmp!=0)
80                         return restcmp;
81                 else
82                         return coeff.compare(other.coeff);
83         }
84         
85         void print(std::ostream & os) const;
86         
87         /** True if this is of the form (numeric,ex(1)). */
88         bool is_canonical_numeric(void) const
89         {
90                 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
91                 return (is_exactly_a<numeric>(rest) && (coeff.is_equal(1)));
92         }
93
94         /** Swap contents with other expair. */
95         void swap(expair & other)
96         {
97                 rest.swap(other.rest);
98                 coeff.swap(other.coeff);
99         }
100         
101         ex rest;    ///< first member of pair, an arbitrary expression
102         ex coeff;   ///< second member of pair, must be numeric
103 };
104
105 /** Function object for insertion into third argument of STL's sort() etc. */
106 struct expair_is_less : public std::binary_function<expair, expair, bool> {
107         bool operator()(const expair &lh, const expair &rh) const { return lh.is_less(rh); }
108 };
109
110 /** Function object not caring about the numerical coefficients for insertion
111  *  into third argument of STL's sort().  Note that this does not define a
112  *  strict weak ordering since for any symbol x we have neither 3*x<2*x or
113  *  2*x<3*x.  Handle with care! */
114 struct expair_rest_is_less : public std::binary_function<expair, expair, bool> {
115         bool operator()(const expair &lh, const expair &rh) const { return (lh.rest.compare(rh.rest)<0); }
116 };
117
118 struct expair_swap : public std::binary_function<expair, expair, void> {
119         void operator()(expair &lh, expair &rh) const { lh.swap(rh); }
120 };
121
122 inline void swap(expair & e1, expair & e2)
123 { e1.swap(e2); }
124
125 // This makes STL algorithms use the more efficient swap operation for ex objects
126 inline void iter_swap(std::vector<expair>::iterator i1, std::vector<expair>::iterator i2)
127 { i1->swap(*i2); }
128
129 } // namespace GiNaC
130
131 #endif // ndef __GINAC_EXPAIR_H__