- ASSERT macro renamed to GINAC_ASSERT
[ginac.git] / ginac / basic.h
1 /** @file basic.h
2  *
3  *  Interface to GiNaC's ABC. */
4
5 /*
6  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #ifndef __GINAC_BASIC_H__
24 #define __GINAC_BASIC_H__
25
26 #include <iostream>
27 #include <typeinfo>
28 #include <vector>
29
30 #include <ginac/flags.h>
31 #include <ginac/tinfos.h>
32 #include <ginac/assertion.h>
33
34 namespace GiNaC {
35
36 class basic;
37 class ex;
38 class symbol;
39 class lst;
40 class numeric;
41
42 typedef vector<ex> exvector;
43
44 #define INLINE_BASIC_CONSTRUCTORS
45
46 /** This class is the ABC (abstract base class) of GiNaC's class hierarchy.
47  *  It is responsible for the reference counting. */
48 class basic
49 {
50     friend class ex;
51
52 // member functions
53
54     // default constructor, destructor, copy constructor assignment operator and helpers
55 public:
56     basic()
57 #ifdef INLINE_BASIC_CONSTRUCTORS
58     : tinfo_key(TINFO_basic), flags(0), refcount(0)
59     {
60     }
61 #else
62 ;
63 #endif // def INLINE_BASIC_CONSTRUCTORS
64
65     virtual ~basic()
66 #ifdef INLINE_BASIC_CONSTRUCTORS
67     {
68         destroy(0);
69         GINAC_ASSERT((!(flags & status_flags::dynallocated))||(refcount==0));
70     }
71 #else
72 ;
73 #endif // def INLINE_BASIC_CONSTRUCTORS
74
75     basic(basic const & other)
76 #ifdef INLINE_BASIC_CONSTRUCTORS
77     {
78         copy(other);
79     }
80 #else
81 ;
82 #endif // def INLINE_BASIC_CONSTRUCTORS
83
84     virtual basic const & operator=(basic const & other);
85     
86 protected:
87     void copy(basic const & other)
88     {
89         flags = other.flags & ~status_flags::dynallocated;
90         hashvalue = other.hashvalue;
91         tinfo_key = other.tinfo_key;
92     }
93     void destroy(bool call_parent) {}
94
95     // other constructors
96     basic(unsigned ti)
97 #ifdef INLINE_BASIC_CONSTRUCTORS
98     : tinfo_key(ti), flags(0), refcount(0)
99     {
100     }
101 #else
102 ;
103 #endif // def INLINE_BASIC_CONSTRUCTORS
104
105     // functions overriding virtual functions from bases classes
106     // none
107     
108     // new virtual functions which can be overridden by derived classes
109 public: // only const functions please (may break reference counting)
110     virtual basic * duplicate() const;
111     virtual void printraw(ostream & os) const;
112     virtual void printtree(ostream & os, unsigned indent) const;
113     virtual void print(ostream & os,unsigned upper_precedence=0) const;
114     virtual void printcsrc(ostream & os, unsigned type, unsigned upper_precedence=0) const;
115     virtual void dbgprint(void) const;
116     virtual void dbgprinttree(void) const;
117     virtual bool info(unsigned inf) const;
118     virtual int nops() const;
119     virtual ex op(int const i) const;
120     virtual ex & let_op(int const i);
121     virtual ex operator[](ex const & index) const;
122     virtual ex operator[](int const i) const;
123     virtual bool has(ex const & other) const;
124     virtual int degree(symbol const & s) const;
125     virtual int ldegree(symbol const & s) const;
126     virtual ex coeff(symbol const & s, int const n=1) const;
127     virtual ex collect(symbol const & s) const;
128     virtual ex eval(int level=0) const;
129     virtual ex evalf(int level=0) const;
130     virtual ex diff(symbol const & s) const;
131     virtual ex series(symbol const & s, ex const & point, int order) const;
132     virtual ex subs(lst const & ls, lst const & lr) const;
133     virtual ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
134     virtual numeric integer_content(void) const;
135     virtual ex smod(numeric const &xi) const;
136     virtual numeric max_coefficient(void) const;
137     virtual exvector get_indices(void) const;
138     virtual ex simplify_ncmul(exvector const & v) const;
139 protected: // non-const functions should be called from class ex only
140     virtual int compare_same_type(basic const & other) const;
141     virtual bool is_equal_same_type(basic const & other) const;
142     virtual unsigned return_type(void) const;
143     virtual unsigned return_type_tinfo(void) const;
144     virtual unsigned calchash(void) const;
145     virtual ex expand(unsigned options=0) const;
146
147     // non-virtual functions in this class
148 public:
149     ex subs(ex const & e) const;
150     int compare(basic const & other) const;
151     bool is_equal(basic const & other) const;
152     basic const & hold(void) const;
153     unsigned gethash(void) const {if (flags & status_flags::hash_calculated) return hashvalue; else return calchash();}
154     unsigned tinfo(void) const {return tinfo_key;}
155 protected:
156     basic const & setflag(unsigned f) const {flags |= f; return *this;}
157     basic const & clearflag(unsigned f) const {flags &= ~f; return *this;}
158     void ensure_if_modifiable(void) const;
159
160 // member variables
161     
162 protected:
163     unsigned tinfo_key;
164     mutable unsigned flags;
165     mutable unsigned hashvalue;
166     static unsigned precedence;
167     static unsigned delta_indent;
168 private:
169     unsigned refcount;
170 };
171
172 // global constants
173
174 extern const basic some_basic;
175 extern type_info const & typeid_basic;
176
177 // global variables
178
179 extern int max_recursion_level;
180
181 // convenience macros
182
183 #define is_of_type(OBJ,TYPE) \
184     (dynamic_cast<TYPE *>(const_cast<GiNaC::basic *>(&OBJ))!=0)
185
186 #define is_exactly_of_type(OBJ,TYPE) \
187     ((OBJ).tinfo()==GiNaC::TINFO_##TYPE)
188
189 #define is_ex_of_type(OBJ,TYPE) \
190     (dynamic_cast<TYPE *>(const_cast<GiNaC::basic *>((OBJ).bp))!=0)
191
192 #define is_ex_exactly_of_type(OBJ,TYPE) \
193     ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE)
194
195 } // namespace GiNaC
196
197 #endif // ndef __GINAC_BASIC_H__