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