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