//  limits : headerfile for the free standard C++ library
//  
//  Copyright (C) 1999 by the free standard C++ Library Team
//                        see AUTHORS for more details
//
//  Homepage : http://www.inf.fu-berlin.de/~mkrueger/fscl/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either	
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Library General Public License for more details.
//  You should have received a copy of the GNU Library General Public
//  License along with this library; if not, write to the Free
//  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//  version : 0.1 last modified : 17.09.99


#ifndef __CPP_LIMITS
#define __CPP_LIMITS

#include<climits>

namespace std {
	
	enum float_round_style {
		round_indeterminate       = -1,
		round_toward_zero         =  0,
		round_to_nearest          =  1,
		round_toward_infinity     =  2,
		round_toward_neg_infinity =  3
    };

	enum float_denorm_style {
		denorm_indeterminate = -1,
		denorm_absent        = 0, 
		denorm_present       = 1 
	};

	
	template<class T>
	class numeric_limits
	{
		public:
			static const bool is_specialized = false;
			
			static T min() throw();
			static T max() throw();

			static const int  digits   = 0;
			static const int  digits10 = 0;

			static const bool is_signed  = false;
			static const bool is_integer = false;
			static const bool is_exact   = false;

			static const int  radix      = 0;

			static T epsilon() throw();
			static T round_error() throw();

			static const int  min_exponent   = 0;
			static const int  min_exponent10 = 0;
			static const int  max_exponent   = 0;
			static const int  max_exponent10 = 0;

			static const bool has_infinity      = false;
			static const bool has_quiet_NaN     = false;
			static const bool has_signaling_NaN = false;
			static const float_denorm_style has_denorm = denorm_absent;
			static const bool has_denorm_loss    = false;

			static T infinity() throw();
			static T quiet_NaN() throw();
			static T signaling_NaN() throw();
			static T denorm_min() throw();

			static const bool is_iec559  = false;
			static const bool is_bounded = false;
			static const bool is_modulo  = false;
		
			static const bool traps           = false;
			static const bool tinyness_before = false;
			static const float_round_style round_style = round_toward_zero;
	};

	class numeric_limits<bool>
	{
		public:
			static const bool is_specialized = true;
				
			static bool min() throw()
			{
				return false;
			}

			static bool max() throw()
			{
				return true;
			}

			static const int digits       = 8;
			static const int digits10     = 2;
			static const bool is_signed   = false;
			static const bool is_integer  = true;
			static const bool is_exact    = true;
			static const int radix        = 2;

			static bool epsilon() throw()
			{ 
				return 0; 
			}

			static bool round_error() throw()
			{
				return 0;
			}

			static const int min_exponent    = 0;
			static const int min_exponent10  = 0;
			static const int max_exponent    = 0;
			static const int max_exponent10  = 0;

			static const bool has_infinity      = false;
			static const bool has_quiet_NaN     = false;
			static const bool has_signaling_NaN = false;
			static const float_denorm_style has_denorm = denorm_absent;
			static const bool has_denorm_loss   = false;

			static bool infinity() throw()
			{
				return false; 
			}

			static bool quiet_NaN() throw()
			{ 
				return false; 
			}
        
			static bool signaling_NaN() throw()
			{ 
				return false; 
			}

			static bool denorm_min() throw()
			{
				return false;
			}

			static const bool is_iec559  = true;
			static const bool is_bounded = true;
			static const bool is_modulo  = true;
			
			static const bool traps = false;
			static const bool tinyness_before = false;
			static const float_round_style round_style = round_toward_zero;
			
	};

	template<> 
	class numeric_limits<char> {
		public:
			static const bool is_specialized = true;

			static char min() throw()
			{ 
				return CHAR_MIN; 
			}
        
			static char max() throw()
			{
				return CHAR_MAX; 
			}

			static const int digits      = CHAR_BIT - 1;
			static const int digits10    = 2;
			static const bool is_signed  = true;
			static const bool is_integer = true;
			static const bool is_exact   = true;
			static const int radix       = 2;

			static char epsilon() throw()
			{
				return 0; 
			}
			static char round_error() throw()
			{
				return 0; 
			}

			static const int min_exponent   = 0;
			static const int min_exponent10 = 0;
			static const int max_exponent   = 0;
			static const int max_exponent10 = 0;

			static const bool has_infinity      = false;
			static const bool has_quiet_NaN     = false;
			static const bool has_signaling_NaN = false;
			static const float_denorm_style has_denorm = denorm_absent;
			static const bool has_denorm_loss   = false;

			static char infinity() throw()
			{
				return 0; 
			}
			static char quiet_NaN() throw()
			{
				return 0; 
			}
			static char signaling_NaN() throw()
			{
				return 0;
			}
			static char denorm_min() throw()
			{
				return 0; 
			}

			static const bool is_iec559  = false;
			static const bool is_bounded = true;
			static const bool is_modulo  = false;

			static const bool traps           = false;
			static const bool tinyness_before = false;
			static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<signed char> {
		public:
			static const bool is_specialized = true;

			static signed char min() throw()
			{ 
				return SCHAR_MIN; 
			}
			static signed char max() throw()
			{ 
				return SCHAR_MAX; 
			}
			static const int digits      = CHAR_BIT - 1;
			static const int digits10    = 2;
			static const bool is_signed  = true;
			static const bool is_integer = true;
			static const bool is_exact   = true;
			static const int radix       = 2;
			static signed char epsilon() throw()
			{
				return 0;
			}
			static signed char round_error() throw()
			{
				return 0;
			}

			static const int min_exponent   = 0;
			static const int min_exponent10 = 0;
			static const int max_exponent   = 0;
			static const int max_exponent10 = 0;

			static const bool has_infinity      = false;
			static const bool has_quiet_NaN     = false;
			static const bool has_signaling_NaN = false;
			static const float_denorm_style has_denorm = denorm_absent;
			static const bool has_denorm_loss   = false;

			static signed char infinity() throw()
			{
				return 0; 
			}

			static signed char quiet_NaN() throw()
			{ 
				return 0; 
			}
			static signed char signaling_NaN() throw()
			{
				return 0;
			}
			static signed char denorm_min() throw()
			{
				return 0;
			}

			static const bool is_iec559  = false;
			static const bool is_bounded = true;
			static const bool is_modulo  = false;

			static const bool traps           = false;
			static const bool tinyness_before = false;
			static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<unsigned char> {
		public:
			static const bool is_specialized = true;

			static unsigned char min() throw()
			{ 
				return 0; 
			}
			static unsigned char max() throw()
			{ 
				return UCHAR_MAX; 
			}

			static const int digits      = CHAR_BIT;
			static const int digits10    = 2;
			static const bool is_signed  = false;
			static const bool is_integer = true;
			static const bool is_exact   = true;
			static const int radix       = 2;

			static unsigned char epsilon() throw()
			{
				return 0;
			}
			static unsigned char round_error() throw()
			{
				return 0;
			}

			static const int min_exponent   = 0;
			static const int min_exponent10 = 0;
			static const int max_exponent   = 0;
			static const int max_exponent10 = 0;

			static const bool has_infinity      = false;
			static const bool has_quiet_NaN     = false;
			static const bool has_signaling_NaN = false;
			static const float_denorm_style has_denorm = denorm_absent;
			static const bool has_denorm_loss   = false;

			static unsigned char infinity() throw()
			{
				return 0;
			}
			static unsigned char quiet_NaN() throw()
			{
				return 0;
			}
			static unsigned char signaling_NaN() throw()
			{
				return 0; 
			}
			static unsigned char denorm_min() throw()
			{
				return 0;
			}

			static const bool is_iec559  = false;
			static const bool is_bounded = true;
			static const bool is_modulo  = true;

			static const bool traps           = true;
			static const bool tinyness_before = false;
			static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<short> {
		public:
			static const bool is_specialized = true;

			static short min() throw()
			{ 
				return SHRT_MIN; 
			}
			static short max() throw()
			{ 
				return SHRT_MAX; 
			}

			static const int digits      = 15;
			static const int digits10    = 4;
			static const bool is_signed  = true;
			static const bool is_integer = true;
			static const bool is_exact   = true;
			static const int radix       = 2;
			static short epsilon() throw()
			{
				return 0; 
			}
			static short round_error() throw()
			{
				return 0;
			}

			static const int min_exponent   = 0;
			static const int min_exponent10 = 0;
			static const int max_exponent   = 0;
			static const int max_exponent10 = 0;

			static const bool has_infinity      = false;
			static const bool has_quiet_NaN     = false;
			static const bool has_signaling_NaN = false;
			static const float_denorm_style has_denorm = denorm_absent;
			static const bool has_denorm_loss   = false;

			static short infinity() throw()
			{
				return 0; 
			}

			static short quiet_NaN() throw()
			{
				return 0;
			}
			static short signaling_NaN() throw()
			{
				return 0;
			}
			static short denorm_min() throw()
			{
				return 0;
			}

			static const bool is_iec559  = false;
			static const bool is_bounded = true;
			static const bool is_modulo  = false;

			static const bool traps           = false;
			static const bool tinyness_before = false;
			static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<unsigned short> {
		static const bool is_specialized = true;

		static unsigned short min() throw()
		{ 
			return 0; 
		}
		static unsigned short max() throw()
		{ 
			return USHRT_MAX; 
		}

		static const int digits      = 16;
		static const int digits10    = 4;
		static const bool is_signed  = false;
		static const bool is_integer = true;
		static const bool is_exact   = true;
		static const int radix       = 2;
		static unsigned short epsilon() throw()
		{
			return 0; 
		}
		static unsigned short round_error() throw()
		{
			return 0; 
		}

		static const int min_exponent   = 0;
		static const int min_exponent10 = 0;
		static const int max_exponent   = 0;
		static const int max_exponent10 = 0;

		static const bool has_infinity      = false;
		static const bool has_quiet_NaN     = false;
		static const bool has_signaling_NaN = false;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static unsigned short infinity() throw()
		{
			return 0;
		}
		static unsigned short quiet_NaN() throw()
		{
			return 0;
		}
		static unsigned short signaling_NaN() throw()
		{ 
			return 0;
		}
		static unsigned short denorm_min() throw()
		{
			return 0;
		}

		static const bool is_iec559  = false;
		static const bool is_bounded = true;
		static const bool is_modulo  = true;

		static const bool traps           = true;
		static const bool tinyness_before = false;
		static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<int> {
		static const bool is_specialized = true;

		static int min() throw()
		{ 
			return INT_MIN; 
		}
		static int max() throw()
		{ 
			return INT_MAX; 
		}

		static const int digits      = 31;
		static const int digits10    = 9;
		static const bool is_signed  = true;
		static const bool is_integer = true;
		static const bool is_exact   = true;
		static const int radix       = 2;

		static int epsilon() throw()
		{
			return 0; 
		}
		static int round_error() throw()
		{
			return 0;
		}

		static const int min_exponent   = 0;
		static const int min_exponent10 = 0;
		static const int max_exponent   = 0;
		static const int max_exponent10 = 0;

		static const bool has_infinity      = false;
		static const bool has_quiet_NaN     = false;
		static const bool has_signaling_NaN = false;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static int infinity() throw()
		{
			return 0;
		}
		static int quiet_NaN() throw()
		{
			return 0;
		}
		static int signaling_NaN() throw()
		{
			return 0;
		}
		static int denorm_min() throw()
		{
			return 0;
		}

		static const bool is_iec559  = true;
		static const bool is_bounded = true;
		static const bool is_modulo  = false;

		static const bool traps           = false;
		static const bool tinyness_before = false;
		static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<unsigned int> {
		static const bool is_specialized = true;

		static unsigned int min() throw()
		{ 
			return 0; 
		}
		static unsigned int max() throw()
		{ 
			return UINT_MAX; 
		}

		static const int digits      = 32;
		static const int digits10    = 9;
		static const bool is_signed  = false;
		static const bool is_integer = true;
		static const bool is_exact   = true;
		static const int radix       = 2;
		static unsigned int epsilon() throw()
		{
			return 0; 
		}
		static unsigned int round_error() throw()
		{
			return 0;
		}

		static const int min_exponent   = 0;
		static const int min_exponent10 = 0;
		static const int max_exponent   = 0;
		static const int max_exponent10 = 0;

		static const bool has_infinity      = false;
		static const bool has_quiet_NaN     = false;
		static const bool has_signaling_NaN = false;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static unsigned int infinity() throw()
		{
			return 0; 
		}
		static unsigned int quiet_NaN() throw()
		{
			return 0;
		}
		static unsigned int signaling_NaN() throw()
		{
			return 0;
		}
		static unsigned int denorm_min() throw()
		{
			return 0;
		}

		static const bool is_iec559  = true;
		static const bool is_bounded = true;
		static const bool is_modulo  = true;

		static const bool traps           = true;
		static const bool tinyness_before = false;
		static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<long> {
		static const bool is_specialized = true;

		static long min() throw()
		{
			return LONG_MIN; 
		}

		static long max() throw()
		{
			return LONG_MAX; 
		}

		static const int digits      = 31;
		static const int digits10    = 9;
		static const bool is_signed  = true;
		static const bool is_integer = true;
		static const bool is_exact   = true;
		static const int radix       = 2;
		static long epsilon() throw()
		{
			return 0; 
		}
		static long round_error() throw()
		{
			return 0; 
		}

		static const int min_exponent   = 0;
		static const int min_exponent10 = 0;
		static const int max_exponent   = 0;
		static const int max_exponent10 = 0;

		static const bool has_infinity      = false;
		static const bool has_quiet_NaN     = false;
		static const bool has_signaling_NaN = false;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static long infinity() throw()
		{
			return 0;
		}
		static long quiet_NaN() throw()
		{
			return 0;
		}
		static long signaling_NaN() throw()
		{
			return 0;
		}
		static long denorm_min() throw()
		{
			return 0;
		}

		static const bool is_iec559  = true;
		static const bool is_bounded = true;
		static const bool is_modulo  = false;

		static const bool traps           = false;
		static const bool tinyness_before = false;
		static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<unsigned long> {
		static const bool is_specialized = true;

		static unsigned long min() throw()
		{ 
			return 0; 
		}
        
		static unsigned long max() throw()
		{
			return ULONG_MAX; 
		}

		static const int digits      = 32;
		static const int digits10    = 9;
		static const bool is_signed  = false;
		static const bool is_integer = true;
		static const bool is_exact   = true;
		static const int radix       = 2;
		static unsigned long epsilon() throw()
		{
			return 0; 
		}
		static unsigned long round_error() throw()
		{ 
			return 0; 
		}

		static const int min_exponent   = 0;
		static const int min_exponent10 = 0;
		static const int max_exponent   = 0;
		static const int max_exponent10 = 0;

		static const bool has_infinity      = false;
		static const bool has_quiet_NaN     = false;
		static const bool has_signaling_NaN = false;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static unsigned long infinity() throw()
		{
			return 0;
		}
		static unsigned long quiet_NaN() throw()
		{
			return 0;
		}
		static unsigned long signaling_NaN() throw()
		{
			return 0;
		}
		static unsigned long denorm_min() throw()
		{
			return 0;
		}

		static const bool is_iec559  = true;
		static const bool is_bounded = true;
		static const bool is_modulo  = true;

		static const bool traps           = true;
		static const bool tinyness_before = false;
		static const float_round_style round_style = round_toward_zero;
	};

	template<> 
	class numeric_limits<float> {
		static const bool is_specialized = true;

		static float min() throw()
		{
			return 1.17549435e-38F; 
		}

		static float max() throw()
		{
			return 3.40282347e+38F; 
		}

		static const int digits      = 24;
		static const int digits10    = 7;
		static const bool is_signed  = true;
		static const bool is_integer = false;
		static const bool is_exact   = false;
		static const int radix       = 2;
		static float epsilon() throw()
		{
			return 1.19209290e-07F; 
		}
		static float round_error() throw()
		{
			return 1.0f; 
		}

		static const int min_exponent   = -125;
		static const int min_exponent10 = -37;
		static const int max_exponent   = 128;
		static const int max_exponent10 = 38;

		static const bool has_infinity      = true;
		static const bool has_quiet_NaN     = true;
		static const bool has_signaling_NaN = true;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static float infinity() throw()
		{
			return 0; 
		}
		static float quiet_NaN() throw()
		{
			return 0;
		}
		static float signaling_NaN() throw()
		{ 
			return 0;
		}
		static float denorm_min() throw()
		{
			return min();
		}

		static const bool is_iec559  = true;
		static const bool is_bounded = true;
		static const bool is_modulo  = false;

		static const bool traps           = true;
		static const bool tinyness_before = true;
		static const float_round_style round_style = round_to_nearest;
	};

	template<> 
	class numeric_limits<double> {
		static const bool is_specialized = true;

		static double min() throw()
		{
			return 2.2250738585072014e-308; 
		}
		static double max() throw()
		{
			return 1.7976931348623157e+308;
		}

		static const int digits      = 53;
		static const int digits10    = 15;
		static const bool is_signed  = true;
		static const bool is_integer = false;
		static const bool is_exact   = false;
		static const int radix       = 2;

		static double epsilon() throw()
		{
			return 2.2204460492503131e-16; 
		}
		static double round_error() throw()
		{
			return 1.0; 
		}

		static const int min_exponent   = -1021;
		static const int min_exponent10 = -307;
		static const int max_exponent   = 1024;
		static const int max_exponent10 = 308;

		static const bool has_infinity      = true;
		static const bool has_quiet_NaN     = true;
		static const bool has_signaling_NaN = true;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static double infinity() throw()
		{
			return 0;
		}
		static double quiet_NaN() throw()
		{
			return 0;
		}
		static double signaling_NaN() throw()
		{
			return 0;
		}
		static double denorm_min() throw()
		{
			return 0;
		}

		static const bool is_iec559  = true;
		static const bool is_bounded = true;
		static const bool is_modulo  = false;

		static const bool traps           = true;
		static const bool tinyness_before = true;
		static const float_round_style round_style = round_to_nearest;
	};

	template<>
	class numeric_limits<long double> {
		static const bool is_specialized = true;

		static long double min() throw()
		{
			return 2.2250738585072014e-308; 
		}
		static long double max() throw()
		{
			return 1.7976931348623157e+308; 
		}

		static const int digits      = 64;
		static const int digits10    = 19;
		static const bool is_signed  = true;
		static const bool is_integer = false;
		static const bool is_exact   = false;
		static const int radix       = 2;
		
		static double epsilon() throw()
		{
			return 2.2204460492503131e-16; 
		}
		static double round_error() throw()
		{
			return 1.0; 
		}

		static const int min_exponent   = -16381;
		static const int min_exponent10 = -4931;
		static const int max_exponent   = 16384;
		static const int max_exponent10 = 4932;

		static const bool has_infinity      = true;
		static const bool has_quiet_NaN     = true;
		static const bool has_signaling_NaN = true;
		static const float_denorm_style has_denorm = denorm_absent;
		static const bool has_denorm_loss   = false;

		static long double infinity() throw()
		{
			return 0; 
		}
		static long double quiet_NaN() throw()
		{ 
			return 0; 
		}
		static long double signaling_NaN() throw()
		{
			return 0;
		}
		static long double denorm_min() throw()
		{
			return 0;
		}

		static const bool is_iec559  = true;
		static const bool is_bounded = true;
		static const bool is_modulo  = false;

		static const bool traps           = true;
		static const bool tinyness_before = true;
		static const float_round_style round_style = round_to_nearest;
	};
}

#endif
