Mercurial > projects > ldc
view dmd2/root/port.c @ 1558:3adcb70700cb
Added back option to disable metadata generation and users. Set USE_METADATA to OFF in ccmake.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail com> |
---|---|
date | Fri, 31 Jul 2009 11:28:31 +0200 |
parents | 638d16625da2 |
children |
line wrap: on
line source
// Copyright (c) 1999-2009 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com #include "port.h" #if __DMC__ #include <math.h> #include <float.h> #include <fp.h> #include <time.h> #include <stdlib.h> #include <string.h> double Port::nan = NAN; double Port::infinity = INFINITY; double Port::dbl_max = DBL_MAX; double Port::dbl_min = DBL_MIN; long double Port::ldbl_max = LDBL_MAX; int Port::isNan(double r) { return ::isnan(r); } int Port::isNan(long double r) { return ::isnan(r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } int Port::isFinite(double r) { return ::isfinite(r); } int Port::isInfinity(double r) { return (::fpclassify(r) == FP_INFINITE); } int Port::Signbit(double r) { return ::signbit(r); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { // LOCALE_SLIST for Windows return ","; } const wchar_t *Port::wlist_separator() { // LOCALE_SLIST for Windows return L","; } char *Port::strupr(char *s) { return ::strupr(s); } #endif #if _MSC_VER // Disable useless warnings about unreferenced functions #pragma warning (disable : 4514) #include <math.h> #include <float.h> #include <time.h> #include <errno.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <limits> // for std::numeric_limits static unsigned long nanarray[2]= { 0xFFFFFFFF, 0x7FFFFFFF }; //static unsigned long nanarray[2] = {0,0x7FF80000 }; double Port::nan = (*(double *)nanarray); //static unsigned long infinityarray[2] = {0,0x7FF00000 }; static double zero = 0; double Port::infinity = 1 / zero; double Port::dbl_max = DBL_MAX; double Port::dbl_min = DBL_MIN; long double Port::ldbl_max = LDBL_MAX; struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { Port::infinity = std::numeric_limits<long double>::infinity(); } int Port::isNan(double r) { return ::_isnan(r); } int Port::isNan(long double r) { return ::_isnan(r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* MSVC doesn't have 80 bit long doubles */ return isSignallingNan((double) r); } int Port::isFinite(double r) { return ::_finite(r); } int Port::isInfinity(double r) { return (::_fpclass(r) & (_FPCLASS_NINF | _FPCLASS_PINF)); } int Port::Signbit(double r) { return (long)(((long *)&(r))[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { if (y == 0) return 1; // even if x is NAN return ::pow(x, y); } unsigned _int64 Port::strtoull(const char *p, char **pend, int base) { unsigned _int64 number = 0; int c; int error; #define ULLONG_MAX ((unsigned _int64)~0I64) while (isspace(*p)) /* skip leading white space */ p++; if (*p == '+') p++; switch (base) { case 0: base = 10; /* assume decimal base */ if (*p == '0') { base = 8; /* could be octal */ p++; switch (*p) { case 'x': case 'X': base = 16; /* hex */ p++; break; #if BINARY case 'b': case 'B': base = 2; /* binary */ p++; break; #endif } } break; case 16: /* skip over '0x' and '0X' */ if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) p += 2; break; #if BINARY case 2: /* skip over '0b' and '0B' */ if (*p == '0' && (p[1] == 'b' || p[1] == 'B')) p += 2; break; #endif } error = 0; for (;;) { c = *p; if (isdigit(c)) c -= '0'; else if (isalpha(c)) c = (c & ~0x20) - ('A' - 10); else /* unrecognized character */ break; if (c >= base) /* not in number base */ break; if ((ULLONG_MAX - c) / base < number) error = 1; number = number * base + c; p++; } if (pend) *pend = (char *)p; if (error) { number = ULLONG_MAX; errno = ERANGE; } return number; } char *Port::ull_to_string(char *buffer, ulonglong ull) { _ui64toa(ull, buffer, 10); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { _ui64tow(ull, buffer, 10); return buffer; } double Port::ull_to_double(ulonglong ull) { double d; if ((__int64) ull < 0) { // MSVC doesn't implement the conversion d = (double) (__int64)(ull - 0x8000000000000000i64); d += (double)(signed __int64)(0x7FFFFFFFFFFFFFFFi64) + 1.0; } else d = (double)(__int64)ull; return d; } const char *Port::list_separator() { // LOCALE_SLIST for Windows return ","; } const wchar_t *Port::wlist_separator() { // LOCALE_SLIST for Windows return L","; } char *Port::strupr(char *s) { return ::strupr(s); } #endif #if linux || __APPLE__ || __FreeBSD__ #include <math.h> #if linux #include <bits/nan.h> #include <bits/mathdef.h> #endif #include <time.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <float.h> static double zero = 0; double Port::nan = NAN; double Port::infinity = 1 / zero; double Port::dbl_max = 1.7976931348623157e308; double Port::dbl_min = 5e-324; long double Port::ldbl_max = LDBL_MAX; struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { // gcc nan's have the sign bit set by default, so turn it off // Need the volatile to prevent gcc from doing incorrect // constant folding. volatile long double foo; foo = NAN; if (signbit(foo)) // signbit sometimes, not always, set foo = -foo; // turn off sign bit Port::nan = foo; #if __FreeBSD__ // LDBL_MAX comes out as infinity. Fix. static unsigned char x[sizeof(long double)] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F }; Port::ldbl_max = *(long double *)&x[0]; #endif } #undef isnan int Port::isNan(double r) { #if __APPLE__ return __inline_isnan(r); #else return ::isnan(r); #endif } int Port::isNan(long double r) { #if __APPLE__ return __inline_isnan(r); #else return ::isnan(r); #endif } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } #undef isfinite int Port::isFinite(double r) { return ::finite(r); } #undef isinf int Port::isInfinity(double r) { #if __APPLE__ return fpclassify(r) == FP_INFINITE; #else return ::isinf(r); #endif } #undef signbit int Port::Signbit(double r) { return (long)(((long *)&r)[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { return ","; } const wchar_t *Port::wlist_separator() { return L","; } char *Port::strupr(char *s) { char *t = s; while (*s) { *s = toupper(*s); s++; } return t; } #endif #if __sun&&__SVR4 #define __C99FEATURES__ 1 // Needed on Solaris for NaN and more #include <math.h> #include <time.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <float.h> #include <ieeefp.h> static double zero = 0; double Port::nan = NAN; double Port::infinity = 1 / zero; double Port::dbl_max = 1.7976931348623157e308; double Port::dbl_min = 5e-324; long double Port::ldbl_max = LDBL_MAX; struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { // gcc nan's have the sign bit set by default, so turn it off // Need the volatile to prevent gcc from doing incorrect // constant folding. volatile long double foo; foo = NAN; if (signbit(foo)) // signbit sometimes, not always, set foo = -foo; // turn off sign bit Port::nan = foo; } int Port::isNan(double r) { return isnan(r); } int Port::isNan(long double r) { return isnan(r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } #undef isfinite int Port::isFinite(double r) { return finite(r); } int Port::isInfinity(double r) { return isinf(r); } #undef signbit int Port::Signbit(double r) { return (long)(((long *)&r)[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { return ","; } const wchar_t *Port::wlist_separator() { return L","; } char *Port::strupr(char *s) { char *t = s; while (*s) { *s = toupper(*s); s++; } return t; } #endif #if IN_GCC #include <math.h> #include <bits/nan.h> #include <bits/mathdef.h> #include <time.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> static double zero = 0; double Port::nan = NAN; double Port::infinity = 1 / zero; double Port::dbl_max = 1.7976931348623157e308; double Port::dbl_min = 5e-324; long double Port::ldbl_max = LDBL_MAX; #include "d-gcc-real.h" extern "C" bool real_isnan (const real_t *); struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { Port::infinity = real_t::getinfinity(); Port::nan = real_t::getnan(real_t::LongDouble); } #undef isnan int Port::isNan(double r) { #if __APPLE__ return __inline_isnan(r); #else return ::isnan(r); #endif } int Port::isNan(long double r) { return real_isnan(&r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } #undef isfinite int Port::isFinite(double r) { return ::finite(r); } #undef isinf int Port::isInfinity(double r) { return ::isinf(r); } #undef signbit int Port::Signbit(double r) { return (long)(((long *)&r)[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { swprintf(buffer, L"%llu", ull); return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { return ","; } const wchar_t *Port::wlist_separator() { return L","; } char *Port::strupr(char *s) { char *t = s; while (*s) { *s = toupper(*s); s++; } return t; } #endif