From patchwork Sun Feb 23 10:32:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 323299 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 D58432C01AE for ; Sun, 23 Feb 2014 21:33:22 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=MoPbyUz/jLbs/qlZ/Do42oYG5QCmKZJbvNGGEvKhN8Rx+psnMH 51oX9s4muXFN/FK1VeVsPh1HlwoCJdDpq8OZtkBrVB/HMEKG5e2FHKsBruv0qX2n sqJYSmCI1XC3vQM1uaoLgLmiTqhZ/z3umR1cZJaNetTdEY+EvXpsJMzOI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=4bpDAEyoi3m2oRp0K6Jskrxb/mQ=; b=WJi95zVsmRpl8g7v7Lkj ivw4e9HFMpq6+7NQnVvWruxEuxLn17JJEvVVsGZFWSa2jJ9rn8cPWhvk+PBwJqTz 3VipfNdA34cOVBgoN9xiaZufB8es12ZRHUZba6+vlSzuaLSplK0cg/Xn3IhhyjL+ wQ1TR7qEB0xsLYMwc5ubpyk= Received: (qmail 22221 invoked by alias); 23 Feb 2014 10:32:56 -0000 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 Received: (qmail 22194 invoked by uid 89); 23 Feb 2014 10:32:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail3-relais-sop.national.inria.fr Received: from mail3-relais-sop.national.inria.fr (HELO mail3-relais-sop.national.inria.fr) (192.134.164.104) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Sun, 23 Feb 2014 10:32:52 +0000 Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail3-relais-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 23 Feb 2014 11:32:49 +0100 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.82) (envelope-from ) id 1WHWMa-0007mn-Po; Sun, 23 Feb 2014 11:32:48 +0100 Date: Sun, 23 Feb 2014 11:32:48 +0100 (CET) From: Marc Glisse To: libstdc++@gcc.gnu.org cc: gcc-patches@gcc.gnu.org Subject: [v3] complex functions with expression template reals Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 Hello, looking at this question: http://stackoverflow.com/q/21737186/1918193 I was surprised to see that libstdc++'s std::complex basically just works with user-defined types, even weird expression template ones, although that's not a supported use afaik. The only functions that fail seem to be exp and pow, both because they call polar with two arguments that have different (expression) types. I am not proposing to make this a supported use, but the cost of this small patch seems very low, and if it makes a couple users happy... Regtested with no problem on x86_64-linux-gnu, ok for stage 1? 2014-02-23 Marc Glisse * include/std/complex (__complex_exp, pow): Specify the template parameter in calls to std::polar, for expression templates. Index: libstdc++-v3/include/std/complex =================================================================== --- libstdc++-v3/include/std/complex (revision 208045) +++ libstdc++-v3/include/std/complex (working copy) @@ -728,21 +728,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #else template inline complex<_Tp> cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } #endif // 26.2.8/3 exp(__z): Returns the complex base e exponential of x template inline complex<_Tp> __complex_exp(const complex<_Tp>& __z) - { return std::polar(exp(__z.real()), __z.imag()); } + { return std::polar<_Tp>(exp(__z.real()), __z.imag()); } #if _GLIBCXX_USE_C99_COMPLEX inline __complex__ float __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } inline __complex__ double __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } inline __complex__ long double __complex_exp(const __complex__ long double& __z) @@ -988,21 +988,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION pow(const complex<_Tp>& __x, const _Tp& __y) { #ifndef _GLIBCXX_USE_C99_COMPLEX if (__x == _Tp()) return _Tp(); #endif if (__x.imag() == _Tp() && __x.real() > _Tp()) return pow(__x.real(), __y); complex<_Tp> __t = std::log(__x); - return std::polar(exp(__y * __t.real()), __y * __t.imag()); + return std::polar<_Tp>(exp(__y * __t.real()), __y * __t.imag()); } template inline complex<_Tp> __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } #if _GLIBCXX_USE_C99_COMPLEX inline __complex__ float __complex_pow(__complex__ float __x, __complex__ float __y) @@ -1025,22 +1025,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template inline complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { return __complex_pow(__x, __y); } #endif template inline complex<_Tp> pow(const _Tp& __x, const complex<_Tp>& __y) { - return __x > _Tp() ? std::polar(pow(__x, __y.real()), - __y.imag() * log(__x)) + return __x > _Tp() ? std::polar<_Tp>(pow(__x, __y.real()), + __y.imag() * log(__x)) : std::pow(complex<_Tp>(__x), __y); } /// 26.2.3 complex specializations /// complex specialization template<> struct complex { typedef float value_type; typedef __complex__ float _ComplexT;