/*
 *
 * This file and its contents are the property of The MathWorks, Inc.
 * 
 * This file contains confidential proprietary information.
 * The reproduction, distribution, utilization or the communication
 * of this file or any part thereof is strictly prohibited.
 * Offenders will be held liable for the payment of damages.
 *
 * Copyright 1999-2012 The MathWorks, Inc.
 *
 */
#ifndef PST_STL_LIMITS
#define PST_STL_LIMITS

#include <__polyspace__float.h>
#include <__polyspace__limits.h>
#include <__polyspace__wchar.h>

#ifdef PST_VISUAL
#pragma push_macro("max")
#pragma push_macro("min")
#endif

/* undefined it ! */
#undef min
#undef max


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

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

 class	__pst__Num_Base
 {
 public:
        static  const __ps_bool                      is_specialized = __ps_false;
        static  const __ps_bool                      is_signed = __ps_false;
        static  const __ps_bool                      is_integer = __ps_false;
        static  const __ps_bool                      is_exact = __ps_false;
        static  const int                       radix = 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 __ps_bool                      has_infinity = __ps_false;
        static  const __ps_bool                      has_quiet_NaN = __ps_false;
        static  const __ps_bool                      has_signaling_NaN = __ps_false;
        static  const float_denorm_style        has_denorm = denorm_absent;
        static  const __ps_bool                      has_denorm_loss = __ps_false;

        static  const __ps_bool                      is_iec559 = __ps_false;
        static  const __ps_bool                      is_bounded = __ps_false;
        static  const __ps_bool                      is_modulo = __ps_false;

        static  const __ps_bool                      traps = __ps_false;
        static  const __ps_bool                      tinyness_before = __ps_false;
        static  const float_round_style         round_style = round_toward_zero;
	static	const int			digits = 0;
	static  const int			digits10 = 0;	
 };

template<class T> 
class numeric_limits : public __pst__Num_Base
 {
  public:
	static	T				min() throw();
	static	T				max() throw();
	static	T				epsilon() throw();
	static	T				round_error() throw();
		
	static	T				infinity() throw();
	static	T				quiet_NaN() throw();
	static	T				signaling_NaN() throw();
	static	T				denorm_min() throw();
 };

// These class are used to specialize numeric_limits

class __pst__Num_int_base : public __pst__Num_Base
{
public:
	static	const __ps_bool			is_bounded 	= __ps_true;
	static	const __ps_bool			is_exact	= __ps_true;
	static	const __ps_bool			is_integer	= __ps_true;
	static	const __ps_bool			is_modulo	= __ps_true;
	static	const __ps_bool			is_specialized	= __ps_true;
	static	const int			radix		= 2;
};

class __pst__Num_float_base : public __pst__Num_Base
{
public:
	static	const float_denorm_style	has_denorm		= denorm_present;
	static	const __ps_bool			has_denorm_loss		= __ps_true;
	static	const __ps_bool			has_infinity		= __ps_true;
	static	const __ps_bool			has_quiet_NaN		= __ps_true;
	static	const __ps_bool			has_signaling_NaN	= __ps_true;
	static	const __ps_bool			is_bounded		= __ps_true;
	static	const __ps_bool			is_exact		= __ps_false;
	static	const __ps_bool			is_iec559		= __ps_true;
	static  const __ps_bool			is_integer		= __ps_false;
	static	const __ps_bool			is_modulo		= __ps_false;
	static	const __ps_bool			is_signed		= __ps_true;
	static	const __ps_bool			is_specialized		= __ps_true;
	static	const __ps_bool			tinyness_before		= __ps_true;
	static	const __ps_bool			traps			= __ps_true;
	static	const float_round_style		round_style		= round_to_nearest;
	static	const int			radix			= FLT_RADIX;		
};

/////////////////////////////////////////////////////

template<> class numeric_limits<char> : public __pst__Num_int_base
{
public:
	static	char				min() throw() { return CHAR_MIN; }
	static	char				max() throw() { return CHAR_MAX; }
	static	char				epsilon() throw() { return 0; }
	static	char				round_error() throw() { return 0; }
	static	char				denorm_min() throw() { return 0; }
	static	char				infinity() throw() { return 0; }
	static	char				quiet_NaN() throw() { return 0; }
	static	char				signaling_NaN() throw() {return 0; }
	 	
	static 	const __ps_bool			is_signed = (CHAR_MIN != 0);
	static	const int			digits = (CHAR_BIT - (CHAR_MIN != 0 ?1:0));
	static	const int			digits10 = (CHAR_BIT - (CHAR_MIN != 0 ? 1 : 0))*301L/1000;
};

#if defined(_WCHAR_T) 



template<> class numeric_limits<wchar_t> : public __pst__Num_int_base
{
public:
	static  wchar_t                            min() throw() { return WCHAR_MIN; }
        static  wchar_t                            max() throw() { return WCHAR_MAX; }
        static  wchar_t                            epsilon() throw() { return 0; }
        static  wchar_t                            round_error() throw() { return 0; }
        static  wchar_t                            denorm_min() throw() { return 0; }
        static  wchar_t                            infinity() throw() { return 0; }
        static  wchar_t                            quiet_NaN() throw() { return 0; }
        static  wchar_t                            signaling_NaN() throw() {return 0; }

	static  const __ps_bool                    is_signed = (WCHAR_MIN != 0);
        static  const int                          digits = (CHAR_BIT * sizeof(wchar_t) - (WCHAR_MIN != 0 ?1:0));
        static  const int                          digits10 = (CHAR_BIT * sizeof(wchar_t) - (CHAR_MIN != 0 ? 1 : 0))*301L/1000;
};

#endif

template<> class numeric_limits<signed char> : public __pst__Num_int_base
{
public:
	static  signed char                        min() throw() { return SCHAR_MIN; }
        static  signed char                        max() throw() { return SCHAR_MAX; }
        static  signed char                        epsilon() throw() { return 0; }
        static  signed char                        round_error() throw() { return 0; }
        static  signed char                        denorm_min() throw() { return 0; }
        static  signed char                        infinity() throw() { return 0; }
        static  signed char                        quiet_NaN() throw() { return 0; }
        static  signed char                        signaling_NaN() throw() {return 0; }

        static  const __ps_bool                         is_signed = __ps_true;
	static  const int                          digits = (CHAR_BIT - 1);
        static  const int                          digits10 = (CHAR_BIT - 1)*301L/1000;
};

template<> class numeric_limits<unsigned char> : public __pst__Num_int_base
{
public:
        static  unsigned char                      min() throw() { return UCHAR_MIN; }
        static  unsigned char                      max() throw() { return UCHAR_MAX; }
        static  unsigned char                      epsilon() throw() { return 0; }
        static  unsigned char                      round_error() throw() { return 0; }
        static  unsigned char                      denorm_min() throw() { return 0; }
        static  unsigned char                      infinity() throw() { return 0; }
        static  unsigned char                      quiet_NaN() throw() { return 0; }
        static  unsigned char                      signaling_NaN() throw() {return 0; }

        static  const __ps_bool                         is_signed = __ps_false;
        static  const int                          digits = CHAR_BIT;
        static  const int                          digits10 = (CHAR_BIT)*301L/1000;
};

template<> class numeric_limits<short> : public __pst__Num_int_base
{
public:
 	static  short                           min() throw() { return SHRT_MIN; }
        static  short                           max() throw() { return SHRT_MAX; }
        static  short                           epsilon() throw() { return 0; }
        static  short                           round_error() throw() { return 0; }
        static  short                           denorm_min() throw() { return 0; }
        static  short                           infinity() throw() { return 0; }
        static  short                           quiet_NaN() throw() { return 0; }
        static  short                           signaling_NaN() throw() {return 0; }
        static  const __ps_bool                      is_signed = __ps_true;
	static  const int                       digits = (CHAR_BIT *sizeof(short) - 1);
        static  const int                       digits10 = (CHAR_BIT * sizeof(short) - 1)*301L/1000;
};

template<> class numeric_limits<unsigned short> : public __pst__Num_int_base
{
public:
        static  unsigned short                  min() throw() { return 0; }
        static  unsigned short                  max() throw() { return USHRT_MAX; }
        static  unsigned short                  epsilon() throw() { return 0; }
        static  unsigned short                  round_error() throw() { return 0; }
        static  unsigned short                  denorm_min() throw() { return 0; }
        static  unsigned short                  infinity() throw() { return 0; }
        static  unsigned short                  quiet_NaN() throw() { return 0; }
        static  unsigned short                  signaling_NaN() throw() {return 0; }
        static  const __ps_bool                      is_signed = __ps_false;
        static  const int                       digits = (CHAR_BIT * sizeof(unsigned short));
        static  const int                       digits10 = (CHAR_BIT * sizeof(unsigned short))*301L/1000;
};

template<> class numeric_limits<int> : public __pst__Num_int_base
{
public:
        static  int                  min() throw() { return INT_MIN; }
        static  int                  max() throw() { return INT_MAX; }
        static  int                  epsilon() throw() { return 0; }
        static  int                  round_error() throw() { return 0; }
        static  int                  denorm_min() throw() { return 0; }
        static  int                  infinity() throw() { return 0; }
        static  int                  quiet_NaN() throw() { return 0; }
        static  int                  signaling_NaN() throw() {return 0; }
        static  const __ps_bool           is_signed = __ps_true;
        static  const int            digits = (CHAR_BIT * sizeof(int) - 1);
        static  const int            digits10 = (CHAR_BIT * sizeof(int) - 1)*301L/1000;
};

template<> class numeric_limits<unsigned int> : public __pst__Num_int_base
{
public:
        static  unsigned int                  min() throw() { return 0; }
        static  unsigned int                  max() throw() { return UINT_MAX; }
        static  unsigned int                  epsilon() throw() { return 0; }
        static  unsigned int                  round_error() throw() { return 0; }
        static  unsigned int                  denorm_min() throw() { return 0; }
        static  unsigned int                  infinity() throw() { return 0; }
        static  unsigned int                  quiet_NaN() throw() { return 0; }
        static  unsigned int                  signaling_NaN() throw() {return 0; }
        static  const __ps_bool           	      is_signed = __ps_false;
        static  const int                     digits = (CHAR_BIT * sizeof(unsigned int));
        static  const int                     digits10 = (CHAR_BIT * sizeof(unsigned int))*301L/1000;
};

template<> class numeric_limits<long> : public __pst__Num_int_base
{
public:
        static  long                  min() throw() { return LONG_MIN; }
        static  long                  max() throw() { return LONG_MAX; }
        static  long                  epsilon() throw() { return 0; }
        static  long                  round_error() throw() { return 0; }
        static  long                  denorm_min() throw() { return 0; }
        static  long                  infinity() throw() { return 0; }
        static  long                  quiet_NaN() throw() { return 0; }
        static  long                  signaling_NaN() throw() {return 0; }
        static  const __ps_bool            is_signed = __ps_true;
        static  const int             digits = (CHAR_BIT * sizeof(long) - 1);
        static  const int             digits10 = (CHAR_BIT * sizeof(long) - 1)*301L/1000;
};

template<> class numeric_limits<unsigned long> : public __pst__Num_int_base
{
public:
        static  unsigned long                  min() throw() { return 0; }
        static  unsigned long                  max() throw() { return ULONG_MAX; }
        static  unsigned long                  epsilon() throw() { return 0; }
        static  unsigned long                  round_error() throw() { return 0; }
        static  unsigned long                  denorm_min() throw() { return 0; }
        static  unsigned long                  infinity() throw() { return 0; }
        static  unsigned long                  quiet_NaN() throw() { return 0; }
        static  unsigned long                  signaling_NaN() throw() {return 0; }
        static  const __ps_bool            	       is_signed = __ps_false;
        static  const int                      digits = (CHAR_BIT * sizeof(unsigned long));
        static  const int                      digits10 = (CHAR_BIT * sizeof(unsigned long))*301L/1000;
};

template<> class numeric_limits<long long> : public __pst__Num_int_base
{
public:
        static  long long                  min() throw() { return LLONG_MIN; }
        static  long long                  max() throw() { return LLONG_MAX; }
        static  long long                  epsilon() throw() { return 0; }
        static  long long                  round_error() throw() { return 0; }
        static  long long                  denorm_min() throw() { return 0; }
        static  long long                  infinity() throw() { return 0; }
        static  long long                  quiet_NaN() throw() { return 0; }
        static  long long                  signaling_NaN() throw() {return 0; }
        static  const __ps_bool                 is_signed = __ps_true;
	static  const int                  digits = (CHAR_BIT * sizeof(long long) - 1);
        static  const int                  digits10 = (CHAR_BIT * sizeof(long long) - 1)*301L/1000;
};

template<> class numeric_limits<unsigned long long> : public __pst__Num_int_base
{
public:
        static  unsigned long long                  min() throw() { return 0; }
        static  unsigned long long                  max() throw() { return ULLONG_MAX; }
        static  unsigned long long                  epsilon() throw() { return 0; }
        static  unsigned long long                  round_error() throw() { return 0; }
        static  unsigned long long                  denorm_min() throw() { return 0; }
        static  unsigned long long                  infinity() throw() { return 0; }
        static  unsigned long long                  quiet_NaN() throw() { return 0; }
        static  unsigned long long                  signaling_NaN() throw() {return 0; }
        static  const __ps_bool                 	    is_signed = __ps_false;
        static  const int                           digits = (CHAR_BIT * sizeof (unsigned long long));
        static  const int                           digits10 = (CHAR_BIT * sizeof(unsigned long long))*301L/1000;
};

#ifdef _BOOL
template<> class numeric_limits<__ps_bool> : public __pst__Num_int_base
{
public:
	static  __ps_bool                            min() throw() { return __ps_false; }
        static  __ps_bool                            max() throw() { return __ps_true; }
        static  __ps_bool                            epsilon() throw() { return 0; }
        static  __ps_bool                            round_error() throw() { return 0; }
        static  __ps_bool                            denorm_min() throw() { return 0; }
        static  __ps_bool                            infinity() throw() { return 0; }
        static  __ps_bool                            quiet_NaN() throw() { return 0; }
        static  __ps_bool                            signaling_NaN() throw() {return 0; }
	static	const __ps_bool			is_modulo 	= __ps_false;
	static	const __ps_bool			is_signed 	= __ps_false;
        static  const int                       digits 		= 1;
        static  const int                       digits10 	= 0;
};
#endif

template<> class numeric_limits<float> : public __pst__Num_float_base
{
public:
#ifdef __FLT_HAS_DENORM__
        static  const float_denorm_style         has_denorm = (__FLT_HAS_DENORM__) ? denorm_present : denorm_absent;
#endif
#ifdef __FLT_HAS_QUIET_NAN__
        static  const __ps_bool                  has_quiet_NaN = __FLT_HAS_QUIET_NAN__;
#endif
#ifdef __FLT_HAS_INFINITY__
	static  const __ps_bool	                 has_infinity = __FLT_HAS_INFINITY__;
#endif
	static  float                            min() throw() { return FLT_MIN; }
        static  float                            max() throw() { return FLT_MAX; }
        static  float                            epsilon() throw() { return FLT_EPSILON; }
        static  float                            round_error() throw() { return 0.5; }
        static  float                            denorm_min() throw() {
#ifdef __FLT_DENORM_MIN__
            return __FLT_DENORM_MIN__;
#else
	    volatile float ret = 0.0F; return ret;
#endif
	}
        static  float                            infinity() throw() { volatile float ret = 0.0F; return ret; }
        static  float                            quiet_NaN() throw() { volatile float ret = 0.0F; return ret; }
        static  float                            signaling_NaN() throw() { volatile float ret = 0.0F; return ret; }
        static  const int                        digits          = FLT_MANT_DIG;
        static  const int                        digits10        = FLT_DIG;
	static	const int			 max_exponent	 = (int)FLT_MAX_EXP;
	static	const int			 max_exponent10	 = (int)FLT_MAX_10_EXP;
	static	const int			 min_exponent	 = (int)FLT_MIN_EXP;
	static  const int			 min_exponent10	 = (int)FLT_MIN_10_EXP;
};

template<> class numeric_limits<double> : public __pst__Num_float_base
{
public:
#ifdef __DBL_HAS_DENORM__
        static  const float_denorm_style          has_denorm = (__DBL_HAS_DENORM__) ? denorm_present : denorm_absent;
#endif
#ifdef __DBL_HAS_INFINITY__
	static  const __ps_bool	                  has_infinity = __DBL_HAS_INFINITY__;
#endif
#ifdef __DBL_HAS_QUIET_NAN__
        static  const __ps_bool                   has_quiet_NaN = __DBL_HAS_QUIET_NAN__;
#endif
        static  double                            min() throw() { return DBL_MIN; }
        static  double                            max() throw() { return DBL_MAX; }
        static  double                            epsilon() throw() { return DBL_EPSILON; }
        static  double                            round_error() throw() { return 0.5; }
        static  double                            denorm_min() throw() { 
#ifdef __DBL_DENORM_MIN__
            return __DBL_DENORM_MIN__;
#else
	    volatile double ret = 0.0; return ret; 
#endif
	}
        static  double                            infinity() throw() { volatile double ret = 0.0; return ret; }
        static  double                            quiet_NaN() throw() { volatile double ret = 0.0; return ret; }
        static  double                            signaling_NaN() throw() { volatile double ret = 0.0; return ret; }
        static  const int                        digits          = DBL_MANT_DIG;
        static  const int                        digits10        = DBL_DIG;
        static  const int                        max_exponent    = (int)DBL_MAX_EXP;
        static  const int                        max_exponent10  = (int)DBL_MAX_10_EXP;
        static  const int                        min_exponent    = (int)DBL_MIN_EXP;
        static  const int                        min_exponent10  = (int)DBL_MIN_10_EXP;
};

template<> class numeric_limits<long double> : public __pst__Num_float_base
{
public:
#ifdef __LDBL_HAS_DENORM__
        static  const float_denorm_style         has_denorm = (__LDBL_HAS_DENORM__) ? denorm_present : denorm_absent;
#endif
#ifdef __LDBL_HAS_INFINITY__
	static  const __ps_bool	                 has_infinity = __LDBL_HAS_INFINITY__;
#endif
#ifdef __LDBL_HAS_QUIET_NAN__
        static  const __ps_bool                  has_quiet_NaN = __LDBL_HAS_QUIET_NAN__;
#endif
        static  long double                      min() throw() { volatile long double ret = 0.0; return ret; }
        static  long double                      max() throw() { volatile long double ret = 0.0; return ret;  }
        static  long double                      epsilon() throw() { 
#ifdef __LDBL_EPSILON__
            return __LDBL_EPSILON__;
#else
	    volatile long double ret = 0.0; return ret; 
#endif
	}
        static  long double                      round_error() throw() { return 0.5; }
        static  long double                      denorm_min() throw() {
#ifdef __LDBL_DENORM_MIN__
            return __LDBL_DENORM_MIN__;
#else
	    volatile long double ret = 0.0; return ret;
#endif
	}
        static  long double                      infinity() throw() { volatile long double ret = 0.0; return ret; }
        static  long double                      quiet_NaN() throw() { volatile long double ret = 0.0; return ret; }
        static  long double                      signaling_NaN() throw() { volatile long double ret = 0.0; return ret; }
        static  const int                        digits          = LDBL_MANT_DIG;
        static  const int                        digits10        = LDBL_DIG;
        static  const int                        max_exponent    = (int)LDBL_MAX_EXP;
        static  const int                        max_exponent10  = (int)LDBL_MAX_10_EXP;
        static  const int                        min_exponent    = (int)LDBL_MIN_EXP;
        static  const int                        min_exponent10  = (int)LDBL_MIN_10_EXP;
};
 	
}

#ifdef __PST_IMPLICIT_USING_STD
/* Implicitly include a using directive for the STD namespace when this
   preprocessing flag is TRUE. */
using namespace std;
#endif /* ifdef __PST_IMPLICIT_USING_STD */

#ifdef PST_VISUAL
#pragma pop_macro("max")
#pragma pop_macro("min")
#endif

#endif /* PST_STL_LIMITS */
