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)
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}.
93 * This file was generated automatically by container.pl.
94 * Please do not modify it directly, edit the perl script instead!
95 * container.pl options: \$CONTAINER=${CONTAINER}
96 * \$STLHEADER=${STLHEADER}
97 * \$reserve=${reserve}
98 * \$prepend=${prepend}
100 * \$open_bracket=${open_bracket}
101 * \$close_bracket=${close_bracket}
103 * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
105 * This program is free software; you can redistribute it and/or modify
106 * it under the terms of the GNU General Public License as published by
107 * the Free Software Foundation; either version 2 of the License, or
108 * (at your option) any later version.
110 * This program is distributed in the hope that it will be useful,
111 * but WITHOUT ANY WARRANTY; without even the implied warranty of
112 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
113 * GNU General Public License for more details.
115 * You should have received a copy of the GNU General Public License
116 * along with this program; if not, write to the Free Software
117 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
120 #ifndef __GINAC_${CONTAINER_UC}_H__
121 #define __GINAC_${CONTAINER_UC}_H__
123 #include <${STLHEADER}>
124 #include <ginac/ginac.h>
126 typedef ${STLHEADER}<ex> ${STLT};
128 class ${CONTAINER} : public basic
134 ${CONTAINER}(${CONTAINER} const & other);
135 ${CONTAINER} const & operator=(${CONTAINER} const & other);
137 void copy(${CONTAINER} const & other);
138 void destroy(bool call_parent);
141 ${CONTAINER}(${STLT} const & s, bool discardable=0);
142 ${CONTAINER}(${STLT} * vp); // vp will be deleted
143 explicit ${CONTAINER}(ex const & e1);
144 explicit ${CONTAINER}(ex const & e1, ex const & e2);
145 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3);
146 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
148 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
149 ex const & e4, ex const & e5);
150 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
151 ex const & e4, ex const & e5, ex const & e6);
152 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
153 ex const & e4, ex const & e5, ex const & e6,
155 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
156 ex const & e4, ex const & e5, ex const & e6,
157 ex const & e7, ex const & e8);
158 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
159 ex const & e4, ex const & e5, ex const & e6,
160 ex const & e7, ex const & e8, ex const & e9);
161 explicit ${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
162 ex const & e4, ex const & e5, ex const & e6,
163 ex const & e7, ex const & e8, ex const & e9,
167 basic * duplicate() const;
168 void printraw(ostream & os) const;
169 void print(ostream & os, unsigned upper_precedence=0) const;
170 void printtree(ostream & os, unsigned indent) const;
171 bool info(unsigned inf) const;
173 ex & let_op(int const i);
174 ex expand(unsigned options=0) const;
175 bool has(ex const & other) const;
176 ex eval(int level=0) const;
177 ex evalf(int level=0) const;
178 ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
179 ex diff(symbol const & s) const;
180 ex subs(lst const & ls, lst const & lr) const;
182 int compare_same_type(basic const & other) const;
183 bool is_equal_same_type(basic const & other) const;
184 unsigned return_type(void) const;
186 // new virtual functions which can be overridden by derived classes
188 virtual ${CONTAINER} & append(ex const & b);
191 virtual void printseq(ostream & os, char openbracket, char delim,
192 char closebracket, unsigned this_precedence,
193 unsigned upper_precedence=0) const;
194 virtual ex this${CONTAINER}(${STLT} const & v) const;
195 virtual ex this${CONTAINER}(${STLT} * vp) const;
198 bool is_canonical() const;
199 ${STLT} evalchildren(int level) const;
200 ${STLT} evalfchildren(int level) const;
201 ${STLT} normalchildren(int level) const;
202 ${STLT} diffchildren(symbol const & s) const;
203 ${STLT} * subschildren(lst const & ls, lst const & lr) const;
207 static unsigned precedence;
212 extern const ${CONTAINER} some_${CONTAINER};
213 extern type_info const & typeid_${CONTAINER};
217 #define ex_to_${CONTAINER}(X) (static_cast<${CONTAINER} const &>(*(X).bp))
219 #endif // ndef __GINAC_${CONTAINER_UC}_H__
223 $implementation=<<END_OF_IMPLEMENTATION;
224 /** \@file ${CONTAINER}.cpp
226 * Implementation of GiNaC's ${CONTAINER}.
227 * This file was generated automatically by container.pl.
228 * Please do not modify it directly, edit the perl script instead!
229 * container.pl options: \$CONTAINER=${CONTAINER}
230 * \$STLHEADER=${STLHEADER}
231 * \$reserve=${reserve}
232 * \$prepend=${prepend}
234 * \$open_bracket=${open_bracket}
235 * \$close_bracket=${close_bracket}
237 * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
239 * This program is free software; you can redistribute it and/or modify
240 * it under the terms of the GNU General Public License as published by
241 * the Free Software Foundation; either version 2 of the License, or
242 * (at your option) any later version.
244 * This program is distributed in the hope that it will be useful,
245 * but WITHOUT ANY WARRANTY; without even the implied warranty of
246 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
247 * GNU General Public License for more details.
249 * You should have received a copy of the GNU General Public License
250 * along with this program; if not, write to the Free Software
251 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
259 ${RESERVE_IMPLEMENTATION}
262 // default constructor, destructor, copy constructor assignment operator and helpers
267 ${CONTAINER}::${CONTAINER}() : basic(TINFO_${CONTAINER_UC})
269 debugmsg("${CONTAINER} default constructor",LOGLEVEL_CONSTRUCT);
272 ${CONTAINER}::~${CONTAINER}()
274 debugmsg("${CONTAINER} destructor",LOGLEVEL_DESTRUCT);
278 ${CONTAINER}::${CONTAINER}(${CONTAINER} const & other)
280 debugmsg("${CONTAINER} copy constructor",LOGLEVEL_CONSTRUCT);
284 ${CONTAINER} const & ${CONTAINER}::operator=(${CONTAINER} const & other)
286 debugmsg("${CONTAINER} operator=",LOGLEVEL_ASSIGNMENT);
287 if (this != &other) {
296 void ${CONTAINER}::copy(${CONTAINER} const & other)
302 void ${CONTAINER}::destroy(bool call_parent)
305 if (call_parent) basic::destroy(call_parent);
309 // other constructors
314 ${CONTAINER}::${CONTAINER}(${STLT} const & s, bool discardable) : basic(TINFO_${CONTAINER_UC})
316 debugmsg("${CONTAINER} constructor from ${STLT}",
319 seq.swap(const_cast<${STLT} &>(s));
325 ${CONTAINER}::${CONTAINER}(${STLT} * vp) : basic(TINFO_${CONTAINER_UC})
327 debugmsg("${CONTAINER} constructor from ${STLT} *",LOGLEVEL_CONSTRUCT);
333 ${CONTAINER}::${CONTAINER}(ex const & e1) : basic(TINFO_${CONTAINER_UC})
335 debugmsg("${CONTAINER} constructor from 1 ex",
341 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2) : basic(TINFO_${CONTAINER_UC})
343 debugmsg("${CONTAINER} constructor from 2 ex",
350 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3)
351 : basic(TINFO_${CONTAINER_UC})
353 debugmsg("${CONTAINER} constructor from 3 ex",
361 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
362 ex const & e4) : basic(TINFO_${CONTAINER_UC})
364 debugmsg("${CONTAINER} constructor from 4 ex",
373 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
374 ex const & e4, ex const & e5) : basic(TINFO_${CONTAINER_UC})
376 debugmsg("${CONTAINER} constructor from 5 ex",
386 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
387 ex const & e4, ex const & e5, ex const & e6)
388 : basic(TINFO_${CONTAINER_UC})
390 debugmsg("${CONTAINER} constructor from 6 ex",
401 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
402 ex const & e4, ex const & e5, ex const & e6,
403 ex const & e7) : basic(TINFO_${CONTAINER_UC})
405 debugmsg("${CONTAINER} constructor from 7 ex",
417 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
418 ex const & e4, ex const & e5, ex const & e6,
419 ex const & e7, ex const & e8) : basic(TINFO_${CONTAINER_UC})
421 debugmsg("${CONTAINER} constructor from 8 ex",
434 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
435 ex const & e4, ex const & e5, ex const & e6,
436 ex const & e7, ex const & e8, ex const & e9)
437 : basic(TINFO_${CONTAINER_UC})
439 debugmsg("${CONTAINER} constructor from 9 ex",
453 ${CONTAINER}::${CONTAINER}(ex const & e1, ex const & e2, ex const & e3,
454 ex const & e4, ex const & e5, ex const & e6,
455 ex const & e7, ex const & e8, ex const & e9,
457 : basic(TINFO_${CONTAINER_UC})
459 debugmsg("${CONTAINER} constructor from 10 ex",
475 // functions overriding virtual functions from bases classes
480 basic * ${CONTAINER}::duplicate() const
482 debugmsg("${CONTAINER} duplicate",LOGLEVEL_DUPLICATE);
483 return new ${CONTAINER}(*this);
486 void ${CONTAINER}::printraw(ostream & os) const
488 debugmsg("${CONTAINER} printraw",LOGLEVEL_PRINT);
490 os << "${CONTAINER}(";
491 for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
492 (*cit).bp->printraw(os);
498 void ${CONTAINER}::print(ostream & os, unsigned upper_precedence) const
500 debugmsg("${CONTAINER} print",LOGLEVEL_PRINT);
501 // always print brackets around seq, ignore upper_precedence
502 printseq(os,'${open_bracket}',',','${close_bracket}',precedence,precedence+1);
505 void ${CONTAINER}::printtree(ostream & os, unsigned indent) const
507 debugmsg("${CONTAINER} printtree",LOGLEVEL_PRINT);
509 os << string(indent,' ') << "type=" << typeid(*this).name()
510 << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
511 << ", flags=" << flags
512 << ", nops=" << nops() << endl;
513 for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
514 (*cit).printtree(os,indent+delta_indent);
516 os << string(indent+delta_indent,' ') << "=====" << endl;
519 // ${CONTAINER}::info() will be implemented by user elsewhere";
521 int ${CONTAINER}::nops() const
526 ${LET_OP_IMPLEMENTATION}
528 ex ${CONTAINER}::expand(unsigned options) const
531 RESERVE(s,seq.size());
532 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
533 s.push_back((*it).expand(options));
536 return this${CONTAINER}(s);
539 // a ${CONTAINER} 'has' an expression if it is this expression itself or a child 'has' it
541 bool ${CONTAINER}::has(ex const & other) const
544 if (is_equal(*other.bp)) return true;
545 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
546 if ((*it).has(other)) return true;
551 ex ${CONTAINER}::eval(int level) const
556 return this${CONTAINER}(evalchildren(level));
559 ex ${CONTAINER}::evalf(int level) const
561 return this${CONTAINER}(evalfchildren(level));
564 /** Implementation of ex::normal() for ${CONTAINER}s. It normalizes the arguments
565 * and replaces the ${CONTAINER} by a temporary symbol.
566 * \@see ex::normal */
567 ex ${CONTAINER}::normal(lst &sym_lst, lst &repl_lst, int level) const
569 ex n=this${CONTAINER}(normalchildren(level));
570 return n.bp->basic::normal(sym_lst,repl_lst,level);
573 ex ${CONTAINER}::diff(symbol const & s) const
575 return this${CONTAINER}(diffchildren(s));
578 ex ${CONTAINER}::subs(lst const & ls, lst const & lr) const
580 ${STLT} * vp=subschildren(ls,lr);
584 return this${CONTAINER}(vp);
589 int ${CONTAINER}::compare_same_type(basic const & other) const
591 ASSERT(is_of_type(other,${CONTAINER}));
592 ${CONTAINER} const & o=static_cast<${CONTAINER} const &>
593 (const_cast<basic &>(other));
595 ${STLT}::const_iterator it1=seq.begin();
596 ${STLT}::const_iterator it2=o.seq.begin();
598 for (; (it1!=seq.end())&&(it2!=o.seq.end()); ++it1, ++it2) {
599 cmpval=(*it1).compare(*it2);
600 if (cmpval!=0) return cmpval;
603 if (it1==seq.end()) {
604 return (it2==o.seq.end() ? 0 : -1);
610 bool ${CONTAINER}::is_equal_same_type(basic const & other) const
612 ASSERT(is_of_type(other,${CONTAINER}));
613 ${CONTAINER} const & o=static_cast<${CONTAINER} const &>
614 (const_cast<basic &>(other));
615 if (seq.size()!=o.seq.size()) return false;
617 ${STLT}::const_iterator it1=seq.begin();
618 ${STLT}::const_iterator it2=o.seq.begin();
620 for (; it1!=seq.end(); ++it1, ++it2) {
621 if (!(*it1).is_equal(*it2)) return false;
627 unsigned ${CONTAINER}::return_type(void) const
629 return return_types::noncommutative_composite;
633 // new virtual functions which can be overridden by derived classes
638 ${CONTAINER} & ${CONTAINER}::append(ex const & b)
640 ensure_if_modifiable();
645 ${PREPEND_IMPLEMENTATION}
649 void ${CONTAINER}::printseq(ostream & os, char openbracket, char delim,
650 char closebracket, unsigned this_precedence,
651 unsigned upper_precedence) const
653 if (this_precedence<=upper_precedence) os << openbracket;
655 ${STLT}::const_iterator it,it_last;
659 for (; it!=it_last; ++it) {
660 (*it).bp->print(os,this_precedence);
663 (*it).bp->print(os,this_precedence);
665 if (this_precedence<=upper_precedence) os << closebracket;
668 ex ${CONTAINER}::this${CONTAINER}(${STLT} const & v) const
670 return ${CONTAINER}(v);
673 ex ${CONTAINER}::this${CONTAINER}(${STLT} * vp) const
675 return ${CONTAINER}(vp);
679 // non-virtual functions in this class
688 bool ${CONTAINER}::is_canonical() const
690 if (seq.size()<=1) { return 1; }
692 ${STLT}::const_iterator it=seq.begin();
693 ${STLT}::const_iterator it_last=it;
694 for (++it; it!=seq.end(); it_last=it, ++it) {
695 if ((*it_last).compare(*it)>0) {
696 if ((*it_last).compare(*it)>0) {
697 cout << *it_last << ">" << *it << "\\n";
706 ${STLT} ${CONTAINER}::evalchildren(int level) const
709 RESERVE(s,seq.size());
714 if (level == -max_recursion_level) {
715 throw(std::runtime_error("max recursion level reached"));
718 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
719 s.push_back((*it).eval(level));
724 ${STLT} ${CONTAINER}::evalfchildren(int level) const
727 RESERVE(s,seq.size());
732 if (level == -max_recursion_level) {
733 throw(std::runtime_error("max recursion level reached"));
736 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
737 s.push_back((*it).evalf(level));
742 ${STLT} ${CONTAINER}::normalchildren(int level) const
745 RESERVE(s,seq.size());
750 if (level == -max_recursion_level) {
751 throw(std::runtime_error("max recursion level reached"));
754 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
755 s.push_back((*it).normal(level));
760 ${STLT} ${CONTAINER}::diffchildren(symbol const & y) const
763 RESERVE(s,seq.size());
764 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
765 s.push_back((*it).diff(y));
770 /* obsolete subschildren
771 ${STLT} ${CONTAINER}::subschildren(lst const & ls, lst const & lr) const
774 RESERVE(s,seq.size());
775 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
776 s.push_back((*it).subs(ls,lr));
782 ${STLT} * ${CONTAINER}::subschildren(lst const & ls, lst const & lr) const
784 // returns a NULL pointer if nothing had to be substituted
785 // returns a pointer to a newly created epvector otherwise
786 // (which has to be deleted somewhere else)
788 ${STLT}::const_iterator last=seq.end();
789 ${STLT}::const_iterator cit=seq.begin();
791 ex const & subsed_ex=(*cit).subs(ls,lr);
792 if (!are_ex_trivially_equal(*cit,subsed_ex)) {
794 // something changed, copy seq, subs and return it
795 ${STLT} *s=new ${STLT};
796 RESERVE(*s,seq.size());
798 // copy parts of seq which are known not to have changed
799 ${STLT}::const_iterator cit2=seq.begin();
804 // copy first changed element
805 s->push_back(subsed_ex);
809 s->push_back((*cit2).subs(ls,lr));
817 return 0; // nothing has changed
821 // static member variables
826 unsigned ${CONTAINER}::precedence=10;
832 const ${CONTAINER} some_${CONTAINER};
833 type_info const & typeid_${CONTAINER}=typeid(some_${CONTAINER});
835 END_OF_IMPLEMENTATION
837 print "Creating interface file ${CONTAINER}.h...";
838 open OUT,">${CONTAINER}.h" or die "cannot open ${CONTAINER}.h";
839 print OUT $interface;
843 print "Creating implementation file ${CONTAINER}.cpp...";
844 open OUT,">${CONTAINER}.cpp" or die "cannot open ${CONTAINER}.cpp";
845 print OUT $implementation;