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); \
115 // Constructors and assignment operators from C numeric types.
119 extern cl_private_thing cl_float_to_FF_pointer (const union ffloatjanus& val);
121 #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
122 inline _class_ :: _class_ (const float x) \
124 pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
126 inline _class_& _class_::operator= (const float x) \
128 cl_dec_refcount(*this); \
129 pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
135 extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const union dfloatjanus& val);
137 #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
138 inline _class_::_class_ (const double x) \
140 pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
142 inline _class_& _class_::operator= (const double x) \
144 cl_dec_refcount(*this); \
145 pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
150 // Abstract class of all numbers.
152 class cl_number : public cl_gcobject {
154 // Default constructor. (Used for objects with no initializer.)
156 // Copy constructor. (Used for function argument passing and function
157 // return value, and of course for objects with initializers of the same type.)
158 cl_number (const cl_number& x);
159 // Converters. (Used for function argument passing and function return values.)
160 // Assignment operators. (Used for assignments.)
161 cl_number& operator= (const cl_number&);
162 // Constructors and assignment operators from C numeric types.
163 cl_number (const int); // |argument| must be < 2^29
164 cl_number (const unsigned int); // argument must be < 2^29
165 cl_number (const long);
166 cl_number (const unsigned long);
167 cl_number (const float);
168 cl_number (const double);
169 cl_number& operator= (const int); // |argument| must be < 2^29
170 cl_number& operator= (const unsigned int); // argument must be < 2^29
171 cl_number& operator= (const long);
172 cl_number& operator= (const unsigned long);
173 cl_number& operator= (const float);
174 cl_number& operator= (const double);
175 // Other constructors.
176 // cl_number (const char *);
177 // Private pointer manipulations.
178 cl_number (cl_private_thing);
181 // Private constructors.
182 inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {}
183 // The assignment operators:
184 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number)
185 // The default constructors.
186 inline cl_number::cl_number ()
187 : cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
188 // The copy constructors.
189 CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject)
190 // Constructors and assignment operators from C numeric types.
191 CL_DEFINE_INT_CONSTRUCTORS(cl_number)
192 CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number)
193 CL_DEFINE_LONG_CONSTRUCTORS(cl_number)
194 CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number)
195 CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
196 CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
201 // Conversions to subtypes without checking, template version:
202 // the<cl_I>(x) converts x to a cl_I, without change of representation.
204 inline const type& the(const cl_number& x)
206 // check that sizeof(type)==sizeof(cl_number)
207 typedef int assertion1 [1 - 2 * (sizeof(type) != sizeof(cl_number))];
208 return *(const type *) &x;
210 // Conversions to subtypes without checking, macro version:
211 // The(cl_I)(x) converts x to a cl_I, without change of representation.
212 #define The(type) *(const type *) & cl_identity
213 // This inline function is for type checking purposes only.
214 inline const cl_number& cl_identity (const cl_number& x) { return x; }
219 // Conversions to subtypes:
220 // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
221 // and then returns it without change of representation.
222 #if 0 // no debug information
223 #define As(type) type##_As
224 #define CL_DEFINE_AS_CONVERSION(_class_) \
225 extern const _class_& _class_##_As (const cl_number& x); \
226 inline const _class_& _class_##_As (const _class_& x) { return x; }
227 #else // Line number information for ease of debugging.
228 #define As(type) type##_As cl_as_aux
229 #define cl_as_aux(expr) (expr,__FILE__,__LINE__)
230 #define CL_DEFINE_AS_CONVERSION(_class_) \
231 extern const _class_& _class_##_As (const cl_number& x, const char * filename, int line); \
232 inline const _class_& _class_##_As (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
236 // x should be a variable `const type x' or `const type& x'.
237 // This macro introduces a new variable `type& x' whose value can be
238 // modified. Useful for modifying the argument of a function which takes
239 // a `const type &x'.
240 // Warning: To apply this to a function's formal parameter, a block { ... }
242 #define Mutable(type,x) \
243 type __copied_##x = x; \
244 type& x = __copied_##x;
246 // DeclareType(type,x);
247 // x should be a variable of some subtype of `cl_number'. type should be
248 // a subtype of `cl_number'. A new variable of the given type is declared,
249 // with name x and which refers to x (by reference, with const attribute).
250 #define DeclareType(type,x) \
251 const type& __tmp_##x = *(const type*) &x; \
252 const type& x = __tmp_##x;
254 #endif /* _CL_NUMBER_H */