1 // Basic definitions of numbers
6 #include "cln/object.h"
7 #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 // Conversions to subtypes:
114 // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
115 // and then returns it without change of representation.
116 #if 0 // no debug information
117 #define As(type) as_##type
118 #define CL_DEFINE_AS_CONVERSION(_class_) \
119 extern const _class_& as_##_class_ (const cl_number& x); \
120 inline const _class_& as_##_class_ (const _class_& x) { return x; }
121 #else // Line number information for ease of debugging.
122 #define As(type) as_##type cl_as_aux
123 #define cl_as_aux(expr) (expr,__FILE__,__LINE__)
124 #define CL_DEFINE_AS_CONVERSION(_class_) \
125 extern const _class_& as_##_class_ (const cl_number& x, const char * filename, int line); \
126 inline const _class_& as_##_class_ (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
130 // Constructors and assignment operators from C numeric types.
133 extern cl_private_thing cl_float_to_FF_pointer (const union ffloatjanus& val);
135 #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
136 inline _class_ :: _class_ (const float x) \
138 pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
140 inline _class_& _class_::operator= (const float x) \
142 cl_dec_refcount(*this); \
143 pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
148 extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const union dfloatjanus& val);
150 #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
151 inline _class_::_class_ (const double x) \
153 pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
155 inline _class_& _class_::operator= (const double x) \
157 cl_dec_refcount(*this); \
158 pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
163 // Abstract class of all numbers.
165 class cl_number : public cl_gcobject {
167 // Default constructor. (Used for objects with no initializer.)
169 // Copy constructor. (Used for function argument passing and function
170 // return value, and of course for objects with initializers of the same type.)
171 cl_number (const cl_number& x);
172 // Converters. (Used for function argument passing and function return values.)
173 // Assignment operators. (Used for assignments.)
174 cl_number& operator= (const cl_number&);
175 // Constructors and assignment operators from C numeric types.
176 cl_number (const int); // |argument| must be < 2^29
177 cl_number (const unsigned int); // argument must be < 2^29
178 cl_number (const long);
179 cl_number (const unsigned long);
180 cl_number (const float);
181 cl_number (const double);
182 cl_number& operator= (const int); // |argument| must be < 2^29
183 cl_number& operator= (const unsigned int); // argument must be < 2^29
184 cl_number& operator= (const long);
185 cl_number& operator= (const unsigned long);
186 cl_number& operator= (const float);
187 cl_number& operator= (const double);
188 // Other constructors.
189 // cl_number (const char *);
190 // Private pointer manipulations.
191 cl_number (cl_private_thing);
192 cl_private_thing _as_cl_private_thing () const;
195 // Private constructors.
196 inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {}
197 // The assignment operators:
198 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number)
199 // The default constructors.
200 inline cl_number::cl_number ()
201 : cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
202 // The copy constructors.
203 CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject)
204 // Constructors and assignment operators from C numeric types.
205 CL_DEFINE_INT_CONSTRUCTORS(cl_number)
206 CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number)
207 CL_DEFINE_LONG_CONSTRUCTORS(cl_number)
208 CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number)
209 CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
210 CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
214 //inline cl_N& cl_as_N (const cl_number& x)
215 //{ return *(cl_N*)(&x); }
220 // Conversions to subtypes without checking:
221 // the<cl_I>(x) converts x to a cl_I, without change of representation!
223 inline const type& the(const cl_number& x)
225 // check that sizeof(type)==sizeof(cl_number)
226 typedef int assertion1 [1 - 2 * (sizeof(type) != sizeof(cl_number))];
227 return *(const type *) &x;
230 // Conversions to subtypes without checking:
231 // The(cl_I)(x) converts x to a cl_I, without change of representation!
232 #define The(type) *(const type *) & cl_identity
233 // This inline function is for type checking purposes only.
234 inline const cl_number& cl_identity (const cl_number& x) { return x; }
237 // x should be a variable `const type x' or `const type& x'.
238 // This macro introduces a new variable `type& x' whose value can be
239 // modified. Useful for modifying the argument of a function which takes
240 // a `const type &x'.
241 // Warning: To apply this to a function's formal parameter, a block { ... }
243 #define Mutable(type,x) \
244 type __copied_##x = x; \
245 type& x = __copied_##x;
247 // DeclareType(type,x);
248 // x should be a variable of some subtype of `cl_number'. type should be
249 // a subtype of `cl_number'. A new variable of the given type is declared,
250 // with name x and which refers to x (by reference, with const attribute).
251 #define DeclareType(type,x) \
252 const type& __tmp_##x = *(const type*) &x; \
253 const type& x = __tmp_##x;
257 #endif /* _CL_NUMBER_H */