You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							297 lines
						
					
					
						
							10 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							297 lines
						
					
					
						
							10 KiB
						
					
					
				| // Basic definitions of numbers | |
|  | |
| 
 | |
| #ifndef _CL_NUMBER_H | |
| #define _CL_NUMBER_H | |
|  | |
| 
 | |
| #include "cln/object.h" | |
| #include "cln/malloc.h" | |
|  | |
| // Type hierachy: | |
| // Number (N) = | |
| //    Real (R) = | |
| //       Float (F) = | |
| //          Short float (SF) | |
| //          Single float (FF) | |
| //          Double float (DF) | |
| //          Long float (LF) | |
| //       Rational (RA) = | |
| //          Integer (I) = | |
| //             Fixnum (FN) | |
| //             Bignum (BN) | |
| //          Ratio (RT) | |
| //    Complex (C) | |
|  | |
| // Constructors and assignment operators from C numeric types. | |
|  | |
| #define CL_DEFINE_INT_CONSTRUCTOR(_class_,_type_)  \ | |
| inline _class_::_class_ (const _type_ wert)				\ | |
| {									\ | |
| 	word = cl_combine(cl_FN_tag,wert);				\ | |
| } | |
| #define CL_DEFINE_INT_CONSTRUCTORS(_class_)  \ | |
| CL_DEFINE_INT_CONSTRUCTOR(_class_, int)					\ | |
| CL_DEFINE_INT_CONSTRUCTOR(_class_, unsigned int) | |
|  | |
| #define CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_,_type_)  \ | |
| inline _class_& _class_::operator= (const _type_ wert)			\ | |
| {									\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	word = cl_combine(cl_FN_tag,wert);				\ | |
| 	return *this;							\ | |
| } | |
| #define CL_DEFINE_INT_ASSIGNMENT_OPERATORS(_class_)  \ | |
| CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, int)				\ | |
| CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, unsigned int) | |
|  | |
| #if (long_bitsize==32) | |
| // `long' == `sintL', `unsigned long' == `uintL'. | |
| #define CL_DEFINE_LONG_CONSTRUCTORS(_class_)  \ | |
| inline _class_::_class_ (const long wert)				\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_L (sint32 wert);	\ | |
| 	pointer = cl_I_constructor_from_L(wert);			\ | |
| }									\ | |
| inline _class_::_class_ (const unsigned long wert)			\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_UL (uint32 wert);	\ | |
| 	pointer = cl_I_constructor_from_UL(wert);			\ | |
| } | |
| #elif (long_bitsize==64) | |
| // `long' == `sintQ', `unsigned long' == `uintQ'. | |
| #define CL_DEFINE_LONG_CONSTRUCTORS(_class_)  \ | |
| inline _class_::_class_ (const long wert)				\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);	\ | |
| 	pointer = cl_I_constructor_from_Q(wert);			\ | |
| }									\ | |
| inline _class_::_class_ (const unsigned long wert)			\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert);	\ | |
| 	pointer = cl_I_constructor_from_UQ(wert);			\ | |
| } | |
| #endif | |
|  | |
| #if (long_bitsize==32) | |
| // `long' == `sintL', `unsigned long' == `uintL'. | |
| #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_)  \ | |
| inline _class_& _class_::operator= (const long wert)			\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_L (sint32 wert);	\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_I_constructor_from_L(wert);			\ | |
| 	return *this;							\ | |
| }									\ | |
| inline _class_& _class_::operator= (const unsigned long wert)		\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_UL (uint32 wert);	\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_I_constructor_from_UL(wert);			\ | |
| 	return *this;							\ | |
| } | |
| #elif (long_bitsize==64) | |
| // `long' == `sintQ', `unsigned long' == `uintQ'. | |
| #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_)  \ | |
| inline _class_& _class_::operator= (const long wert)			\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);	\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_I_constructor_from_Q(wert);			\ | |
| 	return *this;							\ | |
| }									\ | |
| inline _class_& _class_::operator= (const unsigned long wert)		\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert);	\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_I_constructor_from_UQ(wert);			\ | |
| 	return *this;							\ | |
| } | |
| #endif | |
|  | |
| #ifdef HAVE_LONGLONG | |
| #if (long_long_bitsize==64) | |
| // `long' == `sintQ', `unsigned long' == `uintQ'. | |
| #define CL_DEFINE_LONGLONG_CONSTRUCTORS(_class_)  \ | |
| inline _class_::_class_ (const long long wert)				\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);	\ | |
| 	pointer = cl_I_constructor_from_Q(wert);			\ | |
| }									\ | |
| inline _class_::_class_ (const unsigned long long wert)			\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert);	\ | |
| 	pointer = cl_I_constructor_from_UQ(wert);			\ | |
| } | |
| #define CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(_class_)			\ | |
| inline _class_& _class_::operator= (const long long wert)		\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_Q (sint64 wert);	\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_I_constructor_from_Q(wert);			\ | |
| 	return *this;							\ | |
| }									\ | |
| inline _class_& _class_::operator= (const unsigned long long wert)	\ | |
| {									\ | |
| 	extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert);	\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_I_constructor_from_UQ(wert);			\ | |
| 	return *this;							\ | |
| } | |
| #endif | |
| #endif | |
|  | |
| namespace cln { | |
| 
 | |
| // Constructors and assignment operators from C numeric types. | |
|  | |
| // from `float': | |
| union ffloatjanus; | |
| extern cl_private_thing cl_float_to_FF_pointer (const union ffloatjanus& val); | |
| 
 | |
| #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_)				\ | |
| inline _class_ :: _class_ (const float x)				\ | |
| {									\ | |
| 	pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \ | |
| }									\ | |
| inline _class_& _class_::operator= (const float x)			\ | |
| {									\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \ | |
| 	return *this;							\ | |
| } | |
|  | |
| // from `double': | |
| union dfloatjanus; | |
| extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const union dfloatjanus& val); | |
| 
 | |
| #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_)				\ | |
| inline _class_::_class_ (const double x)				\ | |
| {									\ | |
| 	pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \ | |
| }									\ | |
| inline _class_& _class_::operator= (const double x)			\ | |
| {									\ | |
| 	cl_dec_refcount(*this);						\ | |
| 	pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \ | |
| 	return *this;							\ | |
| } | |
|  | |
| 
 | |
| // Abstract class of all numbers. | |
|  | |
| class cl_number : public cl_gcobject { | |
| public: | |
| // Default constructor. (Used for objects with no initializer.) | |
| 	cl_number (); | |
| // Copy constructor. (Used for function argument passing and function | |
| // return value, and of course for objects with initializers of the same type.) | |
| 	cl_number (const cl_number& x); | |
| // Converters. (Used for function argument passing and function return values.) | |
| // Assignment operators. (Used for assignments.) | |
| 	cl_number& operator= (const cl_number&); | |
| // Constructors and assignment operators from C numeric types. | |
| 	cl_number (const int);		// |argument| must be < 2^29 | |
| 	cl_number (const unsigned int);	// argument must be < 2^29 | |
| 	cl_number (const long); | |
| 	cl_number (const unsigned long); | |
| #ifdef HAVE_LONGLONG | |
| 	cl_number (const long long); | |
| 	cl_number (const unsigned long long); | |
| #endif | |
| 	cl_number (const float); | |
| 	cl_number (const double); | |
| 	cl_number& operator= (const int);	// |argument| must be < 2^29 | |
| 	cl_number& operator= (const unsigned int); // argument must be < 2^29 | |
| 	cl_number& operator= (const long); | |
| 	cl_number& operator= (const unsigned long); | |
| 	cl_number& operator= (const float); | |
| 	cl_number& operator= (const double); | |
| #ifdef HAVE_LONGLONG | |
| 	cl_number& operator= (const long long); | |
| 	cl_number& operator= (const unsigned long long); | |
| #endif | |
| // Other constructors. | |
| //	cl_number (const char *); | |
| // Private pointer manipulations. | |
| 	cl_number (cl_private_thing); | |
| }; | |
| 
 | |
| // Private constructors. | |
| inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {} | |
| // The assignment operators: | |
| CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number) | |
| // The default constructors. | |
| inline cl_number::cl_number () | |
| 	: cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {} | |
| // The copy constructors. | |
| CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject) | |
| // Constructors and assignment operators from C numeric types. | |
| CL_DEFINE_INT_CONSTRUCTORS(cl_number) | |
| CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number) | |
| CL_DEFINE_LONG_CONSTRUCTORS(cl_number) | |
| CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number) | |
| #ifdef HAVE_LONGLONG | |
| CL_DEFINE_LONGLONG_CONSTRUCTORS(cl_number) | |
| CL_DEFINE_LONGLONG_ASSIGNMENT_OPERATORS(cl_number) | |
| #endif | |
| CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number) | |
| CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number) | |
| 
 | |
| 
 | |
| // Hack section. | |
|  | |
| // Conversions to subtypes without checking, template version: | |
| // the<cl_I>(x) converts x to a cl_I, without change of representation. | |
| template<class type> | |
| inline const type& the(const cl_number& x) | |
| { | |
| 	// check that sizeof(type)==sizeof(cl_number) | |
| 	typedef int assertion1 [1 - 2 * (sizeof(type) != sizeof(cl_number))]; | |
| 	return *(const type *) &x; | |
| } | |
| // Conversions to subtypes without checking, macro version: | |
| // The(cl_I)(x) converts x to a cl_I, without change of representation. | |
|   #define The(type)  *(const type *) & cl_identity | |
| // This inline function is for type checking purposes only. | |
|   inline const cl_number& cl_identity (const cl_number& x) { return x; } | |
| 
 | |
| }  // namespace cln | |
|  | |
| 
 | |
| // Conversions to subtypes: | |
| // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I | |
| // and then returns it without change of representation. | |
| #if 0 // no debug information   | |
|   #define As(type)  type##_As | |
|   #define CL_DEFINE_AS_CONVERSION(_class_)				\ | |
|     extern const _class_& _class_##_As (const cl_number& x);		\ | |
|     inline const _class_& _class_##_As (const _class_& x) { return x; } | |
| #else // Line number information for ease of debugging. | |
|   #define As(type)  type##_As cl_as_aux | |
|   #define cl_as_aux(expr)  (expr,__FILE__,__LINE__) | |
|   #define CL_DEFINE_AS_CONVERSION(_class_)				\ | |
|     extern const _class_& _class_##_As (const cl_number& x, const char * filename, int line); \ | |
|     inline const _class_& _class_##_As (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; } | |
| #endif | |
|  | |
| // Mutable(type,x); | |
| // x should be a variable `const type x' or `const type& x'. | |
| // This macro introduces a new variable `type& x' whose value can be | |
| // modified. Useful for modifying the argument of a function which takes | |
| // a `const type &x'. | |
| // Warning: To apply this to a function's formal parameter, a block { ... } | |
| // must be inserted. | |
|   #define Mutable(type,x)  \ | |
|     type __copied_##x = x;						\ | |
|     type& x = __copied_##x; | |
|  | |
| // DeclareType(type,x); | |
| // x should be a variable of some subtype of `cl_number'. type should be | |
| // a subtype of `cl_number'. A new variable of the given type is declared, | |
| // with name x and which refers to x (by reference, with const attribute). | |
|   #define DeclareType(type,x)  \ | |
|     const type& __tmp_##x = *(const type*) &x;				\ | |
|     const type& x = __tmp_##x; | |
|  | |
| #endif /* _CL_NUMBER_H */
 |