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)
200 //inline cl_N& cl_as_N (const cl_number& x)
201 //{ return *(cl_N*)(&x); }
206 // Conversions to subtypes without checking, template version:
207 // the<cl_I>(x) converts x to a cl_I, without change of representation.
209 inline const type& the(const cl_number& x)
211 // check that sizeof(type)==sizeof(cl_number)
212 typedef int assertion1 [1 - 2 * (sizeof(type) != sizeof(cl_number))];
213 return *(const type *) &x;
215 // Conversions to subtypes without checking, macro version:
216 // The(cl_I)(x) converts x to a cl_I, without change of representation.
217 #define The(type) *(const type *) & cl_identity
218 // This inline function is for type checking purposes only.
219 inline const cl_number& cl_identity (const cl_number& x) { return x; }
224 // Conversions to subtypes:
225 // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
226 // and then returns it without change of representation.
227 #if 0 // no debug information
228 #define As(type) type##_As
229 #define CL_DEFINE_AS_CONVERSION(_class_) \
230 extern const _class_& _class_##_As (const cl_number& x); \
231 inline const _class_& _class_##_As (const _class_& x) { return x; }
232 #else // Line number information for ease of debugging.
233 #define As(type) type##_As cl_as_aux
234 #define cl_as_aux(expr) (expr,__FILE__,__LINE__)
235 #define CL_DEFINE_AS_CONVERSION(_class_) \
236 extern const _class_& _class_##_As (const cl_number& x, const char * filename, int line); \
237 inline const _class_& _class_##_As (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
241 // x should be a variable `const type x' or `const type& x'.
242 // This macro introduces a new variable `type& x' whose value can be
243 // modified. Useful for modifying the argument of a function which takes
244 // a `const type &x'.
245 // Warning: To apply this to a function's formal parameter, a block { ... }
247 #define Mutable(type,x) \
248 type __copied_##x = x; \
249 type& x = __copied_##x;
251 // DeclareType(type,x);
252 // x should be a variable of some subtype of `cl_number'. type should be
253 // a subtype of `cl_number'. A new variable of the given type is declared,
254 // with name x and which refers to x (by reference, with const attribute).
255 #define DeclareType(type,x) \
256 const type& __tmp_##x = *(const type*) &x; \
257 const type& x = __tmp_##x;
259 #endif /* _CL_NUMBER_H */