- ASSERT macro renamed to GINAC_ASSERT
[ginac.git] / ginac / indexed.cpp
1 /** @file indexed.cpp
2  *
3  *  Implementation of GiNaC's index carrying objects. */
4
5 /*
6  *  GiNaC Copyright (C) 1999 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 #include <string>
24
25 #include "indexed.h"
26 #include "ex.h"
27 #include "idx.h"
28 #include "debugmsg.h"
29
30 namespace GiNaC {
31
32 //////////
33 // default constructor, destructor, copy constructor assignment operator and helpers
34 //////////
35
36 // public
37
38 indexed::indexed()
39 {
40     debugmsg("indexed default constructor",LOGLEVEL_CONSTRUCT);
41     tinfo_key=TINFO_indexed;
42 }
43
44 indexed::~indexed()
45 {
46     debugmsg("indexed destructor",LOGLEVEL_DESTRUCT);
47     destroy(0);
48 }
49
50 indexed::indexed(indexed const & other)
51 {
52     debugmsg("indexed copy constructor",LOGLEVEL_CONSTRUCT);
53     copy (other);
54 }
55
56 indexed const & indexed::operator=(indexed const & other)
57 {
58     debugmsg("indexed operator=",LOGLEVEL_ASSIGNMENT);
59     if (this != &other) {
60         destroy(1);
61         copy(other);
62     }
63     return *this;
64 }
65
66 // protected
67
68 void indexed::copy(indexed const & other)
69 {
70     exprseq::copy(other);
71 }
72
73 void indexed::destroy(bool call_parent)
74 {
75     if (call_parent) {
76         exprseq::destroy(call_parent);
77     }
78 }
79
80 //////////
81 // other constructors
82 //////////
83
84 // public
85
86 indexed::indexed(ex const & i1) : exprseq(i1)
87 {
88     debugmsg("indexed constructor from ex",LOGLEVEL_CONSTRUCT);
89     tinfo_key=TINFO_indexed;
90     GINAC_ASSERT(all_of_type_idx());
91 }
92
93 indexed::indexed(ex const & i1, ex const & i2) : exprseq(i1,i2)
94 {
95     debugmsg("indexed constructor from ex,ex",LOGLEVEL_CONSTRUCT);
96     tinfo_key=TINFO_indexed;
97     GINAC_ASSERT(all_of_type_idx());
98 }
99
100 indexed::indexed(ex const & i1, ex const & i2, ex const & i3)
101     : exprseq(i1,i2,i3)
102 {
103     debugmsg("indexed constructor from ex,ex,ex",LOGLEVEL_CONSTRUCT);
104     tinfo_key=TINFO_indexed;
105     GINAC_ASSERT(all_of_type_idx());
106 }
107
108 indexed::indexed(exvector const & iv) : exprseq(iv)
109 {
110     debugmsg("indexed constructor from exvector",LOGLEVEL_CONSTRUCT);
111     tinfo_key=TINFO_indexed;
112     GINAC_ASSERT(all_of_type_idx());
113 }
114
115 indexed::indexed(exvector * ivp) : exprseq(ivp)
116 {
117     debugmsg("indexed constructor from exvector *",LOGLEVEL_CONSTRUCT);
118     tinfo_key=TINFO_indexed;
119     GINAC_ASSERT(all_of_type_idx());
120 }
121
122 //////////
123 // functions overriding virtual functions from bases classes
124 //////////
125
126 // public
127
128 basic * indexed::duplicate() const
129 {
130     debugmsg("indexed duplicate",LOGLEVEL_DUPLICATE);
131     return new indexed(*this);
132 }
133
134 void indexed::printraw(ostream & os) const
135 {
136     debugmsg("indexed printraw",LOGLEVEL_PRINT);
137     os << "indexed(indices=";
138     printrawindices(os);
139     os << ",hash=" << hashvalue << ",flags=" << flags << ")";
140 }
141
142 void indexed::printtree(ostream & os, unsigned indent) const
143 {
144     debugmsg("indexed printtree",LOGLEVEL_PRINT);
145     os << string(indent,' ') << "indexed: " << seq.size() << " indices";
146     os << ",hash=" << hashvalue << ",flags=" << flags << endl;
147     printtreeindices(os,indent);
148 }
149
150 void indexed::print(ostream & os, unsigned upper_precedence) const
151 {
152     debugmsg("indexed print",LOGLEVEL_PRINT);
153     os << "UNNAMEDINDEX";
154     printindices(os);
155 }
156
157 void indexed::printcsrc(ostream & os, unsigned type,
158                         unsigned upper_precedence) const
159 {
160     debugmsg("indexed print csrc",LOGLEVEL_PRINT);
161     print(os,upper_precedence);
162 }
163
164 bool indexed::info(unsigned inf) const
165 {
166     if (inf==info_flags::indexed) return true;
167     if (inf==info_flags::has_indices) return seq.size()!=0;
168     return exprseq::info(inf);
169 }
170
171 exvector indexed::get_indices(void) const
172 {
173     return seq;
174
175     /*
176     idxvector filtered_indices;
177     filtered_indices.reserve(indices.size());
178     for (idxvector::const_iterator cit=indices.begin(); cit!=indices.end(); ++cit) {
179         if ((*cit).get_type()==t) {
180             filtered_indices.push_back(*cit);
181         }
182     }
183     return filtered_indices;
184     */
185 }
186
187 // protected
188
189 int indexed::compare_same_type(basic const & other) const
190 {
191     GINAC_ASSERT(is_of_type(other,indexed));
192     return exprseq::compare_same_type(other);
193 }
194
195 bool indexed::is_equal_same_type(basic const & other) const
196 {
197     GINAC_ASSERT(is_of_type(other,indexed));
198     return exprseq::is_equal_same_type(other);
199 }
200
201 unsigned indexed::return_type(void) const
202 {
203     return return_types::noncommutative;
204 }
205    
206 unsigned indexed::return_type_tinfo(void) const
207 {
208     return tinfo_key;
209 }
210
211 ex indexed::thisexprseq(exvector const & v) const
212 {
213     return indexed(v);
214 }
215
216 ex indexed::thisexprseq(exvector * vp) const
217 {
218     return indexed(vp);
219 }
220
221 //////////
222 // virtual functions which can be overridden by derived classes
223 //////////
224
225 // none
226
227 //////////
228 // non-virtual functions in this class
229 //////////
230
231 // protected
232
233 void indexed::printrawindices(ostream & os) const
234 {
235     if (seq.size()!=0) {
236         for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
237             (*cit).printraw(os);
238             os << ",";
239         }
240     }
241 }
242
243 void indexed::printtreeindices(ostream & os, unsigned indent) const
244 {
245     if (seq.size()!=0) {
246         for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
247             os << string(indent+delta_indent,' ');
248             (*cit).printraw(os);
249             os << endl;
250         }
251     }
252 }
253
254 void indexed::printindices(ostream & os) const
255 {
256     if (seq.size()!=0) {
257         if (seq.size()>1) {
258             os << "{";
259         }
260         exvector::const_iterator last=seq.end()-1;
261         exvector::const_iterator cit=seq.begin();
262         for (; cit!=last; ++cit) {
263             (*cit).print(os);
264             os << ",";
265         }
266         (*cit).print(os);
267         if (seq.size()>1) {
268             os << "}";
269         }
270     }
271 }
272
273 bool indexed::all_of_type_idx(void) const
274 {
275     // used only inside of ASSERTs
276     for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
277         if (!is_ex_of_type(*cit,idx)) return false;
278     }
279     return true;
280 }
281
282 //////////
283 // static member variables
284 //////////
285
286 // none
287
288 //////////
289 // global constants
290 //////////
291
292 const indexed some_indexed;
293 type_info const & typeid_indexed=typeid(some_indexed);
294
295 } // namespace GiNaC