- switched to automake build environment
[ginac.git] / ginac / basic.h
1 /** @file basic.h
2  *
3  *  Interface to GiNaC's ABC. */
4
5 #ifndef _BASIC_H_
6 #define _BASIC_H_
7
8 #include <iostream>
9 #include <typeinfo>
10 #include <vector>
11
12 #include "flags.h"
13 #include "tinfos.h"
14 #include "debugmsg.h"
15
16 class basic;
17 class ex;
18 class symbol;
19 class lst;
20 class numeric;
21
22 typedef vector<ex> exvector;
23
24 #define INLINE_BASIC_CONSTRUCTORS
25
26 /** This class is the ABC (abstract base class) of GiNaC's class hierarchy.
27  *  It is responsible for the reference counting. */
28 class basic
29 {
30     friend class ex;
31
32 // member functions
33
34     // default constructor, destructor, copy constructor assignment operator and helpers
35 public:
36     basic()
37 #ifdef INLINE_BASIC_CONSTRUCTORS
38     : tinfo_key(TINFO_BASIC), flags(0), refcount(0)
39     {
40         debugmsg("basic default constructor",LOGLEVEL_CONSTRUCT);
41         // nothing to do
42     }
43 #else
44 ;
45 #endif // def INLINE_BASIC_CONSTRUCTORS
46
47     virtual ~basic()
48 #ifdef INLINE_BASIC_CONSTRUCTORS
49     {
50         debugmsg("basic destructor",LOGLEVEL_DESTRUCT);
51         destroy(0);
52         ASSERT((!(flags & status_flags::dynallocated))||(refcount==0));
53     }
54 #else
55 ;
56 #endif // def INLINE_BASIC_CONSTRUCTORS
57
58     basic(basic const & other)
59 #ifdef INLINE_BASIC_CONSTRUCTORS
60     {
61         debugmsg("basic copy constructor",LOGLEVEL_CONSTRUCT);
62         copy(other);
63     }
64 #else
65 ;
66 #endif // def INLINE_BASIC_CONSTRUCTORS
67
68     virtual basic const & operator=(basic const & other);
69     
70 protected:
71     void copy(basic const & other)
72     {
73         flags = other.flags & ~status_flags::dynallocated;
74         hashvalue = other.hashvalue;
75         tinfo_key = other.tinfo_key;
76     }
77     void destroy(bool call_parent) {}
78
79     // other constructors
80     basic(unsigned ti)
81 #ifdef INLINE_BASIC_CONSTRUCTORS
82     : tinfo_key(ti), flags(0), refcount(0)
83     {
84         debugmsg("basic constructor with tinfo_key",LOGLEVEL_CONSTRUCT);
85         // nothing to do
86     }
87 #else
88 ;
89 #endif // def INLINE_BASIC_CONSTRUCTORS
90
91     // functions overriding virtual functions from bases classes
92     // none
93     
94     // new virtual functions which can be overridden by derived classes
95 public: // only const functions please (may break reference counting)
96     virtual basic * duplicate() const;
97     virtual void printraw(ostream & os) const;
98     virtual void printtree(ostream & os, unsigned indent) const;
99     virtual void print(ostream & os,unsigned upper_precedence=0) const;
100     virtual void printcsrc(ostream & os, unsigned type, unsigned upper_precedence=0) const;
101     virtual void dbgprint(void) const;
102     virtual void dbgprinttree(void) const;
103     virtual bool info(unsigned inf) const;
104     virtual int nops() const;
105     virtual ex op(int const i) const;
106     virtual ex & let_op(int const i);
107     virtual ex operator[](ex const & index) const;
108     virtual ex operator[](int const i) const;
109     virtual bool has(ex const & other) const;
110     virtual int degree(symbol const & s) const;
111     virtual int ldegree(symbol const & s) const;
112     virtual ex coeff(symbol const & s, int const n=1) const;
113     virtual ex collect(symbol const & s) const;
114     virtual ex eval(int level=0) const;
115     virtual ex evalf(int level=0) const;
116     virtual ex diff(symbol const & s) const;
117     virtual ex series(symbol const & s, ex const & point, int order) const;
118     virtual ex subs(lst const & ls, lst const & lr) const;
119     virtual ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
120     virtual numeric integer_content(void) const;
121     virtual ex smod(numeric const &xi) const;
122     virtual numeric max_coefficient(void) const;
123     virtual exvector get_indices(void) const;
124     virtual ex simplify_ncmul(exvector const & v) const;
125 protected: // non-const functions should be called from class ex only
126     virtual int compare_same_type(basic const & other) const;
127     virtual bool is_equal_same_type(basic const & other) const;
128     virtual unsigned return_type(void) const;
129     virtual unsigned return_type_tinfo(void) const;
130     virtual unsigned calchash(void) const;
131     virtual ex expand(unsigned options=0) const;
132
133     // non-virtual functions in this class
134 public:
135     ex subs(ex const & e) const;
136     int compare(basic const & other) const;
137     bool is_equal(basic const & other) const;
138     basic const & hold(void) const;
139     unsigned gethash(void) const {if (flags & status_flags::hash_calculated) return hashvalue; else return calchash();}
140     unsigned tinfo(void) const {return tinfo_key;}
141 protected:
142     basic const & setflag(unsigned f) const {flags |= f; return *this;}
143     basic const & clearflag(unsigned f) const {flags &= ~f; return *this;}
144     void ensure_if_modifiable(void) const;
145
146 // member variables
147     
148 protected:
149     unsigned tinfo_key;
150     mutable unsigned flags;
151     mutable unsigned hashvalue;
152     static unsigned precedence;
153     static unsigned delta_indent;
154 private:
155     unsigned refcount;
156 };
157
158 // global constants
159
160 extern const basic some_basic;
161 extern type_info const & typeid_basic;
162
163 // global variables
164
165 extern int max_recursion_level;
166
167 /*
168 #ifndef _DEBUG
169 */
170 #define is_of_type(OBJ,TYPE) \
171     (dynamic_cast<TYPE *>(const_cast<basic *>(&OBJ))!=0)
172
173 /*
174 #define is_exactly_of_type(OBJ,TYPE) \
175     (typeid(OBJ)==typeid(some_##TYPE))
176 */
177 #define is_exactly_of_type(OBJ,TYPE) \
178     ((OBJ).tinfo()==(some_##TYPE).tinfo())
179
180
181     /*
182 #else 
183 #define is_of_type(OBJ,TYPE)                               \
184     (ASSERT(typeid(OBJ)!=typeid(exZERO())),                \
185      (dynamic_cast<TYPE *>(const_cast<basic *>(&OBJ))!=0))
186
187 #define is_exactly_of_type(OBJ,TYPE)                       \
188     (ASSERT(typeid(OBJ)!=typeid(exZERO())),                \
189      (typeid(OBJ)==typeid(some_##TYPE))
190 #endif // ndef _DEBUG
191 */
192
193 #define is_ex_of_type(OBJ,TYPE) \
194     (dynamic_cast<TYPE *>(const_cast<basic *>((OBJ).bp))!=0)
195
196 /*
197 #define is_ex_exactly_of_type(OBJ,TYPE) \
198     (typeid(*(OBJ).bp)==typeid(some_##TYPE))
199 */
200
201 #define is_ex_exactly_of_type(OBJ,TYPE) \
202     ((*(OBJ).bp).tinfo()==(some_##TYPE).tinfo())
203
204 #define are_ex_trivially_equal(EX1,EX2) \
205     ((EX1).bp==(EX2).bp)
206
207 // global functions
208
209 inline unsigned rotate_left_31(unsigned n)
210 {
211     // clear highest bit and shift 1 bit to the left
212     n=(n & 0x7FFFFFFFU) << 1;
213
214     // overflow? clear highest bit and set lowest bit
215     if (n & 0x80000000U) {
216         n=(n & 0x7FFFFFFFU) | 0x00000001U;
217     }
218
219     ASSERT(n<0x80000000U);
220
221     return n;
222 }
223
224 inline unsigned golden_ratio_hash(unsigned n)
225 {
226 #if 0
227         // This requires ´long long´ (or an equivalent 64 bit type)---which is,
228     // unfortunately, not ANSI-compliant:
229         unsigned long long l = n * 0x4f1bbcddLL;
230         return (l & 0x7fffffffU) ^ (l >> 32);
231 #else
232         // This requires ´long double´ to have a mantissa of at least 64 bit---
233     // which is not guaranteed by any standard:
234     const static long double golden_ratio=.618033988749894848204586834370;
235     long double m=golden_ratio*n;
236     return unsigned((m-int(m))*0x80000000);
237 #endif
238 }
239
240 #endif // ndef _BASIC_H_