From patchwork Fri Oct 21 13:42:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 685121 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3t0n0z2wKkz9t1S for ; Sat, 22 Oct 2016 00:42:27 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=TjlzCLIY; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:message-id:date:mime-version :content-type; q=dns; s=default; b=cpmY894SyDPFw9d1FmBKOH+cfxaUv Y0AUfeU0wrrGWFiligY9oGh2WfycJODQLXasEpp628Zm322rSR5LoBocn0SGUWdD St7BM2bY8aBTgXuYbc/Rt3MwvvkW/001gAjbpV6Q8qs4WYs9Ieg5Nv2o3FhyYK84 ffpLvV0vX4TDmc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:message-id:date:mime-version :content-type; s=default; bh=2inywQjLfSz0h8eSgZZKQeGH0j4=; b=Tjl zCLIY/yZVKolWaqeM1T5VHR9Rs06cnqTyKBPJ75ZcE1Q+Gm6njKQzFYRv4nwOCw3 Jv3q6ZueXFAxAaIZsLOlQasXWwrJ6UqhBx0B/7aBwoNGvHsKolPkzt118kHE2srF WYsXayHU4SwcWPJdNoFeBa+A6sYjP96flMl3zOgE= Received: (qmail 63417 invoked by alias); 21 Oct 2016 13:42:17 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 63393 invoked by uid 89); 21 Oct 2016 13:42:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=1657, sk:2aa6a34, 2676, no X-HELO: mx1.redhat.com To: GNU C Library From: Florian Weimer Subject: [PATCH] Define iszero as a function template for C++ [BZ #20715] Message-ID: <2b2fa3c4-5bd6-4025-717f-fe2e2ee19555@redhat.com> Date: Fri, 21 Oct 2016 15:42:03 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 Tested on x86_64, ppc64, ppc64le, s390x, aarch64. I'm not sure if the new test is particularly meaningful, but at least it catches syntax errors in . Thanks, Florian math: Define iszero as a function template for C++ [BZ #20715] This increases compatibility with C++ code which is forced to compile with _GNU_SOURCE. 2016-10-21 Florian Weimer [BZ #20715] * math/math.h [__cplusplus] (iszero): Define as function template. * math/Makefile [CXX] (tests): Add test-math-iszero. (CFLAGS-test-math-iszero.cc): Set. * math/test-math-iszero.cc: New file. diff --git a/math/Makefile b/math/Makefile index 2aa6a34..7cecba5 100644 --- a/math/Makefile +++ b/math/Makefile @@ -165,7 +165,7 @@ tests-static = test-fpucw-static test-fpucw-ieee-static \ test-signgam-ullong-static test-signgam-ullong-init-static ifneq (,$(CXX)) -tests += test-math-isinff +tests += test-math-isinff test-math-iszero endif ifneq (no,$(PERL)) @@ -267,6 +267,7 @@ CFLAGS-test-signgam-ullong-static.c = -std=c99 CFLAGS-test-signgam-ullong-init-static.c = -std=c99 CFLAGS-test-math-isinff.cc = -std=gnu++11 +CFLAGS-test-math-iszero.cc = -std=gnu++11 CFLAGS-test-iszero-excess-precision.c = -fexcess-precision=standard CFLAGS-test-iseqsig-excess-precision.c = -fexcess-precision=standard diff --git a/math/math.h b/math/math.h index 880b4a0..0220d08 100644 --- a/math/math.h +++ b/math/math.h @@ -335,11 +335,25 @@ enum # define issubnormal(x) (fpclassify (x) == FP_SUBNORMAL) /* Return nonzero value if X is zero. */ -# ifdef __SUPPORT_SNAN__ -# define iszero(x) (fpclassify (x) == FP_ZERO) -# else -# define iszero(x) (((__typeof (x)) (x)) == 0) -# endif +# ifndef __cplusplus +# ifdef __SUPPORT_SNAN__ +# define iszero(x) (fpclassify (x) == FP_ZERO) +# else +# define iszero(x) (((__typeof (x)) (x)) == 0) +# endif +# else /* __cplusplus */ +__END_DECLS +template inline bool +iszero (__T __val) +{ +# ifdef __SUPPORT_SNAN__ + return fpclassify (__val) == FP_ZERO; +# else + return __val == 0; +# endif +} +__BEGIN_DECLS +# endif /* __cplusplus */ #endif /* Use IEC_60559_BFP_EXT. */ #ifdef __USE_MISC diff --git a/math/test-math-iszero.cc b/math/test-math-iszero.cc new file mode 100644 index 0000000..b4a9c2e --- /dev/null +++ b/math/test-math-iszero.cc @@ -0,0 +1,86 @@ +/* Test for the C++ implementation of iszero. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define _GNU_SOURCE 1 +#include +#include + +#include + +static bool errors; + +static void +check (int actual, int expected, const char *actual_expr, int line) +{ + if (actual != expected) + { + errors = true; + printf ("%s:%d: error: %s\n", __FILE__, line, actual_expr); + printf ("%s:%d: expected: %d\n", __FILE__, line, expected); + printf ("%s:%d: actual: %d\n", __FILE__, line, actual); + } +} + +#define CHECK(actual, expected) \ + check ((actual), (expected), #actual, __LINE__) + +template +static void +check_type () +{ + typedef std::numeric_limits limits; + CHECK (iszero (T{}), 1); + CHECK (iszero (T{0}), 1); + CHECK (iszero (T{1}), 0); + CHECK (iszero (T{-1}), 0); + CHECK (iszero (limits::min ()), 0); + CHECK (iszero (-limits::min ()), 0); + CHECK (iszero (limits::max ()), 0); + CHECK (iszero (-limits::max ()), 0); + if (limits::has_infinity) + { + CHECK (iszero (limits::infinity ()), 0); + CHECK (iszero (-limits::infinity ()), 0); + } + CHECK (iszero (limits::epsilon ()), 0); + CHECK (iszero (-limits::epsilon ()), 0); + if (limits::has_quiet_NaN) + CHECK (iszero (limits::quiet_NaN ()), 0); + if (limits::has_signaling_NaN) + CHECK (iszero (limits::signaling_NaN ()), 0); + if (limits::has_signaling_NaN) + CHECK (iszero (limits::signaling_NaN ()), 0); + CHECK (iszero (limits::denorm_min ()), + std::numeric_limits::has_denorm == std::denorm_absent); + CHECK (iszero (-limits::denorm_min ()), + std::numeric_limits::has_denorm == std::denorm_absent); +} + +static int +do_test (void) +{ + check_type (); + check_type (); +#ifndef NO_LONG_DOUBLE + check_type (); +#endif + return errors; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c"