From patchwork Sun Aug 8 10:08:27 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 61206 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 22B2FB6EE8 for ; Sun, 8 Aug 2010 20:08:47 +1000 (EST) Received: (qmail 9957 invoked by alias); 8 Aug 2010 10:08:40 -0000 Received: (qmail 9925 invoked by uid 22791); 8 Aug 2010 10:08:37 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from vsmtp14.tin.it (HELO vsmtp14.tin.it) (212.216.176.118) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 08 Aug 2010 10:08:31 +0000 Received: from [192.168.0.4] (79.17.189.251) by vsmtp14.tin.it (8.5.113) id 4BCE303709ACF850; Sun, 8 Aug 2010 12:08:28 +0200 Message-ID: <4C5E821B.2060403@oracle.com> Date: Sun, 08 Aug 2010 12:08:27 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.11) Gecko/20100714 SUSE/3.0.6 Thunderbird/3.0.6 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: libstdc++ Subject: [v3] Implement US 136 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, tested x86_64-linux, committed to mainline. Paolo. /////////////////// 2010-08-08 Paolo Carlini * 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. Index: include/tr1_impl/cmath =================================================================== --- include/tr1_impl/cmath (revision 162994) +++ include/tr1_impl/cmath (working copy) @@ -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 @@ #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC /// Function template definitions [8.16.3]. - using std::signbit; - - using std::fpclassify; + template + 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)); + } - using std::isfinite; - using std::isinf; - using std::isnan; - using std::isnormal; + template + 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)); + } - using std::isgreater; - using std::isgreaterequal; - using std::isless; - using std::islessequal; - using std::islessgreater; - using std::isunordered; + template + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 Index: include/c_global/cmath =================================================================== --- include/c_global/cmath (revision 162994) +++ include/c_global/cmath (working copy) @@ -497,7 +497,253 @@ _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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type fpclassify(_Tp __f) @@ -606,6 +852,8 @@ return __builtin_isunordered(__type(__f1), __type(__f2)); } +#endif + _GLIBCXX_END_NAMESPACE #endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ Index: testsuite/26_numerics/headers/cmath/c99_classification_macros_c++0x.cc =================================================================== --- testsuite/26_numerics/headers/cmath/c99_classification_macros_c++0x.cc (revision 0) +++ testsuite/26_numerics/headers/cmath/c99_classification_macros_c++0x.cc (revision 0) @@ -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 +// . + +// { dg-options "-std=gnu++0x" } +// { dg-do compile { xfail uclibc } } +// { dg-excess-errors "" { target uclibc } } + +#include + +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 + 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(); + test_c99_classify(); + test_c99_classify(); + test_c99_classify(); + test_c99_classify(); + test_c99_classify(); + test_c99_classify(); + test_c99_classify(); + test_c99_classify(); +#endif + return 0; +}