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.
		
		
		
		
		
			
		
			
				
					
					
						
							254 lines
						
					
					
						
							8.6 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							254 lines
						
					
					
						
							8.6 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
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								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);
							 | 
						|
									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);
							 | 
						|
								// 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)
							 | 
						|
								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 */
							 |