diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2010-08-08 10:07:16 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2010-08-08 10:07:16 +0000 |
commit | 77fd1c1d447a899e176c92150ba84a72c29ecc52 (patch) | |
tree | 3dcbcfb53c58869df23992490255df43bde8eb51 | |
parent | 1159da448c8666d559371dc00a5d64a2ad1205b5 (diff) | |
download | gcc-77fd1c1d447a899e176c92150ba84a72c29ecc52.zip gcc-77fd1c1d447a899e176c92150ba84a72c29ecc52.tar.gz gcc-77fd1c1d447a899e176c92150ba84a72c29ecc52.tar.bz2 |
cmath: Implement US 136.
2010-08-08 Paolo Carlini <paolo.carlini@oracle.com>
* include/c_global/cmath: Implement US 136.
* include/tr1_impl/cmath: Do not bring fpclassify, etc from namespace
std, define namespace tr1.
* testsuite/26_numerics/headers/cmath/
c99_classification_macros_c++0x.cc: New.
From-SVN: r162995
-rw-r--r-- | libstdc++-v3/ChangeLog | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/c_global/cmath | 248 | ||||
-rw-r--r-- | libstdc++-v3/include/tr1_impl/cmath | 126 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++0x.cc | 92 |
4 files changed, 458 insertions, 16 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4056c5a..b70de70 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2010-08-08 Paolo Carlini <paolo.carlini@oracle.com> + + * include/c_global/cmath: Implement US 136. + * include/tr1_impl/cmath: Do not bring fpclassify, etc from namespace + std, define namespace tr1. + * testsuite/26_numerics/headers/cmath/ + c99_classification_macros_c++0x.cc: New. + 2010-08-06 David Malcolm <dmalcolm@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath index 1267211..02ca6af 100644 --- a/libstdc++-v3/include/c_global/cmath +++ b/libstdc++-v3/include/c_global/cmath @@ -497,6 +497,252 @@ _GLIBCXX_END_NAMESPACE _GLIBCXX_BEGIN_NAMESPACE(std) +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + inline int + fpclassify(float __x) + { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, __x); } + + inline int + fpclassify(double __x) + { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, __x); } + + inline int + fpclassify(long double __x) + { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, __x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + int>::__type + fpclassify(_Tp __x) + { return __x != 0 ? FP_NORMAL : FP_ZERO; } + + inline bool + isfinite(float __x) + { return __builtin_isfinite(__x); } + + inline bool + isfinite(double __x) + { return __builtin_isfinite(__x); } + + inline bool + isfinite(long double __x) + { return __builtin_isfinite(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + bool>::__type + isfinite(_Tp __x) + { return true; } + + inline bool + isinf(float __x) + { return __builtin_isinf(__x); } + + inline bool + isinf(double __x) + { return __builtin_isinf(__x); } + + inline bool + isinf(long double __x) + { return __builtin_isinf(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + bool>::__type + isinf(_Tp __x) + { return false; } + + inline bool + isnan(float __x) + { return __builtin_isnan(__x); } + + inline bool + isnan(double __x) + { return __builtin_isnan(__x); } + + inline bool + isnan(long double __x) + { return __builtin_isnan(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + bool>::__type + isnan(_Tp __x) + { return false; } + + inline bool + isnormal(float __x) + { return __builtin_isnormal(__x); } + + inline bool + isnormal(double __x) + { return __builtin_isnormal(__x); } + + inline bool + isnormal(long double __x) + { return __builtin_isnormal(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + bool>::__type + isnormal(_Tp __x) + { return __x != 0 ? true : false; } + + inline bool + signbit(float __x) + { return __builtin_signbit(__x); } + + inline bool + signbit(double __x) + { return __builtin_signbit(__x); } + + inline bool + signbit(long double __x) + { return __builtin_signbit(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + bool>::__type + signbit(_Tp __x) + { return __x < 0 ? true : false; } + + inline bool + isgreater(float __x, float __y) + { return __builtin_isgreater(__x, __y); } + + inline bool + isgreater(double __x, double __y) + { return __builtin_isgreater(__x, __y); } + + inline bool + isgreater(long double __x, long double __y) + { return __builtin_isgreater(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename + __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value + && __is_arithmetic<_Up>::__value), bool>::__type + isgreater(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return __builtin_isgreater(__type(__x), __type(__y)); + } + + inline bool + isgreaterequal(float __x, float __y) + { return __builtin_isgreaterequal(__x, __y); } + + inline bool + isgreaterequal(double __x, double __y) + { return __builtin_isgreaterequal(__x, __y); } + + inline bool + isgreaterequal(long double __x, long double __y) + { return __builtin_isgreaterequal(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename + __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value + && __is_arithmetic<_Up>::__value), bool>::__type + isgreaterequal(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return __builtin_isgreaterequal(__type(__x), __type(__y)); + } + + inline bool + isless(float __x, float __y) + { return __builtin_isless(__x, __y); } + + inline bool + isless(double __x, double __y) + { return __builtin_isless(__x, __y); } + + inline bool + isless(long double __x, long double __y) + { return __builtin_isless(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename + __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value + && __is_arithmetic<_Up>::__value), bool>::__type + isless(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return __builtin_isless(__type(__x), __type(__y)); + } + + inline bool + islessequal(float __x, float __y) + { return __builtin_islessequal(__x, __y); } + + inline bool + islessequal(double __x, double __y) + { return __builtin_islessequal(__x, __y); } + + inline bool + islessequal(long double __x, long double __y) + { return __builtin_islessequal(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename + __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value + && __is_arithmetic<_Up>::__value), bool>::__type + islessequal(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return __builtin_islessequal(__type(__x), __type(__y)); + } + + inline bool + islessgreater(float __x, float __y) + { return __builtin_islessgreater(__x, __y); } + + inline bool + islessgreater(double __x, double __y) + { return __builtin_islessgreater(__x, __y); } + + inline bool + islessgreater(long double __x, long double __y) + { return __builtin_islessgreater(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename + __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value + && __is_arithmetic<_Up>::__value), bool>::__type + islessgreater(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return __builtin_islessgreater(__type(__x), __type(__y)); + } + + inline bool + isunordered(float __x, float __y) + { return __builtin_isunordered(__x, __y); } + + inline bool + isunordered(double __x, double __y) + { return __builtin_isunordered(__x, __y); } + + inline bool + isunordered(long double __x, long double __y) + { return __builtin_isunordered(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename + __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value + && __is_arithmetic<_Up>::__value), bool>::__type + isunordered(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return __builtin_isunordered(__type(__x), __type(__y)); + } + +#else + template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type @@ -606,6 +852,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __builtin_isunordered(__type(__f1), __type(__f2)); } +#endif + _GLIBCXX_END_NAMESPACE #endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ diff --git a/libstdc++-v3/include/tr1_impl/cmath b/libstdc++-v3/include/tr1_impl/cmath index 5807380..cf460dd 100644 --- a/libstdc++-v3/include/tr1_impl/cmath +++ b/libstdc++-v3/include/tr1_impl/cmath @@ -1,6 +1,6 @@ // TR1 cmath -*- C++ -*- -// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -294,21 +294,115 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1 #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC /// Function template definitions [8.16.3]. - using std::signbit; - - using std::fpclassify; - - using std::isfinite; - using std::isinf; - using std::isnan; - using std::isnormal; - - using std::isgreater; - using std::isgreaterequal; - using std::isless; - using std::islessequal; - using std::islessgreater; - using std::isunordered; + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + fpclassify(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, __type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isfinite(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isfinite(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isinf(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isinf(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isnan(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isnan(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isnormal(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isnormal(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + signbit(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_signbit(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isgreater(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isgreater(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isgreaterequal(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isgreaterequal(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isless(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isless(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + islessequal(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_islessequal(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + islessgreater(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_islessgreater(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isunordered(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isunordered(__type(__f1), __type(__f2)); + } + #endif #endif diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++0x.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++0x.cc new file mode 100644 index 0000000..413fe69 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++0x.cc @@ -0,0 +1,92 @@ +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++0x" } +// { dg-do compile { xfail uclibc } } +// { dg-excess-errors "" { target uclibc } } + +#include <cmath> + +void fpclassify() { } + +void isfinite() { } + +void isinf() { } + +void isnan() { } + +void isnormal() { } + +void signbit() { } + +void isgreater() { } + +void isgreaterequal() { } + +void isless() { } + +void islessequal() { } + +void islessgreater() { } + +void isunordered() { } + +#if _GLIBCXX_USE_C99_MATH +template <typename _Tp, typename _Up = _Tp> + void test_c99_classify() + { + bool test __attribute__((unused)) = true; + + typedef _Tp fp_type_one; + typedef _Up fp_type_two; + fp_type_one f1 = 1.0; + fp_type_two f2 = 3.0; + int resi; + bool res; + + resi = std::fpclassify(f1); + res = std::isfinite(f2); + res = std::isinf(f1); + res = std::isnan(f2); + res = std::isnormal(f1); + res = std::signbit(f2); + res = std::isgreater(f1, f2); + res = std::isgreaterequal(f1, f2); + res = std::isless(f1, f2); + res = std::islessequal(f1,f2); + res = std::islessgreater(f1, f2); + res = std::isunordered(f1, f2); + resi = resi; // Suppress unused warning. + res = res; + } +#endif + +int main() +{ +#if _GLIBCXX_USE_C99_MATH + test_c99_classify<float>(); + test_c99_classify<double>(); + test_c99_classify<long double>(); + test_c99_classify<float, double>(); + test_c99_classify<float, long double>(); + test_c99_classify<double, float>(); + test_c99_classify<double, long double>(); + test_c99_classify<long double, float>(); + test_c99_classify<long double, double>(); +#endif + return 0; +} |