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