]> www.ginac.de Git - ginac.git/blob - ginac/expair.h
- added find() (like has(), but returns list of all occurrences)
[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-2001 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                 os << "expair:";
88                 print_tree c(os);
89                 rest.print(c, c.delta_indent);
90                 coeff.print(c, c.delta_indent);
91         }
92         
93         /** True if this is of the form (numeric,ex(1)). */
94         bool is_canonical_numeric(void) const
95         {
96                 GINAC_ASSERT(is_exactly_a<numeric>(coeff));
97                 return (is_ex_exactly_of_type(rest,numeric) &&
98                         (coeff.is_equal(1)));
99         }
100
101         /** Swap contents with other expair. */
102         void swap(expair & other)
103         {
104                 rest.swap(other.rest);
105                 coeff.swap(other.coeff);
106         }
107         
108         ex rest;    ///< first member of pair, an arbitrary expression
109         ex coeff;   ///< second member of pair, must be numeric
110 };
111
112 /** Function objects for insertion into third argument of STL's sort() etc. */
113 struct expair_is_less : public std::binary_function<expair, expair, bool> {
114         bool operator()(const expair &lh, const expair &rh) const { return lh.is_less(rh); }
115 };
116
117 struct expair_swap : public std::binary_function<expair, expair, void> {
118         void operator()(expair &lh, expair &rh) const { lh.swap(rh); }
119 };
120
121 } // namespace GiNaC
122
123 #endif // ndef __GINAC_EXPAIR_H__