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