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