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