]> www.ginac.de Git - cln.git/blob - include/cl_number.h
- Added lots of @cindex to produce an index.
[cln.git] / include / cl_number.h
1 // Basic definitions of numbers
2
3 #ifndef _CL_NUMBER_H
4 #define _CL_NUMBER_H
5
6 #include "cl_object.h"
7 #include "cl_malloc.h"
8
9 // Type hierachy:
10 // Number (N) =
11 //    Real (R) =
12 //       Float (F) =
13 //          Short float (SF)
14 //          Single float (FF)
15 //          Double float (DF)
16 //          Long float (LF)
17 //       Rational (RA) =
18 //          Integer (I) =
19 //             Fixnum (FN)
20 //             Bignum (BN)
21 //          Ratio (RT)
22 //    Complex (C)
23
24
25 // Constructors and assignment operators from C numeric types.
26
27 #define CL_DEFINE_INT_CONSTRUCTOR(_class_,_type_)  \
28 inline _class_::_class_ (const _type_ wert)                             \
29 {                                                                       \
30         word = cl_combine(cl_FN_tag,wert);                              \
31 }
32 #define CL_DEFINE_INT_CONSTRUCTORS(_class_)  \
33 CL_DEFINE_INT_CONSTRUCTOR(_class_, int)                                 \
34 CL_DEFINE_INT_CONSTRUCTOR(_class_, unsigned int)
35
36 #define CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_,_type_)  \
37 inline _class_& _class_::operator= (const _type_ wert)                  \
38 {                                                                       \
39         cl_dec_refcount(*this);                                         \
40         word = cl_combine(cl_FN_tag,wert);                              \
41         return *this;                                                   \
42 }
43 #define CL_DEFINE_INT_ASSIGNMENT_OPERATORS(_class_)  \
44 CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, int)                         \
45 CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, unsigned int)
46
47 #if (long_bitsize==32)
48 // `long' == `sintL', `unsigned long' == `uintL'.
49 #define CL_DEFINE_LONG_CONSTRUCTORS(_class_)  \
50 inline _class_::_class_ (const long wert)                               \
51 {                                                                       \
52         extern cl_private_thing cl_I_constructor_from_L (sint32 wert);  \
53         pointer = cl_I_constructor_from_L(wert);                        \
54 }                                                                       \
55 inline _class_::_class_ (const unsigned long wert)                      \
56 {                                                                       \
57         extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
58         pointer = cl_I_constructor_from_UL(wert);                       \
59 }
60 #elif (long_bitsize==64)
61 // `long' == `sintQ', `unsigned long' == `uintQ'.
62 #define CL_DEFINE_LONG_CONSTRUCTORS(_class_)  \
63 inline _class_::_class_ (const long wert)                               \
64 {                                                                       \
65         extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);  \
66         pointer = cl_I_constructor_from_Q(wert);                        \
67 }                                                                       \
68 inline _class_::_class_ (const unsigned long wert)                      \
69 {                                                                       \
70         extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
71         pointer = cl_I_constructor_from_UQ(wert);                       \
72 }
73 #endif
74
75 #if (long_bitsize==32)
76 // `long' == `sintL', `unsigned long' == `uintL'.
77 #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_)  \
78 inline _class_& _class_::operator= (const long wert)                    \
79 {                                                                       \
80         extern cl_private_thing cl_I_constructor_from_L (sint32 wert);  \
81         cl_dec_refcount(*this);                                         \
82         pointer = cl_I_constructor_from_L(wert);                        \
83         return *this;                                                   \
84 }                                                                       \
85 inline _class_& _class_::operator= (const unsigned long wert)           \
86 {                                                                       \
87         extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
88         cl_dec_refcount(*this);                                         \
89         pointer = cl_I_constructor_from_UL(wert);                       \
90         return *this;                                                   \
91 }
92 #elif (long_bitsize==64)
93 // `long' == `sintQ', `unsigned long' == `uintQ'.
94 #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_)  \
95 inline _class_& _class_::operator= (const long wert)                    \
96 {                                                                       \
97         extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);  \
98         cl_dec_refcount(*this);                                         \
99         pointer = cl_I_constructor_from_Q(wert);                        \
100         return *this;                                                   \
101 }                                                                       \
102 inline _class_& _class_::operator= (const unsigned long wert)           \
103 {                                                                       \
104         extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
105         cl_dec_refcount(*this);                                         \
106         pointer = cl_I_constructor_from_UQ(wert);                       \
107         return *this;                                                   \
108 }
109 #endif
110
111
112 // Conversions to subtypes:
113 // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
114 // and then returns it without change of representation.
115 #if 0 // no debug information
116   #define As(type)  as_##type
117   #define CL_DEFINE_AS_CONVERSION(_class_)                              \
118     extern const _class_& as_##_class_ (const cl_number& x);            \
119     inline const _class_& as_##_class_ (const _class_& x) { return x; }
120 #else // Line number information for ease of debugging.
121   #define As(type)  as_##type cl_as_aux
122   #define cl_as_aux(expr)  (expr,__FILE__,__LINE__)
123   #define CL_DEFINE_AS_CONVERSION(_class_)                              \
124     extern const _class_& as_##_class_ (const cl_number& x, const char * filename, int line); \
125     inline const _class_& as_##_class_ (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
126 #endif
127
128
129 // Constructors and assignment operators from C numeric types.
130
131 // from `float':
132 extern cl_private_thing cl_float_to_FF_pointer (const union ffloatjanus& val);
133
134 #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_)                            \
135 inline _class_ :: _class_ (const float x)                               \
136 {                                                                       \
137         pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
138 }                                                                       \
139 inline _class_& _class_::operator= (const float x)                      \
140 {                                                                       \
141         cl_dec_refcount(*this);                                         \
142         pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
143         return *this;                                                   \
144 }
145
146 // from `double':
147 extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const union dfloatjanus& val);
148
149 #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_)                           \
150 inline _class_::_class_ (const double x)                                \
151 {                                                                       \
152         pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
153 }                                                                       \
154 inline _class_& _class_::operator= (const double x)                     \
155 {                                                                       \
156         cl_dec_refcount(*this);                                         \
157         pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
158         return *this;                                                   \
159 }
160
161
162 // Abstract class of all numbers.
163
164 class cl_number : public cl_gcobject {
165 public:
166 // Default constructor. (Used for objects with no initializer.)
167         cl_number ();
168 // Copy constructor. (Used for function argument passing and function
169 // return value, and of course for objects with initializers of the same type.)
170         cl_number (const cl_number& x);
171 // Converters. (Used for function argument passing and function return values.)
172 // Assignment operators. (Used for assignments.)
173         cl_number& operator= (const cl_number&);
174 // Constructors and assignment operators from C numeric types.
175         cl_number (const int);          // |argument| must be < 2^29
176         cl_number (const unsigned int); // argument must be < 2^29
177         cl_number (const long);
178         cl_number (const unsigned long);
179         cl_number (const float);
180         cl_number (const double);
181         cl_number& operator= (const int);       // |argument| must be < 2^29
182         cl_number& operator= (const unsigned int); // argument must be < 2^29
183         cl_number& operator= (const long);
184         cl_number& operator= (const unsigned long);
185         cl_number& operator= (const float);
186         cl_number& operator= (const double);
187 // Other constructors.
188 //      cl_number (const char *);
189 // Private pointer manipulations.
190         cl_number (cl_private_thing);
191         cl_private_thing _as_cl_private_thing () const;
192 };
193
194 // Private constructors.
195 inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {}
196 // The assignment operators:
197 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number)
198 // The default constructors.
199 inline cl_number::cl_number ()
200         : cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
201 // The copy constructors.
202 CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject)
203 // Constructors and assignment operators from C numeric types.
204 CL_DEFINE_INT_CONSTRUCTORS(cl_number)
205 CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number)
206 CL_DEFINE_LONG_CONSTRUCTORS(cl_number)
207 CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number)
208 CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
209 CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
210
211
212 // Conversion:
213 //inline cl_N& cl_as_N (const cl_number& x)
214 //{ return *(cl_N*)(&x); }
215
216
217 // Hack section.
218
219 // Conversions to subtypes without checking:
220 // The(cl_I)(x) converts x to a cl_I, without change of representation!
221   #define The(type)  *(const type *) & cl_identity
222 // This inline function is for type checking purposes only.
223   inline const cl_number& cl_identity (const cl_number& x) { return x; }
224
225 // Mutable(type,x);
226 // x should be a variable `const type x' or `const type& x'.
227 // This macro introduces a new variable `type& x' whose value can be
228 // modified. Useful for modifying the argument of a function which takes
229 // a `const type &x'.
230 // Warning: To apply this to a function's formal parameter, a block { ... }
231 // must be inserted.
232   #define Mutable(type,x)  \
233     type __copied_##x = x;                                              \
234     type& x = __copied_##x;
235
236 // DeclareType(type,x);
237 // x should be a variable of some subtype of `cl_number'. type should be
238 // a subtype of `cl_number'. A new variable of the given type is declared,
239 // with name x and which refers to x (by reference, with const attribute).
240   #define DeclareType(type,x)  \
241     const type& __tmp_##x = *(const type*) &x;                          \
242     const type& x = __tmp_##x;
243
244
245 #endif /* _CL_NUMBER_H */