1 // Basic definitions of numbers
8 #include "cln/object.h"
9 #include "cln/malloc.h"
26 // Constructors and assignment operators from C numeric types.
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
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);
40 #define CL_DEFINE_INT_CONSTRUCTOR(_class_,_type_) \
41 inline _class_::_class_ (const _type_ wert) \
43 word = cl_combine(cl_FN_tag,wert); \
45 #define CL_DEFINE_INT_CONSTRUCTORS(_class_) \
46 CL_DEFINE_INT_CONSTRUCTOR(_class_, int) \
47 CL_DEFINE_INT_CONSTRUCTOR(_class_, unsigned int)
49 #define CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_,_type_) \
50 inline _class_& _class_::operator= (const _type_ wert) \
52 cl_dec_refcount(*this); \
53 word = cl_combine(cl_FN_tag,wert); \
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)
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) \
65 extern cl_private_thing cl_I_constructor_from_L (sint32 wert); \
66 pointer = cl_I_constructor_from_L(wert); \
68 inline _class_::_class_ (const unsigned long wert) \
70 extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
71 pointer = cl_I_constructor_from_UL(wert); \
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) \
78 extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
79 pointer = cl_I_constructor_from_Q(wert); \
81 inline _class_::_class_ (const unsigned long wert) \
83 extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
84 pointer = cl_I_constructor_from_UQ(wert); \
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) \
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); \
98 inline _class_& _class_::operator= (const unsigned long wert) \
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); \
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) \
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); \
115 inline _class_& _class_::operator= (const unsigned long wert) \
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); \
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) \
130 extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
131 pointer = cl_I_constructor_from_Q(wert); \
133 inline _class_::_class_ (const unsigned long long wert) \
135 extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
136 pointer = cl_I_constructor_from_UQ(wert); \
138 #define CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(_class_) \
139 inline _class_& _class_::operator= (const long long wert) \
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); \
146 inline _class_& _class_::operator= (const unsigned long long wert) \
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); \
158 // Constructors and assignment operators from C numeric types.
161 extern cl_private_thing cl_float_to_FF_pointer (const float val);
163 #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
164 inline _class_ :: _class_ (const float x) \
166 pointer = cl_float_to_FF_pointer(x); \
168 inline _class_& _class_::operator= (const float x) \
170 cl_dec_refcount(*this); \
171 pointer = cl_float_to_FF_pointer(x); \
176 extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const double val);
178 #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
179 inline _class_::_class_ (const double x) \
181 pointer = cl_double_to_DF_pointer(x); \
183 inline _class_& _class_::operator= (const double x) \
185 cl_dec_refcount(*this); \
186 pointer = cl_double_to_DF_pointer(x); \
191 // Abstract class of all numbers.
193 class cl_number : public cl_gcobject {
195 // Default constructor. (Used for objects with no initializer.)
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);
209 cl_number (const long long);
210 cl_number (const unsigned long long);
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);
221 cl_number& operator= (const long long);
222 cl_number& operator= (const unsigned long long);
224 // Other constructors.
225 // cl_number (const char *);
226 // Private pointer manipulations.
227 cl_number (cl_private_thing);
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)
245 CL_DEFINE_LONGLONG_CONSTRUCTORS(cl_number)
246 CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(cl_number)
248 CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
249 CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
254 // Conversions to subtypes without checking, template version:
255 // the<cl_I>(x) converts x to a cl_I, without change of representation.
257 inline const type& the(const cl_number& x)
259 // check that sizeof(type)==sizeof(cl_number)
260 typedef int assertion1 [1 - 2 * (sizeof(type) != sizeof(cl_number))];
261 return *(const type *) &x;
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; }
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; }
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 { ... }
295 #define Mutable(type,x) \
296 type __copied_##x = x; \
297 type& x = __copied_##x;
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;
307 #endif /* _CL_NUMBER_H */