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); \
124 #if (long_long_bitsize==64)
125 // `long' == `sintQ', `unsigned long' == `uintQ'.
126 #define CL_DEFINE_LONGLONG_CONSTRUCTORS(_class_) \
127 inline _class_::_class_ (const long long wert) \
129 extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
130 pointer = cl_I_constructor_from_Q(wert); \
132 inline _class_::_class_ (const unsigned long long wert) \
134 extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
135 pointer = cl_I_constructor_from_UQ(wert); \
137 #define CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(_class_) \
138 inline _class_& _class_::operator= (const long long wert) \
140 extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
141 cl_dec_refcount(*this); \
142 pointer = cl_I_constructor_from_Q(wert); \
145 inline _class_& _class_::operator= (const unsigned long long wert) \
147 extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
148 cl_dec_refcount(*this); \
149 pointer = cl_I_constructor_from_UQ(wert); \
156 // Constructors and assignment operators from C numeric types.
159 extern cl_private_thing cl_float_to_FF_pointer (const float val);
161 #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
162 inline _class_ :: _class_ (const float x) \
164 pointer = cl_float_to_FF_pointer(x); \
166 inline _class_& _class_::operator= (const float x) \
168 cl_dec_refcount(*this); \
169 pointer = cl_float_to_FF_pointer(x); \
174 extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const double val);
176 #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
177 inline _class_::_class_ (const double x) \
179 pointer = cl_double_to_DF_pointer(x); \
181 inline _class_& _class_::operator= (const double x) \
183 cl_dec_refcount(*this); \
184 pointer = cl_double_to_DF_pointer(x); \
189 // Abstract class of all numbers.
191 class cl_number : public cl_gcobject {
193 // Default constructor. (Used for objects with no initializer.)
195 // Copy constructor. (Used for function argument passing and function
196 // return value, and of course for objects with initializers of the same type.)
197 cl_number (const cl_number& x);
198 // Converters. (Used for function argument passing and function return values.)
199 // Assignment operators. (Used for assignments.)
200 cl_number& operator= (const cl_number&);
201 // Constructors and assignment operators from C numeric types.
202 cl_number (const int); // |argument| must be < 2^29
203 cl_number (const unsigned int); // argument must be < 2^29
204 cl_number (const long);
205 cl_number (const unsigned long);
206 cl_number (const long long);
207 cl_number (const unsigned long long);
208 cl_number (const float);
209 cl_number (const double);
210 cl_number& operator= (const int); // |argument| must be < 2^29
211 cl_number& operator= (const unsigned int); // argument must be < 2^29
212 cl_number& operator= (const long);
213 cl_number& operator= (const unsigned long);
214 cl_number& operator= (const float);
215 cl_number& operator= (const double);
216 cl_number& operator= (const long long);
217 cl_number& operator= (const unsigned long long);
218 // Other constructors.
219 // cl_number (const char *);
220 // Private pointer manipulations.
221 cl_number (cl_private_thing);
224 // Private constructors.
225 inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {}
226 // The assignment operators:
227 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number)
228 // The default constructors.
229 inline cl_number::cl_number ()
230 : cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
231 // The copy constructors.
232 CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject)
233 // Constructors and assignment operators from C numeric types.
234 CL_DEFINE_INT_CONSTRUCTORS(cl_number)
235 CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number)
236 CL_DEFINE_LONG_CONSTRUCTORS(cl_number)
237 CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number)
238 CL_DEFINE_LONGLONG_CONSTRUCTORS(cl_number)
239 CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(cl_number)
240 CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
241 CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
246 // Conversions to subtypes without checking, template version:
247 // the<cl_I>(x) converts x to a cl_I, without change of representation.
249 inline const type& the(const cl_number& x)
251 // check that sizeof(type)==sizeof(cl_number)
252 static_assert(sizeof(type)==sizeof(cl_number),
253 "sizeof(type)!=sizeof(cl_number)");
254 return *(const type *) &x;
256 // Conversions to subtypes without checking, macro version:
257 // The(cl_I)(x) converts x to a cl_I, without change of representation.
258 #define The(type) *(const type *) & cl_identity
259 // This inline function is for type checking purposes only.
260 inline const cl_number& cl_identity (const cl_number& x) { return x; }
265 // Conversions to subtypes:
266 // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
267 // and then returns it without change of representation.
268 #if 0 // no debug information
269 #define As(type) type##_As
270 #define CL_DEFINE_AS_CONVERSION(_class_) \
271 extern const _class_& _class_##_As (const cl_number& x); \
272 inline const _class_& _class_##_As (const _class_& x) { return x; }
273 #else // Line number information for ease of debugging.
274 #define As(type) type##_As cl_as_aux
275 #define cl_as_aux(expr) (expr,__FILE__,__LINE__)
276 #define CL_DEFINE_AS_CONVERSION(_class_) \
277 extern const _class_& _class_##_As (const cl_number& x, const char * filename, int line); \
278 inline const _class_& _class_##_As (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
282 // x should be a variable `const type x' or `const type& x'.
283 // This macro introduces a new variable `type& x' whose value can be
284 // modified. Useful for modifying the argument of a function which takes
285 // a `const type &x'.
286 // Warning: To apply this to a function's formal parameter, a block { ... }
288 #define Mutable(type,x) \
289 type __copied_##x = x; \
290 type& x = __copied_##x;
292 // DeclareType(type,x);
293 // x should be a variable of some subtype of `cl_number'. type should be
294 // a subtype of `cl_number'. A new variable of the given type is declared,
295 // with name x and which refers to x (by reference, with const attribute).
296 #define DeclareType(type,x) \
297 const type& __tmp_##x = *(const type*) &x; \
298 const type& x = __tmp_##x;
300 #endif /* _CL_NUMBER_H */