]> www.ginac.de Git - ginac.git/blob - ginac/lst.cpp
- enforced GiNaC coding standards :-)
[ginac.git] / ginac / lst.cpp
1 /** @file lst.cpp
2  *
3  *  Implementation of GiNaC's lst. 
4  *  This file was generated automatically by container.pl.
5  *  Please do not modify it directly, edit the perl script instead!
6  *  container.pl options: $CONTAINER=lst
7  *                        $STLHEADER=list
8  *                        $reserve=0
9  *                        $prepend=1
10  *                        $let_op=1
11  *                        $open_bracket=[
12  *                        $close_bracket=]
13  *
14  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 2 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, write to the Free Software
28  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29  */
30
31 #include <iostream>
32 #include <stdexcept>
33
34 #include "ginac.h"
35
36 #define RESERVE(s,size) // no reserve needed for list
37
38 //////////
39 // default constructor, destructor, copy constructor assignment operator and helpers
40 //////////
41
42 // public
43
44 lst::lst() : basic(TINFO_LST)
45 {
46     debugmsg("lst default constructor",LOGLEVEL_CONSTRUCT);
47 }
48
49 lst::~lst()
50 {
51     debugmsg("lst destructor",LOGLEVEL_DESTRUCT);
52     destroy(0);
53 }
54
55 lst::lst(lst const & other)
56 {
57     debugmsg("lst copy constructor",LOGLEVEL_CONSTRUCT);
58     copy(other);
59 }
60
61 lst const & lst::operator=(lst const & other)
62 {
63     debugmsg("lst operator=",LOGLEVEL_ASSIGNMENT);
64     if (this != &other) {
65         destroy(1);
66         copy(other);
67     }
68     return *this;
69 }
70
71 // protected
72
73 void lst::copy(lst const & other)
74 {
75     basic::copy(other);
76     seq=other.seq;
77 }
78
79 void lst::destroy(bool call_parent)
80 {
81     seq.clear();
82     if (call_parent) basic::destroy(call_parent);
83 }
84
85 //////////
86 // other constructors
87 //////////
88
89 // public
90
91 lst::lst(exlist const & s, bool discardable) :  basic(TINFO_LST)
92 {
93     debugmsg("lst constructor from exlist",
94              LOGLEVEL_CONSTRUCT);
95     if (discardable) {
96         seq.swap(const_cast<exlist &>(s));
97     } else {
98         seq=s;
99     }
100 }
101
102 lst::lst(exlist * vp) : basic(TINFO_LST)
103 {
104     debugmsg("lst constructor from exlist *",LOGLEVEL_CONSTRUCT);
105     ASSERT(vp!=0);
106     seq.swap(*vp);
107     delete vp;
108 }
109
110 lst::lst(ex const & e1) :  basic(TINFO_LST)
111 {
112     debugmsg("lst constructor from 1 ex",
113              LOGLEVEL_CONSTRUCT);
114     RESERVE(seq,1);
115     seq.push_back(e1);
116 }
117
118 lst::lst(ex const & e1, ex const & e2) : basic(TINFO_LST)
119 {
120     debugmsg("lst constructor from 2 ex",
121              LOGLEVEL_CONSTRUCT);
122     RESERVE(seq,2);
123     seq.push_back(e1);
124     seq.push_back(e2);
125 }
126
127 lst::lst(ex const & e1, ex const & e2, ex const & e3)
128     : basic(TINFO_LST)
129 {
130     debugmsg("lst constructor from 3 ex",
131              LOGLEVEL_CONSTRUCT);
132     RESERVE(seq,3);
133     seq.push_back(e1);
134     seq.push_back(e2);
135     seq.push_back(e3);
136 }
137
138 lst::lst(ex const & e1, ex const & e2, ex const & e3,
139                      ex const & e4) : basic(TINFO_LST)
140 {
141     debugmsg("lst constructor from 4 ex",
142              LOGLEVEL_CONSTRUCT);
143     RESERVE(seq,4);
144     seq.push_back(e1);
145     seq.push_back(e2);
146     seq.push_back(e3);
147     seq.push_back(e4);
148 }
149
150 lst::lst(ex const & e1, ex const & e2, ex const & e3,
151                      ex const & e4, ex const & e5) : basic(TINFO_LST)
152 {
153     debugmsg("lst constructor from 5 ex",
154              LOGLEVEL_CONSTRUCT);
155     RESERVE(seq,5);
156     seq.push_back(e1);
157     seq.push_back(e2);
158     seq.push_back(e3);
159     seq.push_back(e4);
160     seq.push_back(e5);
161 }
162
163 lst::lst(ex const & e1, ex const & e2, ex const & e3,
164                      ex const & e4, ex const & e5, ex const & e6)
165     : basic(TINFO_LST)
166 {
167     debugmsg("lst constructor from 6 ex",
168              LOGLEVEL_CONSTRUCT);
169     RESERVE(seq,6);
170     seq.push_back(e1);
171     seq.push_back(e2);
172     seq.push_back(e3);
173     seq.push_back(e4);
174     seq.push_back(e5);
175     seq.push_back(e6);
176 }
177
178 lst::lst(ex const & e1, ex const & e2, ex const & e3,
179                      ex const & e4, ex const & e5, ex const & e6,
180                      ex const & e7) : basic(TINFO_LST)
181 {
182     debugmsg("lst constructor from 7 ex",
183              LOGLEVEL_CONSTRUCT);
184     RESERVE(seq,7);
185     seq.push_back(e1);
186     seq.push_back(e2);
187     seq.push_back(e3);
188     seq.push_back(e4);
189     seq.push_back(e5);
190     seq.push_back(e6);
191     seq.push_back(e7);
192 }
193
194 lst::lst(ex const & e1, ex const & e2, ex const & e3,
195                      ex const & e4, ex const & e5, ex const & e6,
196                      ex const & e7, ex const & e8) : basic(TINFO_LST)
197 {
198     debugmsg("lst constructor from 8 ex",
199              LOGLEVEL_CONSTRUCT);
200     RESERVE(seq,8);
201     seq.push_back(e1);
202     seq.push_back(e2);
203     seq.push_back(e3);
204     seq.push_back(e4);
205     seq.push_back(e5);
206     seq.push_back(e6);
207     seq.push_back(e7);
208     seq.push_back(e8);
209 }
210
211 lst::lst(ex const & e1, ex const & e2, ex const & e3,
212                      ex const & e4, ex const & e5, ex const & e6,
213                      ex const & e7, ex const & e8, ex const & e9)
214     : basic(TINFO_LST)
215 {
216     debugmsg("lst constructor from 9 ex",
217              LOGLEVEL_CONSTRUCT);
218     RESERVE(seq,9);
219     seq.push_back(e1);
220     seq.push_back(e2);
221     seq.push_back(e3);
222     seq.push_back(e4);
223     seq.push_back(e5);
224     seq.push_back(e6);
225     seq.push_back(e7);
226     seq.push_back(e8);
227     seq.push_back(e9);
228 }
229
230 lst::lst(ex const & e1, ex const & e2, ex const & e3,
231                      ex const & e4, ex const & e5, ex const & e6,
232                      ex const & e7, ex const & e8, ex const & e9,
233                      ex const &e10)
234     : basic(TINFO_LST)
235 {
236     debugmsg("lst constructor from 10 ex",
237              LOGLEVEL_CONSTRUCT);
238     RESERVE(seq,10);
239     seq.push_back(e1);
240     seq.push_back(e2);
241     seq.push_back(e3);
242     seq.push_back(e4);
243     seq.push_back(e5);
244     seq.push_back(e6);
245     seq.push_back(e7);
246     seq.push_back(e8);
247     seq.push_back(e9);
248     seq.push_back(e10);
249 }
250
251 //////////
252 // functions overriding virtual functions from bases classes
253 //////////
254
255 // public
256
257 basic * lst::duplicate() const
258 {
259     debugmsg("lst duplicate",LOGLEVEL_DUPLICATE);
260     return new lst(*this);
261 }
262
263 void lst::printraw(ostream & os) const
264 {
265     debugmsg("lst printraw",LOGLEVEL_PRINT);
266
267     os << "lst(";
268     for (exlist::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
269         (*cit).bp->printraw(os);
270         os << ",";
271     }
272     os << ")";
273 }
274
275 void lst::print(ostream & os, unsigned upper_precedence) const
276 {
277     debugmsg("lst print",LOGLEVEL_PRINT);
278     // always print brackets around seq, ignore upper_precedence
279     printseq(os,'[',',',']',precedence,precedence+1);
280 }
281
282 void lst::printtree(ostream & os, unsigned indent) const
283 {
284     debugmsg("lst printtree",LOGLEVEL_PRINT);
285
286     os << string(indent,' ') << "type=" << typeid(*this).name()
287        << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
288        << ", flags=" << flags
289        << ", nops=" << nops() << endl;
290     for (exlist::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
291         (*cit).printtree(os,indent+delta_indent);
292     }
293     os << string(indent+delta_indent,' ') << "=====" << endl;
294 }
295
296 // lst::info() will be implemented by user elsewhere";
297
298 int lst::nops() const
299 {
300     return seq.size();
301 }
302
303 ex & lst::let_op(int const i)
304 {
305     ASSERT(i>=0);
306     ASSERT(i<nops());
307
308     exlist::iterator it=seq.begin();
309     for (int j=0; j<i; j++) {
310         ++it;
311     }
312     return *it;
313 }
314
315
316 ex lst::expand(unsigned options) const
317 {
318     exlist s;
319     RESERVE(s,seq.size());
320     for (exlist::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
321         s.push_back((*it).expand(options));
322     }
323
324     return thislst(s);
325 }
326
327 // a lst 'has' an expression if it is this expression itself or a child 'has' it
328
329 bool lst::has(ex const & other) const
330 {
331     ASSERT(other.bp!=0);
332     if (is_equal(*other.bp)) return true;
333     for (exlist::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
334         if ((*it).has(other)) return true;
335     }
336     return false;
337 }
338
339 ex lst::eval(int level) const
340 {
341     if (level==1) {
342         return this->hold();
343     }
344     return thislst(evalchildren(level));
345 }
346
347 ex lst::evalf(int level) const
348 {
349     return thislst(evalfchildren(level));
350 }
351
352 /** Implementation of ex::normal() for lsts. It normalizes the arguments
353  *  and replaces the lst by a temporary symbol.
354  *  @see ex::normal */
355 ex lst::normal(lst &sym_lst, lst &repl_lst, int level) const
356 {
357     ex n=thislst(normalchildren(level));
358     return n.bp->basic::normal(sym_lst,repl_lst,level);
359 }
360
361 ex lst::diff(symbol const & s) const
362 {
363     return thislst(diffchildren(s));
364 }
365
366 ex lst::subs(lst const & ls, lst const & lr) const
367 {
368     exlist * vp=subschildren(ls,lr);
369     if (vp==0) {
370         return *this;
371     }
372     return thislst(vp);
373 }
374
375 // protected
376
377 int lst::compare_same_type(basic const & other) const
378 {
379     ASSERT(is_of_type(other,lst));
380     lst const & o=static_cast<lst const &>
381                                     (const_cast<basic &>(other));
382     int cmpval;
383     exlist::const_iterator it1=seq.begin();
384     exlist::const_iterator it2=o.seq.begin();
385
386     for (; (it1!=seq.end())&&(it2!=o.seq.end()); ++it1, ++it2) {
387         cmpval=(*it1).compare(*it2);
388         if (cmpval!=0) return cmpval;
389     }
390
391     if (it1==seq.end()) {
392         return (it2==o.seq.end() ? 0 : -1);
393     }
394
395     return 1;
396 }
397
398 bool lst::is_equal_same_type(basic const & other) const
399 {
400     ASSERT(is_of_type(other,lst));
401     lst const & o=static_cast<lst const &>
402                                     (const_cast<basic &>(other));
403     if (seq.size()!=o.seq.size()) return false;
404
405     exlist::const_iterator it1=seq.begin();
406     exlist::const_iterator it2=o.seq.begin();
407
408     for (; it1!=seq.end(); ++it1, ++it2) {
409         if (!(*it1).is_equal(*it2)) return false;
410     }
411
412     return true;
413 }
414
415 unsigned lst::return_type(void) const
416 {
417     return return_types::noncommutative_composite;
418 }
419
420 //////////
421 // new virtual functions which can be overridden by derived classes
422 //////////
423
424 // public
425
426 lst & lst::append(ex const & b)
427 {
428     ensure_if_modifiable();
429     seq.push_back(b);
430     return *this;
431 }
432
433 lst & lst::prepend(ex const & b)
434 {
435     ensure_if_modifiable();
436     seq.push_front(b);
437     return *this;
438 }
439
440
441 // protected
442
443 void lst::printseq(ostream & os, char openbracket, char delim,
444                          char closebracket, unsigned this_precedence,
445                          unsigned upper_precedence) const
446 {
447     if (this_precedence<=upper_precedence) os << openbracket;
448     if (seq.size()!=0) {
449         exlist::const_iterator it,it_last;
450         it=seq.begin();
451         it_last=seq.end();
452         --it_last;
453         for (; it!=it_last; ++it) {
454             (*it).bp->print(os,this_precedence);
455             os << delim;
456         }
457         (*it).bp->print(os,this_precedence);
458     }
459     if (this_precedence<=upper_precedence) os << closebracket;
460 }
461
462 ex lst::thislst(exlist const & v) const
463 {
464     return lst(v);
465 }
466
467 ex lst::thislst(exlist * vp) const
468 {
469     return lst(vp);
470 }
471
472 //////////
473 // non-virtual functions in this class
474 //////////
475
476 // public
477
478 // none
479
480 // protected
481
482 bool lst::is_canonical() const
483 {
484     if (seq.size()<=1) { return 1; }
485
486     exlist::const_iterator it=seq.begin();
487     exlist::const_iterator it_last=it;
488     for (++it; it!=seq.end(); it_last=it, ++it) {
489         if ((*it_last).compare(*it)>0) {
490             if ((*it_last).compare(*it)>0) {
491                 cout << *it_last << ">" << *it << "\n";
492                 return 0;
493                 }
494         }
495     }
496     return 1;
497 }
498
499
500 exlist lst::evalchildren(int level) const
501 {
502     exlist s;
503     RESERVE(s,seq.size());
504
505     if (level==1) {
506         return seq;
507     }
508     if (level == -max_recursion_level) {
509         throw(std::runtime_error("max recursion level reached"));
510     }
511     --level;
512     for (exlist::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
513         s.push_back((*it).eval(level));
514     }
515     return s;
516 }
517
518 exlist lst::evalfchildren(int level) const
519 {
520     exlist s;
521     RESERVE(s,seq.size());
522
523     if (level==1) {
524         return seq;
525     }
526     if (level == -max_recursion_level) {
527         throw(std::runtime_error("max recursion level reached"));
528     }
529     --level;
530     for (exlist::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
531         s.push_back((*it).evalf(level));
532     }
533     return s;
534 }
535
536 exlist lst::normalchildren(int level) const
537 {
538     exlist s;
539     RESERVE(s,seq.size());
540
541     if (level==1) {
542         return seq;
543     }
544     if (level == -max_recursion_level) {
545         throw(std::runtime_error("max recursion level reached"));
546     }
547     --level;
548     for (exlist::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
549         s.push_back((*it).normal(level));
550     }
551     return s;
552 }
553
554 exlist lst::diffchildren(symbol const & y) const
555 {
556     exlist s;
557     RESERVE(s,seq.size());
558     for (exlist::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
559         s.push_back((*it).diff(y));
560     }
561     return s;
562 }
563
564 /* obsolete subschildren
565 exlist lst::subschildren(lst const & ls, lst const & lr) const
566 {
567     exlist s;
568     RESERVE(s,seq.size());
569     for (exlist::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
570         s.push_back((*it).subs(ls,lr));
571     }
572     return s;
573 }
574 */
575
576 exlist * lst::subschildren(lst const & ls, lst const & lr) const
577 {
578     // returns a NULL pointer if nothing had to be substituted
579     // returns a pointer to a newly created epvector otherwise
580     // (which has to be deleted somewhere else)
581
582     exlist::const_iterator last=seq.end();
583     exlist::const_iterator cit=seq.begin();
584     while (cit!=last) {
585         ex const & subsed_ex=(*cit).subs(ls,lr);
586         if (!are_ex_trivially_equal(*cit,subsed_ex)) {
587
588             // something changed, copy seq, subs and return it
589             exlist *s=new exlist;
590             RESERVE(*s,seq.size());
591
592             // copy parts of seq which are known not to have changed
593             exlist::const_iterator cit2=seq.begin();
594             while (cit2!=cit) {
595                 s->push_back(*cit2);
596                 ++cit2;
597             }
598             // copy first changed element
599             s->push_back(subsed_ex);
600             ++cit2;
601             // copy rest
602             while (cit2!=last) {
603                 s->push_back((*cit2).subs(ls,lr));
604                 ++cit2;
605             }
606             return s;
607         }
608         ++cit;
609     }
610     
611     return 0; // nothing has changed
612 }
613
614 //////////
615 // static member variables
616 //////////
617
618 // protected
619
620 unsigned lst::precedence=10;
621
622 //////////
623 // global constants
624 //////////
625
626 const lst some_lst;
627 type_info const & typeid_lst=typeid(some_lst);
628