Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-19 08:08:31

0001 // Basic definitions of numbers
0002 
0003 
0004 #ifndef _CL_NUMBER_H
0005 #define _CL_NUMBER_H
0006 
0007 
0008 #include "cln/object.h"
0009 #include "cln/malloc.h"
0010 
0011 // Type hierachy:
0012 // Number (N) =
0013 //    Real (R) =
0014 //       Float (F) =
0015 //          Short float (SF)
0016 //          Single float (FF)
0017 //          Double float (DF)
0018 //          Long float (LF)
0019 //       Rational (RA) =
0020 //          Integer (I) =
0021 //             Fixnum (FN)
0022 //             Bignum (BN)
0023 //          Ratio (RT)
0024 //    Complex (C)
0025 
0026 // Constructors and assignment operators from C numeric types.
0027 
0028 #ifdef _MSC_VER
0029 // Workaround to force MSVC to tag the symbol with the cln:: namespace
0030 // When declaring inside an inlined function the symbol is placed in the 
0031 // global namespace!
0032 namespace cln {
0033 extern cl_private_thing cl_I_constructor_from_L (sint32 wert);
0034 extern cl_private_thing cl_I_constructor_from_UL (uint32 wert);
0035 extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);
0036 extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert);
0037 }
0038 #endif
0039 
0040 #define CL_DEFINE_INT_CONSTRUCTOR(_class_,_type_)  \
0041 inline _class_::_class_ (const _type_ wert)             \
0042 {                                   \
0043     word = cl_combine(cl_FN_tag,wert);              \
0044 }
0045 #define CL_DEFINE_INT_CONSTRUCTORS(_class_)  \
0046 CL_DEFINE_INT_CONSTRUCTOR(_class_, int)                 \
0047 CL_DEFINE_INT_CONSTRUCTOR(_class_, unsigned int)
0048 
0049 #define CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_,_type_)  \
0050 inline _class_& _class_::operator= (const _type_ wert)          \
0051 {                                   \
0052     cl_dec_refcount(*this);                     \
0053     word = cl_combine(cl_FN_tag,wert);              \
0054     return *this;                           \
0055 }
0056 #define CL_DEFINE_INT_ASSIGNMENT_OPERATORS(_class_)  \
0057 CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, int)             \
0058 CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, unsigned int)
0059 
0060 #if (long_bitsize==32)
0061 // `long' == `sintL', `unsigned long' == `uintL'.
0062 #define CL_DEFINE_LONG_CONSTRUCTORS(_class_)  \
0063 inline _class_::_class_ (const long wert)               \
0064 {                                   \
0065     extern cl_private_thing cl_I_constructor_from_L (sint32 wert);  \
0066     pointer = cl_I_constructor_from_L(wert);            \
0067 }                                   \
0068 inline _class_::_class_ (const unsigned long wert)          \
0069 {                                   \
0070     extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
0071     pointer = cl_I_constructor_from_UL(wert);           \
0072 }
0073 #elif (long_bitsize==64)
0074 // `long' == `sintQ', `unsigned long' == `uintQ'.
0075 #define CL_DEFINE_LONG_CONSTRUCTORS(_class_)  \
0076 inline _class_::_class_ (const long wert)               \
0077 {                                   \
0078     extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);  \
0079     pointer = cl_I_constructor_from_Q(wert);            \
0080 }                                   \
0081 inline _class_::_class_ (const unsigned long wert)          \
0082 {                                   \
0083     extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
0084     pointer = cl_I_constructor_from_UQ(wert);           \
0085 }
0086 #endif
0087 
0088 #if (long_bitsize==32)
0089 // `long' == `sintL', `unsigned long' == `uintL'.
0090 #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_)  \
0091 inline _class_& _class_::operator= (const long wert)            \
0092 {                                   \
0093     extern cl_private_thing cl_I_constructor_from_L (sint32 wert);  \
0094     cl_dec_refcount(*this);                     \
0095     pointer = cl_I_constructor_from_L(wert);            \
0096     return *this;                           \
0097 }                                   \
0098 inline _class_& _class_::operator= (const unsigned long wert)       \
0099 {                                   \
0100     extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
0101     cl_dec_refcount(*this);                     \
0102     pointer = cl_I_constructor_from_UL(wert);           \
0103     return *this;                           \
0104 }
0105 #elif (long_bitsize==64)
0106 // `long' == `sintQ', `unsigned long' == `uintQ'.
0107 #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_)  \
0108 inline _class_& _class_::operator= (const long wert)            \
0109 {                                   \
0110     extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);  \
0111     cl_dec_refcount(*this);                     \
0112     pointer = cl_I_constructor_from_Q(wert);            \
0113     return *this;                           \
0114 }                                   \
0115 inline _class_& _class_::operator= (const unsigned long wert)       \
0116 {                                   \
0117     extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
0118     cl_dec_refcount(*this);                     \
0119     pointer = cl_I_constructor_from_UQ(wert);           \
0120     return *this;                           \
0121 }
0122 #endif
0123 
0124 #if (long_long_bitsize==64)
0125 // `long' == `sintQ', `unsigned long' == `uintQ'.
0126 #define CL_DEFINE_LONGLONG_CONSTRUCTORS(_class_)  \
0127 inline _class_::_class_ (const long long wert)              \
0128 {                                   \
0129     extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);  \
0130     pointer = cl_I_constructor_from_Q(wert);            \
0131 }                                   \
0132 inline _class_::_class_ (const unsigned long long wert)         \
0133 {                                   \
0134     extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
0135     pointer = cl_I_constructor_from_UQ(wert);           \
0136 }
0137 #define CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(_class_)            \
0138 inline _class_& _class_::operator= (const long long wert)       \
0139 {                                   \
0140     extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);  \
0141     cl_dec_refcount(*this);                     \
0142     pointer = cl_I_constructor_from_Q(wert);            \
0143     return *this;                           \
0144 }                                   \
0145 inline _class_& _class_::operator= (const unsigned long long wert)  \
0146 {                                   \
0147     extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
0148     cl_dec_refcount(*this);                     \
0149     pointer = cl_I_constructor_from_UQ(wert);           \
0150     return *this;                           \
0151 }
0152 #endif
0153 
0154 namespace cln {
0155 
0156 // Constructors and assignment operators from C numeric types.
0157 
0158 // from `float':
0159 extern cl_private_thing cl_float_to_FF_pointer (const float val);
0160 
0161 #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_)                \
0162 inline _class_ :: _class_ (const float x)               \
0163 {                                   \
0164     pointer = cl_float_to_FF_pointer(x);                \
0165 }                                   \
0166 inline _class_& _class_::operator= (const float x)          \
0167 {                                   \
0168     cl_dec_refcount(*this);                     \
0169     pointer = cl_float_to_FF_pointer(x);                \
0170     return *this;                           \
0171 }
0172 
0173 // from `double':
0174 extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const double val);
0175 
0176 #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_)               \
0177 inline _class_::_class_ (const double x)                \
0178 {                                   \
0179     pointer = cl_double_to_DF_pointer(x);               \
0180 }                                   \
0181 inline _class_& _class_::operator= (const double x)         \
0182 {                                   \
0183     cl_dec_refcount(*this);                     \
0184     pointer = cl_double_to_DF_pointer(x);               \
0185     return *this;                           \
0186 }
0187 
0188 
0189 // Abstract class of all numbers.
0190 
0191 class cl_number : public cl_gcobject {
0192 public:
0193 // Default constructor. (Used for objects with no initializer.)
0194     cl_number ();
0195 // Copy constructor. (Used for function argument passing and function
0196 // return value, and of course for objects with initializers of the same type.)
0197     cl_number (const cl_number& x);
0198 // Converters. (Used for function argument passing and function return values.)
0199 // Assignment operators. (Used for assignments.)
0200     cl_number& operator= (const cl_number&);
0201 // Constructors and assignment operators from C numeric types.
0202     cl_number (const int);      // |argument| must be < 2^29
0203     cl_number (const unsigned int); // argument must be < 2^29
0204     cl_number (const long);
0205     cl_number (const unsigned long);
0206     cl_number (const long long);
0207     cl_number (const unsigned long long);
0208     cl_number (const float);
0209     cl_number (const double);
0210     cl_number& operator= (const int);   // |argument| must be < 2^29
0211     cl_number& operator= (const unsigned int); // argument must be < 2^29
0212     cl_number& operator= (const long);
0213     cl_number& operator= (const unsigned long);
0214     cl_number& operator= (const float);
0215     cl_number& operator= (const double);
0216     cl_number& operator= (const long long);
0217     cl_number& operator= (const unsigned long long);
0218 // Other constructors.
0219 //  cl_number (const char *);
0220 // Private pointer manipulations.
0221     cl_number (cl_private_thing);
0222 };
0223 
0224 // Private constructors.
0225 inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {}
0226 // The assignment operators:
0227 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number)
0228 // The default constructors.
0229 inline cl_number::cl_number ()
0230     : cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
0231 // The copy constructors.
0232 CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject)
0233 // Constructors and assignment operators from C numeric types.
0234 CL_DEFINE_INT_CONSTRUCTORS(cl_number)
0235 CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number)
0236 CL_DEFINE_LONG_CONSTRUCTORS(cl_number)
0237 CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number)
0238 CL_DEFINE_LONGLONG_CONSTRUCTORS(cl_number)
0239 CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(cl_number)
0240 CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
0241 CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
0242 
0243 
0244 // Hack section.
0245 
0246 // Conversions to subtypes without checking, template version:
0247 // the<cl_I>(x) converts x to a cl_I, without change of representation.
0248 template<class type>
0249 inline const type& the(const cl_number& x)
0250 {
0251     // check that sizeof(type)==sizeof(cl_number)
0252     static_assert(sizeof(type)==sizeof(cl_number),
0253                   "sizeof(type)!=sizeof(cl_number)");
0254     return *(const type *) &x;
0255 }
0256 // Conversions to subtypes without checking, macro version:
0257 // The(cl_I)(x) converts x to a cl_I, without change of representation.
0258   #define The(type)  *(const type *) & cl_identity
0259 // This inline function is for type checking purposes only.
0260   inline const cl_number& cl_identity (const cl_number& x) { return x; }
0261 
0262 }  // namespace cln
0263 
0264 
0265 // Conversions to subtypes:
0266 // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
0267 // and then returns it without change of representation.
0268 #if 0 // no debug information  
0269   #define As(type)  type##_As
0270   #define CL_DEFINE_AS_CONVERSION(_class_)              \
0271     extern const _class_& _class_##_As (const cl_number& x);        \
0272     inline const _class_& _class_##_As (const _class_& x) { return x; }
0273 #else // Line number information for ease of debugging.
0274   #define As(type)  type##_As cl_as_aux
0275   #define cl_as_aux(expr)  (expr,__FILE__,__LINE__)
0276   #define CL_DEFINE_AS_CONVERSION(_class_)              \
0277     extern const _class_& _class_##_As (const cl_number& x, const char * filename, int line); \
0278     inline const _class_& _class_##_As (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
0279 #endif
0280 
0281 // Mutable(type,x);
0282 // x should be a variable `const type x' or `const type& x'.
0283 // This macro introduces a new variable `type& x' whose value can be
0284 // modified. Useful for modifying the argument of a function which takes
0285 // a `const type &x'.
0286 // Warning: To apply this to a function's formal parameter, a block { ... }
0287 // must be inserted.
0288   #define Mutable(type,x)  \
0289     type __copied_##x = x;                      \
0290     type& x = __copied_##x;
0291 
0292 // DeclareType(type,x);
0293 // x should be a variable of some subtype of `cl_number'. type should be
0294 // a subtype of `cl_number'. A new variable of the given type is declared,
0295 // with name x and which refers to x (by reference, with const attribute).
0296   #define DeclareType(type,x)  \
0297     const type& __tmp_##x = *(const type*) &x;              \
0298     const type& x = __tmp_##x;
0299 
0300 #endif /* _CL_NUMBER_H */