1 // Basic definitions of numbers
8 #include "cln/object.h"
9 #include "cln/malloc.h"
26 // Constructors and assignment operators from C numeric types.
28 #define CL_DEFINE_INT_CONSTRUCTOR(_class_,_type_) \
29 inline _class_::_class_ (const _type_ wert) \
31 word = cl_combine(cl_FN_tag,wert); \
33 #define CL_DEFINE_INT_CONSTRUCTORS(_class_) \
34 CL_DEFINE_INT_CONSTRUCTOR(_class_, int) \
35 CL_DEFINE_INT_CONSTRUCTOR(_class_, unsigned int)
37 #define CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_,_type_) \
38 inline _class_& _class_::operator= (const _type_ wert) \
40 cl_dec_refcount(*this); \
41 word = cl_combine(cl_FN_tag,wert); \
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)
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) \
53 extern cl_private_thing cl_I_constructor_from_L (sint32 wert); \
54 pointer = cl_I_constructor_from_L(wert); \
56 inline _class_::_class_ (const unsigned long wert) \
58 extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
59 pointer = cl_I_constructor_from_UL(wert); \
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) \
66 extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
67 pointer = cl_I_constructor_from_Q(wert); \
69 inline _class_::_class_ (const unsigned long wert) \
71 extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
72 pointer = cl_I_constructor_from_UQ(wert); \
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) \
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); \
86 inline _class_& _class_::operator= (const unsigned long wert) \
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); \
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) \
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); \
103 inline _class_& _class_::operator= (const unsigned long wert) \
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); \
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) \
118 extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
119 pointer = cl_I_constructor_from_Q(wert); \
121 inline _class_::_class_ (const unsigned long long wert) \
123 extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
124 pointer = cl_I_constructor_from_UQ(wert); \
126 #define CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(_class_) \
127 inline _class_& _class_::operator= (const long long wert) \
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); \
134 inline _class_& _class_::operator= (const unsigned long long wert) \
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); \
146 // Constructors and assignment operators from C numeric types.
149 extern cl_private_thing cl_float_to_FF_pointer (const float val);
151 #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
152 inline _class_ :: _class_ (const float x) \
154 pointer = cl_float_to_FF_pointer(x); \
156 inline _class_& _class_::operator= (const float x) \
158 cl_dec_refcount(*this); \
159 pointer = cl_float_to_FF_pointer(x); \
164 extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const double val);
166 #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
167 inline _class_::_class_ (const double x) \
169 pointer = cl_double_to_DF_pointer(x); \
171 inline _class_& _class_::operator= (const double x) \
173 cl_dec_refcount(*this); \
174 pointer = cl_double_to_DF_pointer(x); \
179 // Abstract class of all numbers.
181 class cl_number : public cl_gcobject {
183 // Default constructor. (Used for objects with no initializer.)
185 // Copy constructor. (Used for function argument passing and function
186 // return value, and of course for objects with initializers of the same type.)
187 cl_number (const cl_number& x);
188 // Converters. (Used for function argument passing and function return values.)
189 // Assignment operators. (Used for assignments.)
190 cl_number& operator= (const cl_number&);
191 // Constructors and assignment operators from C numeric types.
192 cl_number (const int); // |argument| must be < 2^29
193 cl_number (const unsigned int); // argument must be < 2^29
194 cl_number (const long);
195 cl_number (const unsigned long);
197 cl_number (const long long);
198 cl_number (const unsigned long long);
200 cl_number (const float);
201 cl_number (const double);
202 cl_number& operator= (const int); // |argument| must be < 2^29
203 cl_number& operator= (const unsigned int); // argument must be < 2^29
204 cl_number& operator= (const long);
205 cl_number& operator= (const unsigned long);
206 cl_number& operator= (const float);
207 cl_number& operator= (const double);
209 cl_number& operator= (const long long);
210 cl_number& operator= (const unsigned long long);
212 // Other constructors.
213 // cl_number (const char *);
214 // Private pointer manipulations.
215 cl_number (cl_private_thing);
218 // Private constructors.
219 inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {}
220 // The assignment operators:
221 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number)
222 // The default constructors.
223 inline cl_number::cl_number ()
224 : cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
225 // The copy constructors.
226 CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject)
227 // Constructors and assignment operators from C numeric types.
228 CL_DEFINE_INT_CONSTRUCTORS(cl_number)
229 CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number)
230 CL_DEFINE_LONG_CONSTRUCTORS(cl_number)
231 CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number)
233 CL_DEFINE_LONGLONG_CONSTRUCTORS(cl_number)
234 CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(cl_number)
236 CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
237 CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
242 // Conversions to subtypes without checking, template version:
243 // the<cl_I>(x) converts x to a cl_I, without change of representation.
245 inline const type& the(const cl_number& x)
247 // check that sizeof(type)==sizeof(cl_number)
248 typedef int assertion1 [1 - 2 * (sizeof(type) != sizeof(cl_number))];
249 return *(const type *) &x;
251 // Conversions to subtypes without checking, macro version:
252 // The(cl_I)(x) converts x to a cl_I, without change of representation.
253 #define The(type) *(const type *) & cl_identity
254 // This inline function is for type checking purposes only.
255 inline const cl_number& cl_identity (const cl_number& x) { return x; }
260 // Conversions to subtypes:
261 // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
262 // and then returns it without change of representation.
263 #if 0 // no debug information
264 #define As(type) type##_As
265 #define CL_DEFINE_AS_CONVERSION(_class_) \
266 extern const _class_& _class_##_As (const cl_number& x); \
267 inline const _class_& _class_##_As (const _class_& x) { return x; }
268 #else // Line number information for ease of debugging.
269 #define As(type) type##_As cl_as_aux
270 #define cl_as_aux(expr) (expr,__FILE__,__LINE__)
271 #define CL_DEFINE_AS_CONVERSION(_class_) \
272 extern const _class_& _class_##_As (const cl_number& x, const char * filename, int line); \
273 inline const _class_& _class_##_As (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
277 // x should be a variable `const type x' or `const type& x'.
278 // This macro introduces a new variable `type& x' whose value can be
279 // modified. Useful for modifying the argument of a function which takes
280 // a `const type &x'.
281 // Warning: To apply this to a function's formal parameter, a block { ... }
283 #define Mutable(type,x) \
284 type __copied_##x = x; \
285 type& x = __copied_##x;
287 // DeclareType(type,x);
288 // x should be a variable of some subtype of `cl_number'. type should be
289 // a subtype of `cl_number'. A new variable of the given type is declared,
290 // with name x and which refers to x (by reference, with const attribute).
291 #define DeclareType(type,x) \
292 const type& __tmp_##x = *(const type*) &x; \
293 const type& x = __tmp_##x;
295 #endif /* _CL_NUMBER_H */