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