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(const ex & b);
56 END_OF_PREPEND_INTERFACE
58 $PREPEND_IMPLEMENTATION=<<END_OF_PREPEND_IMPLEMENTATION;
59 ${CONTAINER} & ${CONTAINER}::prepend(const ex & 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 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-2000 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>
133 #ifndef NO_NAMESPACE_GINAC
135 #endif // ndef NO_NAMESPACE_GINAC
137 // typedef ${STLHEADER}<ex> ${STLT};
138 typedef ${STLHEADER}<ex,malloc_alloc> ${STLT}; // CINT does not like ${STLHEADER}<...,default_alloc>
140 class ${CONTAINER} : public basic
142 GINAC_DECLARE_REGISTERED_CLASS(${CONTAINER}, basic)
147 ${CONTAINER}(${CONTAINER} const & other);
148 ${CONTAINER} const & operator=(${CONTAINER} const & other);
150 void copy(${CONTAINER} const & other);
151 void destroy(bool call_parent);
154 ${CONTAINER}(${STLT} const & s, bool discardable=0);
155 ${CONTAINER}(${STLT} * vp); // vp will be deleted
156 explicit ${CONTAINER}(const ex & e1);
157 explicit ${CONTAINER}(const ex & e1, const ex & e2);
158 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3);
159 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
161 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
162 const ex & e4, const ex & e5);
163 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
164 const ex & e4, const ex & e5, const ex & e6);
165 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
166 const ex & e4, const ex & e5, const ex & e6,
168 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
169 const ex & e4, const ex & e5, const ex & e6,
170 const ex & e7, const ex & e8);
171 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
172 const ex & e4, const ex & e5, const ex & e6,
173 const ex & e7, const ex & e8, const ex & e9);
174 explicit ${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
175 const ex & e4, const ex & e5, const ex & e6,
176 const ex & e7, const ex & e8, const ex & e9,
180 basic * duplicate() const;
181 void printraw(ostream & os) const;
182 void print(ostream & os, unsigned upper_precedence=0) const;
183 void printtree(ostream & os, unsigned indent) const;
184 bool info(unsigned inf) const;
185 unsigned nops() const;
187 ex expand(unsigned options=0) const;
188 bool has(const ex & other) const;
189 ex eval(int level=0) const;
190 ex evalf(int level=0) const;
191 ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
192 ex derivative(const symbol & s) const;
193 ex subs(const lst & ls, const lst & lr) const;
195 int compare_same_type(const basic & other) const;
196 bool is_equal_same_type(const basic & other) const;
197 unsigned return_type(void) const;
199 // new virtual functions which can be overridden by derived classes
201 virtual ${CONTAINER} & append(const ex & b);
204 virtual void printseq(ostream & os, char openbracket, char delim,
205 char closebracket, unsigned this_precedence,
206 unsigned upper_precedence=0) const;
207 virtual ex this${CONTAINER}(${STLT} const & v) const;
208 virtual ex this${CONTAINER}(${STLT} * vp) const;
211 bool is_canonical() const;
212 ${STLT} evalchildren(int level) const;
213 ${STLT} evalfchildren(int level) const;
214 ${STLT} normalchildren(int level) const;
215 ${STLT} diffchildren(const symbol & s) const;
216 ${STLT} * subschildren(const lst & ls, const lst & lr) const;
220 static unsigned precedence;
225 extern const ${CONTAINER} some_${CONTAINER};
226 extern const type_info & typeid_${CONTAINER};
229 inline const ${CONTAINER} &ex_to_${CONTAINER}(const ex &e)
231 return static_cast<const ${CONTAINER} &>(*e.bp);
234 inline ${CONTAINER} &ex_to_nonconst_${CONTAINER}(const ex &e)
236 return static_cast<${CONTAINER} &>(*e.bp);
239 #ifndef NO_NAMESPACE_GINAC
241 #endif // ndef NO_NAMESPACE_GINAC
243 #endif // ndef __GINAC_${CONTAINER_UC}_H__
247 $implementation=<<END_OF_IMPLEMENTATION;
248 /** \@file ${CONTAINER}.cpp
250 * Implementation of GiNaC's ${CONTAINER}. */
253 * This file was generated automatically by container.pl.
254 * Please do not modify it directly, edit the perl script instead!
255 * container.pl options: \$CONTAINER=${CONTAINER}
256 * \$STLHEADER=${STLHEADER}
257 * \$reserve=${reserve}
258 * \$prepend=${prepend}
260 * \$open_bracket=${open_bracket}
261 * \$close_bracket=${close_bracket}
263 * GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
265 * This program is free software; you can redistribute it and/or modify
266 * it under the terms of the GNU General Public License as published by
267 * the Free Software Foundation; either version 2 of the License, or
268 * (at your option) any later version.
270 * This program is distributed in the hope that it will be useful,
271 * but WITHOUT ANY WARRANTY; without even the implied warranty of
272 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
273 * GNU General Public License for more details.
275 * You should have received a copy of the GNU General Public License
276 * along with this program; if not, write to the Free Software
277 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
283 #include "${CONTAINER}.h"
286 #include "debugmsg.h"
288 #ifndef NO_NAMESPACE_GINAC
290 #endif // ndef NO_NAMESPACE_GINAC
292 GINAC_IMPLEMENT_REGISTERED_CLASS(${CONTAINER}, basic)
294 ${RESERVE_IMPLEMENTATION}
297 // default constructor, destructor, copy constructor assignment operator and helpers
302 ${CONTAINER}::${CONTAINER}() : basic(TINFO_${CONTAINER})
304 debugmsg("${CONTAINER} default constructor",LOGLEVEL_CONSTRUCT);
307 ${CONTAINER}::~${CONTAINER}()
309 debugmsg("${CONTAINER} destructor",LOGLEVEL_DESTRUCT);
313 ${CONTAINER}::${CONTAINER}(${CONTAINER} const & other)
315 debugmsg("${CONTAINER} copy constructor",LOGLEVEL_CONSTRUCT);
319 ${CONTAINER} const & ${CONTAINER}::operator=(${CONTAINER} const & other)
321 debugmsg("${CONTAINER} operator=",LOGLEVEL_ASSIGNMENT);
322 if (this != &other) {
331 void ${CONTAINER}::copy(${CONTAINER} const & other)
333 inherited::copy(other);
337 void ${CONTAINER}::destroy(bool call_parent)
340 if (call_parent) inherited::destroy(call_parent);
344 // other constructors
349 ${CONTAINER}::${CONTAINER}(${STLT} const & s, bool discardable) : basic(TINFO_${CONTAINER})
351 debugmsg("${CONTAINER} constructor from ${STLT}",
354 seq.swap(const_cast<${STLT} &>(s));
360 ${CONTAINER}::${CONTAINER}(${STLT} * vp) : basic(TINFO_${CONTAINER})
362 debugmsg("${CONTAINER} constructor from ${STLT} *",LOGLEVEL_CONSTRUCT);
368 ${CONTAINER}::${CONTAINER}(const ex & e1) : basic(TINFO_${CONTAINER})
370 debugmsg("${CONTAINER} constructor from 1 ex",
376 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2) : basic(TINFO_${CONTAINER})
378 debugmsg("${CONTAINER} constructor from 2 ex",
385 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3)
386 : basic(TINFO_${CONTAINER})
388 debugmsg("${CONTAINER} constructor from 3 ex",
396 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
397 const ex & e4) : basic(TINFO_${CONTAINER})
399 debugmsg("${CONTAINER} constructor from 4 ex",
408 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
409 const ex & e4, const ex & e5) : basic(TINFO_${CONTAINER})
411 debugmsg("${CONTAINER} constructor from 5 ex",
421 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
422 const ex & e4, const ex & e5, const ex & e6)
423 : basic(TINFO_${CONTAINER})
425 debugmsg("${CONTAINER} constructor from 6 ex",
436 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
437 const ex & e4, const ex & e5, const ex & e6,
438 const ex & e7) : basic(TINFO_${CONTAINER})
440 debugmsg("${CONTAINER} constructor from 7 ex",
452 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
453 const ex & e4, const ex & e5, const ex & e6,
454 const ex & e7, const ex & e8) : basic(TINFO_${CONTAINER})
456 debugmsg("${CONTAINER} constructor from 8 ex",
469 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
470 const ex & e4, const ex & e5, const ex & e6,
471 const ex & e7, const ex & e8, const ex & e9)
472 : basic(TINFO_${CONTAINER})
474 debugmsg("${CONTAINER} constructor from 9 ex",
488 ${CONTAINER}::${CONTAINER}(const ex & e1, const ex & e2, const ex & e3,
489 const ex & e4, const ex & e5, const ex & e6,
490 const ex & e7, const ex & e8, const ex & e9,
492 : basic(TINFO_${CONTAINER})
494 debugmsg("${CONTAINER} constructor from 10 ex",
513 /** Construct object from archive_node. */
514 ${CONTAINER}::${CONTAINER}(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
516 debugmsg("${CONTAINER} constructor from archive_node", LOGLEVEL_CONSTRUCT);
517 for (unsigned int i=0; true; i++) {
519 if (n.find_ex("seq", e, sym_lst, i))
526 /** Unarchive the object. */
527 ex ${CONTAINER}::unarchive(const archive_node &n, const lst &sym_lst)
529 return (new ${CONTAINER}(n, sym_lst))->setflag(status_flags::dynallocated);
532 /** Archive the object. */
533 void ${CONTAINER}::archive(archive_node &n) const
535 inherited::archive(n);
536 ${STLT}::const_iterator i = seq.begin(), iend = seq.end();
544 // functions overriding virtual functions from bases classes
549 basic * ${CONTAINER}::duplicate() const
551 debugmsg("${CONTAINER} duplicate",LOGLEVEL_DUPLICATE);
552 return new ${CONTAINER}(*this);
555 void ${CONTAINER}::printraw(ostream & os) const
557 debugmsg("${CONTAINER} printraw",LOGLEVEL_PRINT);
559 os << "${CONTAINER}(";
560 for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
561 (*cit).bp->printraw(os);
567 void ${CONTAINER}::print(ostream & os, unsigned upper_precedence) const
569 debugmsg("${CONTAINER} print",LOGLEVEL_PRINT);
570 // always print brackets around seq, ignore upper_precedence
571 printseq(os,'${open_bracket}',',','${close_bracket}',precedence,precedence+1);
574 void ${CONTAINER}::printtree(ostream & os, unsigned indent) const
576 debugmsg("${CONTAINER} printtree",LOGLEVEL_PRINT);
578 os << string(indent,' ') << "type=" << typeid(*this).name()
579 << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
580 << ", flags=" << flags
581 << ", nops=" << nops() << endl;
582 for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
583 (*cit).printtree(os,indent+delta_indent);
585 os << string(indent+delta_indent,' ') << "=====" << endl;
588 // ${CONTAINER}::info() will be implemented by user elsewhere";
590 unsigned ${CONTAINER}::nops() const
595 ${LET_OP_IMPLEMENTATION}
597 ex ${CONTAINER}::expand(unsigned options) const
600 RESERVE(s,seq.size());
601 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
602 s.push_back((*it).expand(options));
605 return this${CONTAINER}(s);
608 // a ${CONTAINER} 'has' an expression if it is this expression itself or a child 'has' it
610 bool ${CONTAINER}::has(const ex & other) const
612 GINAC_ASSERT(other.bp!=0);
613 if (is_equal(*other.bp)) return true;
614 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
615 if ((*it).has(other)) return true;
620 ex ${CONTAINER}::eval(int level) const
625 return this${CONTAINER}(evalchildren(level));
628 ex ${CONTAINER}::evalf(int level) const
630 return this${CONTAINER}(evalfchildren(level));
633 /** Implementation of ex::normal() for ${CONTAINER}s. It normalizes the arguments
634 * and replaces the ${CONTAINER} by a temporary symbol.
635 * \@see ex::normal */
636 ex ${CONTAINER}::normal(lst &sym_lst, lst &repl_lst, int level) const
638 ex n=this${CONTAINER}(normalchildren(level));
639 return n.bp->basic::normal(sym_lst,repl_lst,level);
642 ex ${CONTAINER}::derivative(const symbol & s) const
644 return this${CONTAINER}(diffchildren(s));
647 ex ${CONTAINER}::subs(const lst & ls, const lst & lr) const
649 ${STLT} * vp=subschildren(ls,lr);
653 return this${CONTAINER}(vp);
658 int ${CONTAINER}::compare_same_type(const basic & other) const
660 GINAC_ASSERT(is_of_type(other,${CONTAINER}));
661 ${CONTAINER} const & o=static_cast<${CONTAINER} const &>
662 (const_cast<basic &>(other));
664 ${STLT}::const_iterator it1=seq.begin();
665 ${STLT}::const_iterator it2=o.seq.begin();
667 for (; (it1!=seq.end())&&(it2!=o.seq.end()); ++it1, ++it2) {
668 cmpval=(*it1).compare(*it2);
669 if (cmpval!=0) return cmpval;
672 if (it1==seq.end()) {
673 return (it2==o.seq.end() ? 0 : -1);
679 bool ${CONTAINER}::is_equal_same_type(const basic & other) const
681 GINAC_ASSERT(is_of_type(other,${CONTAINER}));
682 ${CONTAINER} const & o=static_cast<${CONTAINER} const &>
683 (const_cast<basic &>(other));
684 if (seq.size()!=o.seq.size()) return false;
686 ${STLT}::const_iterator it1=seq.begin();
687 ${STLT}::const_iterator it2=o.seq.begin();
689 for (; it1!=seq.end(); ++it1, ++it2) {
690 if (!(*it1).is_equal(*it2)) return false;
696 unsigned ${CONTAINER}::return_type(void) const
698 return return_types::noncommutative_composite;
702 // new virtual functions which can be overridden by derived classes
707 ${CONTAINER} & ${CONTAINER}::append(const ex & b)
709 ensure_if_modifiable();
714 ${PREPEND_IMPLEMENTATION}
718 void ${CONTAINER}::printseq(ostream & os, char openbracket, char delim,
719 char closebracket, unsigned this_precedence,
720 unsigned upper_precedence) const
722 if (this_precedence<=upper_precedence) os << openbracket;
724 ${STLT}::const_iterator it,it_last;
728 for (; it!=it_last; ++it) {
729 (*it).bp->print(os,this_precedence);
732 (*it).bp->print(os,this_precedence);
734 if (this_precedence<=upper_precedence) os << closebracket;
737 ex ${CONTAINER}::this${CONTAINER}(${STLT} const & v) const
739 return ${CONTAINER}(v);
742 ex ${CONTAINER}::this${CONTAINER}(${STLT} * vp) const
744 return ${CONTAINER}(vp);
748 // non-virtual functions in this class
757 bool ${CONTAINER}::is_canonical() const
759 if (seq.size()<=1) { return 1; }
761 ${STLT}::const_iterator it=seq.begin();
762 ${STLT}::const_iterator it_last=it;
763 for (++it; it!=seq.end(); it_last=it, ++it) {
764 if ((*it_last).compare(*it)>0) {
765 if ((*it_last).compare(*it)>0) {
766 cout << *it_last << ">" << *it << "\\n";
775 ${STLT} ${CONTAINER}::evalchildren(int level) const
778 RESERVE(s,seq.size());
783 if (level == -max_recursion_level) {
784 throw(std::runtime_error("max recursion level reached"));
787 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
788 s.push_back((*it).eval(level));
793 ${STLT} ${CONTAINER}::evalfchildren(int level) const
796 RESERVE(s,seq.size());
801 if (level == -max_recursion_level) {
802 throw(std::runtime_error("max recursion level reached"));
805 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
806 s.push_back((*it).evalf(level));
811 ${STLT} ${CONTAINER}::normalchildren(int level) const
814 RESERVE(s,seq.size());
819 if (level == -max_recursion_level) {
820 throw(std::runtime_error("max recursion level reached"));
823 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
824 s.push_back((*it).normal(level));
829 ${STLT} ${CONTAINER}::diffchildren(const symbol & y) const
832 RESERVE(s,seq.size());
833 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
834 s.push_back((*it).diff(y));
839 /* obsolete subschildren
840 ${STLT} ${CONTAINER}::subschildren(const lst & ls, const lst & lr) const
843 RESERVE(s,seq.size());
844 for (${STLT}::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
845 s.push_back((*it).subs(ls,lr));
851 ${STLT} * ${CONTAINER}::subschildren(const lst & ls, const lst & lr) const
853 // returns a NULL pointer if nothing had to be substituted
854 // returns a pointer to a newly created epvector otherwise
855 // (which has to be deleted somewhere else)
857 ${STLT}::const_iterator last=seq.end();
858 ${STLT}::const_iterator cit=seq.begin();
860 const ex & subsed_ex=(*cit).subs(ls,lr);
861 if (!are_ex_trivially_equal(*cit,subsed_ex)) {
863 // something changed, copy seq, subs and return it
864 ${STLT} *s=new ${STLT};
865 RESERVE(*s,seq.size());
867 // copy parts of seq which are known not to have changed
868 ${STLT}::const_iterator cit2=seq.begin();
873 // copy first changed element
874 s->push_back(subsed_ex);
878 s->push_back((*cit2).subs(ls,lr));
886 return 0; // nothing has changed
890 // static member variables
895 unsigned ${CONTAINER}::precedence=10;
901 const ${CONTAINER} some_${CONTAINER};
902 const type_info & typeid_${CONTAINER}=typeid(some_${CONTAINER});
904 #ifndef NO_NAMESPACE_GINAC
906 #endif // ndef NO_NAMESPACE_GINAC
908 END_OF_IMPLEMENTATION
910 print "Creating interface file ${CONTAINER}.h...";
911 open OUT,">${CONTAINER}.h" or die "cannot open ${CONTAINER}.h";
912 print OUT $interface;
916 print "Creating implementation file ${CONTAINER}.cpp...";
917 open OUT,">${CONTAINER}.cpp" or die "cannot open ${CONTAINER}.cpp";
918 print OUT $implementation;