4 die 'usage: container.pl type (type=lst or exprseq)';
7 if ($ARGV[0] eq 'lst') {
9 } elsif ($ARGV[0] eq 'exprseq') {
12 die 'only lst and exprseq supported';
18 if ($type eq 'exprseq') {
20 # settings for exprseq
29 } elsif ($type eq 'lst') {
41 die "invalid type $type";
44 $CONTAINER_UC=uc(${CONTAINER});
45 $STLT="ex".$STLHEADER;
48 $RESERVE_IMPLEMENTATION="#define RESERVE(s,size) (s).reserve(size)";
50 $RESERVE_IMPLEMENTATION="#define RESERVE(s,size) // no reserve needed for ${STLHEADER}";
54 $PREPEND_INTERFACE=<<END_OF_PREPEND_INTERFACE;
55 virtual ${CONTAINER} & prepend(ex const & b);
56 END_OF_PREPEND_INTERFACE
58 $PREPEND_IMPLEMENTATION=<<END_OF_PREPEND_IMPLEMENTATION;
59 ${CONTAINER} & ${CONTAINER}::prepend(ex const & b)
61 ensure_if_modifiable();
65 END_OF_PREPEND_IMPLEMENTATION
67 $PREPEND_INTERFACE=" // no prepend possible for ${CONTAINER}";
68 $PREPEND_IMPLEMENTATION="";
72 $LET_OP_IMPLEMENTATION=<<END_OF_LET_OP_IMPLEMENTATION
73 ex & ${CONTAINER}::let_op(int const i)
76 GINAC_ASSERT(i<nops());
78 ${STLT}::iterator it=seq.begin();
79 for (int j=0; j<i; j++) {
84 END_OF_LET_OP_IMPLEMENTATION
86 $LET_OP_IMPLEMENTATION="// ${CONTAINER}::let_op() will be implemented by user elsewhere";
89 $interface=<<END_OF_INTERFACE;
90 /** \@file ${CONTAINER}.h
92 * Definition of GiNaC's ${CONTAINER}. */
95 * This file was generated automatically by container.pl.
96 * Please do not modify it directly, edit the perl script instead!
97 * container.pl options: \$CONTAINER=${CONTAINER}
98 * \$STLHEADER=${STLHEADER}
99 * \$reserve=${reserve}
100 * \$prepend=${prepend}
102 * \$open_bracket=${open_bracket}
103 * \$close_bracket=${close_bracket}
105 * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
107 * This program is free software; you can redistribute it and/or modify
108 * it under the terms of the GNU General Public License as published by
109 * the Free Software Foundation; either version 2 of the License, or
110 * (at your option) any later version.
112 * This program is distributed in the hope that it will be useful,
113 * but WITHOUT ANY WARRANTY; without even the implied warranty of
114 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
115 * GNU General Public License for more details.
117 * You should have received a copy of the GNU General Public License
118 * along with this program; if not, write to the Free Software
119 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
122 #ifndef __GINAC_${CONTAINER_UC}_H__
123 #define __GINAC_${CONTAINER_UC}_H__
125 #include <${STLHEADER}>
127 // CINT needs <algorithm> to work properly with <vector> and <list>
130 #include <ginac/basic.h>
131 #include <ginac/ex.h>
133 #ifndef NO_GINAC_NAMESPACE
135 #endif // ndef NO_GINAC_NAMESPACE
137 // typedef ${STLHEADER}<ex> ${STLT};
138 typedef ${STLHEADER}<ex,malloc_alloc> ${STLT}; // CINT does not like ${STLHEADER}<...,default_alloc>
140 class ${CONTAINER} : public basic
146 ${CONTAINER}(${CONTAINER} const & other);
147 ${CONTAINER} const & operator=(${CONTAINER} const & other);
149 void copy(${CONTAINER} const & other);
150 void destroy(bool call_parent);
153 ${CONTAINER}(${STLT} const & s, bool discardable=0);
154 ${CONTAINER}(${STLT} * vp); // vp will be deleted
155 explicit ${CONTAINER}(ex const & e1);
156 explicit ${CONTAINER}(ex const & e1, ex const & e2);
157 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3);
158 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
160 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
161 ex const & e4, ex const & e5);
162 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
163 ex const & e4, ex const & e5, ex const & e6);
164 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
165 ex const & e4, ex const & e5, ex const & e6,
167 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
168 ex const & e4, ex const & e5, ex const & e6,
169 ex const & e7, ex const & e8);
170 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
171 ex const & e4, ex const & e5, ex const & e6,
172 ex const & e7, ex const & e8, ex const & e9);
173 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
174 ex const & e4, ex const & e5, ex const & e6,
175 ex const & e7, ex const & e8, ex const & e9,
179 basic * duplicate() const;
180 void printraw(ostream & os) const;
181 void print(ostream & os, unsigned upper_precedence=0) const;
182 void printtree(ostream & os, unsigned indent) const;
183 bool info(unsigned inf) const;
185 ex & let_op(int const i);
186 ex expand(unsigned options=0) const;
187 bool has(ex const & other) const;
188 ex eval(int level=0) const;
189 ex evalf(int level=0) const;
190 ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
191 ex diff(symbol const & s) const;
192 ex subs(lst const & ls, lst const & lr) const;
194 int compare_same_type(basic const & other) const;
195 bool is_equal_same_type(basic const & other) const;
196 unsigned return_type(void) const;
198 // new virtual functions which can be overridden by derived classes
200 virtual ${CONTAINER} & append(ex const & b);
203 virtual void printseq(ostream & os, char openbracket, char delim,
204 char closebracket, unsigned this_precedence,
205 unsigned upper_precedence=0) const;
206 virtual ex this${CONTAINER}(${STLT} const & v) const;
207 virtual ex this${CONTAINER}(${STLT} * vp) const;
210 bool is_canonical() const;
211 ${STLT} evalchildren(int level) const;
212 ${STLT} evalfchildren(int level) const;
213 ${STLT} normalchildren(int level) const;
214 ${STLT} diffchildren(symbol const & s) const;
215 ${STLT} * subschildren(lst const & ls, lst const & lr) const;
219 static unsigned precedence;
224 extern const ${CONTAINER} some_${CONTAINER};
225 extern type_info const & typeid_${CONTAINER};
228 inline const ${CONTAINER} &ex_to_${CONTAINER}(const ex &e)
230 return static_cast<const ${CONTAINER} &>(*e.bp);
233 #ifndef NO_GINAC_NAMESPACE
235 #endif // ndef NO_GINAC_NAMESPACE
237 #endif // ndef __GINAC_${CONTAINER_UC}_H__
241 $implementation=<<END_OF_IMPLEMENTATION;
242 /** \@file ${CONTAINER}.cpp
244 * Implementation of GiNaC's ${CONTAINER}. */
247 * This file was generated automatically by container.pl.
248 * Please do not modify it directly, edit the perl script instead!
249 * container.pl options: \$CONTAINER=${CONTAINER}
250 * \$STLHEADER=${STLHEADER}
251 * \$reserve=${reserve}
252 * \$prepend=${prepend}
254 * \$open_bracket=${open_bracket}
255 * \$close_bracket=${close_bracket}
257 * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
259 * This program is free software; you can redistribute it and/or modify
260 * it under the terms of the GNU General Public License as published by
261 * the Free Software Foundation; either version 2 of the License, or
262 * (at your option) any later version.
264 * This program is distributed in the hope that it will be useful,
265 * but WITHOUT ANY WARRANTY; without even the implied warranty of
266 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
267 * GNU General Public License for more details.
269 * You should have received a copy of the GNU General Public License
270 * along with this program; if not, write to the Free Software
271 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
277 #include "${CONTAINER}.h"
279 #include "debugmsg.h"
281 #ifndef NO_GINAC_NAMESPACE
283 #endif // ndef NO_GINAC_NAMESPACE
285 ${RESERVE_IMPLEMENTATION}
288 // default constructor, destructor, copy constructor assignment operator and helpers
293 ${CONTAINER}::${CONTAINER}() : basic(TINFO_${CONTAINER})
295 debugmsg("${CONTAINER} default constructor",LOGLEVEL_CONSTRUCT);
298 ${CONTAINER}::~${CONTAINER}()
300 debugmsg("${CONTAINER} destructor",LOGLEVEL_DESTRUCT);
304 ${CONTAINER}::${CONTAINER}(${CONTAINER} const & other)
306 debugmsg("${CONTAINER} copy constructor",LOGLEVEL_CONSTRUCT);
310 ${CONTAINER} const & ${CONTAINER}::operator=(${CONTAINER} const & other)
312 debugmsg("${CONTAINER} operator=",LOGLEVEL_ASSIGNMENT);
313 if (this != &other) {
322 void ${CONTAINER}::copy(${CONTAINER} const & other)
328 void ${CONTAINER}::destroy(bool call_parent)
331 if (call_parent) basic::destroy(call_parent);
335 // other constructors
340 ${CONTAINER}::${CONTAINER}(${STLT} const & s, bool discardable) : basic(TINFO_${CONTAINER})
342 debugmsg("${CONTAINER} constructor from ${STLT}",
345 seq.swap(const_cast<${STLT} &>(s));
351 ${CONTAINER}::${CONTAINER}(${STLT} * vp) : basic(TINFO_${CONTAINER})
353 debugmsg("${CONTAINER} constructor from ${STLT} *",LOGLEVEL_CONSTRUCT);
359 ${CONTAINER}::${CONTAINER}(ex const & e1) : basic(TINFO_${CONTAINER})
361 debugmsg("${CONTAINER} constructor from 1 ex",
367 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2) : basic(TINFO_${CONTAINER})
369 debugmsg("${CONTAINER} constructor from 2 ex",
376 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3)
377 : basic(TINFO_${CONTAINER})
379 debugmsg("${CONTAINER} constructor from 3 ex",
387 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
388 ex const & e4) : basic(TINFO_${CONTAINER})
390 debugmsg("${CONTAINER} constructor from 4 ex",
399 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
400 ex const & e4, ex const & e5) : basic(TINFO_${CONTAINER})
402 debugmsg("${CONTAINER} constructor from 5 ex",
412 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
413 ex const & e4, ex const & e5, ex const & e6)
414 : basic(TINFO_${CONTAINER})
416 debugmsg("${CONTAINER} constructor from 6 ex",
427 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
428 ex const & e4, ex const & e5, ex const & e6,
429 ex const & e7) : basic(TINFO_${CONTAINER})
431 debugmsg("${CONTAINER} constructor from 7 ex",
443 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
444 ex const & e4, ex const & e5, ex const & e6,
445 ex const & e7, ex const & e8) : basic(TINFO_${CONTAINER})
447 debugmsg("${CONTAINER} constructor from 8 ex",
460 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
461 ex const & e4, ex const & e5, ex const & e6,
462 ex const & e7, ex const & e8, ex const & e9)
463 : basic(TINFO_${CONTAINER})
465 debugmsg("${CONTAINER} constructor from 9 ex",
479 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
480 ex const & e4, ex const & e5, ex const & e6,
481 ex const & e7, ex const & e8, ex const & e9,
483 : basic(TINFO_${CONTAINER})
485 debugmsg("${CONTAINER} constructor from 10 ex",
501 // functions overriding virtual functions from bases classes
506 basic * ${CONTAINER}::duplicate() const
508 debugmsg("${CONTAINER} duplicate",LOGLEVEL_DUPLICATE);
509 return new ${CONTAINER}(*this);
512 void ${CONTAINER}::printraw(ostream & os) const
514 debugmsg("${CONTAINER} printraw",LOGLEVEL_PRINT);
516 os << "${CONTAINER}(";
517 for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
518 (*cit).bp->printraw(os);
524 void ${CONTAINER}::print(ostream & os, unsigned upper_precedence) const
526 debugmsg("${CONTAINER} print",LOGLEVEL_PRINT);
527 // always print brackets around seq, ignore upper_precedence
528 printseq(os,'${open_bracket}',',','${close_bracket}',precedence,precedence+1);
531 void ${CONTAINER}::printtree(ostream & os, unsigned indent) const
533 debugmsg("${CONTAINER} printtree",LOGLEVEL_PRINT);
535 os << string(indent,' ') << "type=" << typeid(*this).name()
536 << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
537 << ", flags=" << flags
538 << ", nops=" << nops() << endl;
539 for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
540 (*cit).printtree(os,indent+delta_indent);
542 os << string(indent+delta_indent,' ') << "=====" << endl;
545 // ${CONTAINER}::info() will be implemented by user elsewhere";
547 int ${CONTAINER}::nops() const
552 ${LET_OP_IMPLEMENTATION}
554 ex ${CONTAINER}::expand(unsigned options) const
557 RESERVE(s,seq.size());
558 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
559 s.push_back((*it).expand(options));
562 return this${CONTAINER}(s);
565 // a ${CONTAINER} 'has' an expression if it is this expression itself or a child 'has' it
567 bool ${CONTAINER}::has(ex const & other) const
569 GINAC_ASSERT(other.bp!=0);
570 if (is_equal(*other.bp)) return true;
571 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
572 if ((*it).has(other)) return true;
577 ex ${CONTAINER}::eval(int level) const
582 return this${CONTAINER}(evalchildren(level));
585 ex ${CONTAINER}::evalf(int level) const
587 return this${CONTAINER}(evalfchildren(level));
590 /** Implementation of ex::normal() for ${CONTAINER}s. It normalizes the arguments
591 * and replaces the ${CONTAINER} by a temporary symbol.
592 * \@see ex::normal */
593 ex ${CONTAINER}::normal(lst &sym_lst, lst &repl_lst, int level) const
595 ex n=this${CONTAINER}(normalchildren(level));
596 return n.bp->basic::normal(sym_lst,repl_lst,level);
599 ex ${CONTAINER}::diff(symbol const & s) const
601 return this${CONTAINER}(diffchildren(s));
604 ex ${CONTAINER}::subs(lst const & ls, lst const & lr) const
606 ${STLT} * vp=subschildren(ls,lr);
610 return this${CONTAINER}(vp);
615 int ${CONTAINER}::compare_same_type(basic const & other) const
617 GINAC_ASSERT(is_of_type(other,${CONTAINER}));
618 ${CONTAINER} const & o=static_cast<${CONTAINER} const &>
619 (const_cast<basic &>(other));
621 ${STLT}::const_iterator it1=seq.begin();
622 ${STLT}::const_iterator it2=o.seq.begin();
624 for (; (it1!=seq.end())&&(it2!=o.seq.end()); ++it1, ++it2) {
625 cmpval=(*it1).compare(*it2);
626 if (cmpval!=0) return cmpval;
629 if (it1==seq.end()) {
630 return (it2==o.seq.end() ? 0 : -1);
636 bool ${CONTAINER}::is_equal_same_type(basic const & other) const
638 GINAC_ASSERT(is_of_type(other,${CONTAINER}));
639 ${CONTAINER} const & o=static_cast<${CONTAINER} const &>
640 (const_cast<basic &>(other));
641 if (seq.size()!=o.seq.size()) return false;
643 ${STLT}::const_iterator it1=seq.begin();
644 ${STLT}::const_iterator it2=o.seq.begin();
646 for (; it1!=seq.end(); ++it1, ++it2) {
647 if (!(*it1).is_equal(*it2)) return false;
653 unsigned ${CONTAINER}::return_type(void) const
655 return return_types::noncommutative_composite;
659 // new virtual functions which can be overridden by derived classes
664 ${CONTAINER} & ${CONTAINER}::append(ex const & b)
666 ensure_if_modifiable();
671 ${PREPEND_IMPLEMENTATION}
675 void ${CONTAINER}::printseq(ostream & os, char openbracket, char delim,
676 char closebracket, unsigned this_precedence,
677 unsigned upper_precedence) const
679 if (this_precedence<=upper_precedence) os << openbracket;
681 ${STLT}::const_iterator it,it_last;
685 for (; it!=it_last; ++it) {
686 (*it).bp->print(os,this_precedence);
689 (*it).bp->print(os,this_precedence);
691 if (this_precedence<=upper_precedence) os << closebracket;
694 ex ${CONTAINER}::this${CONTAINER}(${STLT} const & v) const
696 return ${CONTAINER}(v);
699 ex ${CONTAINER}::this${CONTAINER}(${STLT} * vp) const
701 return ${CONTAINER}(vp);
705 // non-virtual functions in this class
714 bool ${CONTAINER}::is_canonical() const
716 if (seq.size()<=1) { return 1; }
718 ${STLT}::const_iterator it=seq.begin();
719 ${STLT}::const_iterator it_last=it;
720 for (++it; it!=seq.end(); it_last=it, ++it) {
721 if ((*it_last).compare(*it)>0) {
722 if ((*it_last).compare(*it)>0) {
723 cout << *it_last << ">" << *it << "\\n";
732 ${STLT} ${CONTAINER}::evalchildren(int level) const
735 RESERVE(s,seq.size());
740 if (level == -max_recursion_level) {
741 throw(std::runtime_error("max recursion level reached"));
744 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
745 s.push_back((*it).eval(level));
750 ${STLT} ${CONTAINER}::evalfchildren(int level) const
753 RESERVE(s,seq.size());
758 if (level == -max_recursion_level) {
759 throw(std::runtime_error("max recursion level reached"));
762 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
763 s.push_back((*it).evalf(level));
768 ${STLT} ${CONTAINER}::normalchildren(int level) const
771 RESERVE(s,seq.size());
776 if (level == -max_recursion_level) {
777 throw(std::runtime_error("max recursion level reached"));
780 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
781 s.push_back((*it).normal(level));
786 ${STLT} ${CONTAINER}::diffchildren(symbol const & y) const
789 RESERVE(s,seq.size());
790 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
791 s.push_back((*it).diff(y));
796 /* obsolete subschildren
797 ${STLT} ${CONTAINER}::subschildren(lst const & ls, lst const & lr) const
800 RESERVE(s,seq.size());
801 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
802 s.push_back((*it).subs(ls,lr));
808 ${STLT} * ${CONTAINER}::subschildren(lst const & ls, lst const & lr) const
810 // returns a NULL pointer if nothing had to be substituted
811 // returns a pointer to a newly created epvector otherwise
812 // (which has to be deleted somewhere else)
814 ${STLT}::const_iterator last=seq.end();
815 ${STLT}::const_iterator cit=seq.begin();
817 ex const & subsed_ex=(*cit).subs(ls,lr);
818 if (!are_ex_trivially_equal(*cit,subsed_ex)) {
820 // something changed, copy seq, subs and return it
821 ${STLT} *s=new ${STLT};
822 RESERVE(*s,seq.size());
824 // copy parts of seq which are known not to have changed
825 ${STLT}::const_iterator cit2=seq.begin();
830 // copy first changed element
831 s->push_back(subsed_ex);
835 s->push_back((*cit2).subs(ls,lr));
843 return 0; // nothing has changed
847 // static member variables
852 unsigned ${CONTAINER}::precedence=10;
858 const ${CONTAINER} some_${CONTAINER};
859 type_info const & typeid_${CONTAINER}=typeid(some_${CONTAINER});
861 #ifndef NO_GINAC_NAMESPACE
863 #endif // ndef NO_GINAC_NAMESPACE
865 END_OF_IMPLEMENTATION
867 print "Creating interface file ${CONTAINER}.h...";
868 open OUT,">${CONTAINER}.h" or die "cannot open ${CONTAINER}.h";
869 print OUT $interface;
873 print "Creating implementation file ${CONTAINER}.cpp...";
874 open OUT,">${CONTAINER}.cpp" or die "cannot open ${CONTAINER}.cpp";
875 print OUT $implementation;