1*f8a1b7d9SAlexander Kabaev// TR1 complex -*- C++ -*- 2*f8a1b7d9SAlexander Kabaev 3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2006 Free Software Foundation, Inc. 4*f8a1b7d9SAlexander Kabaev// 5*f8a1b7d9SAlexander Kabaev// This file is part of the GNU ISO C++ Library. This library is free 6*f8a1b7d9SAlexander Kabaev// software; you can redistribute it and/or modify it under the 7*f8a1b7d9SAlexander Kabaev// terms of the GNU General Public License as published by the 8*f8a1b7d9SAlexander Kabaev// Free Software Foundation; either version 2, or (at your option) 9*f8a1b7d9SAlexander Kabaev// any later version. 10*f8a1b7d9SAlexander Kabaev 11*f8a1b7d9SAlexander Kabaev// This library is distributed in the hope that it will be useful, 12*f8a1b7d9SAlexander Kabaev// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*f8a1b7d9SAlexander Kabaev// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*f8a1b7d9SAlexander Kabaev// GNU General Public License for more details. 15*f8a1b7d9SAlexander Kabaev 16*f8a1b7d9SAlexander Kabaev// You should have received a copy of the GNU General Public License along 17*f8a1b7d9SAlexander Kabaev// with this library; see the file COPYING. If not, write to the Free 18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19*f8a1b7d9SAlexander Kabaev// USA. 20*f8a1b7d9SAlexander Kabaev 21*f8a1b7d9SAlexander Kabaev// As a special exception, you may use this file as part of a free software 22*f8a1b7d9SAlexander Kabaev// library without restriction. Specifically, if other files instantiate 23*f8a1b7d9SAlexander Kabaev// templates or use macros or inline functions from this file, or you compile 24*f8a1b7d9SAlexander Kabaev// this file and link it with other files to produce an executable, this 25*f8a1b7d9SAlexander Kabaev// file does not by itself cause the resulting executable to be covered by 26*f8a1b7d9SAlexander Kabaev// the GNU General Public License. This exception does not however 27*f8a1b7d9SAlexander Kabaev// invalidate any other reasons why the executable file might be covered by 28*f8a1b7d9SAlexander Kabaev// the GNU General Public License. 29*f8a1b7d9SAlexander Kabaev 30*f8a1b7d9SAlexander Kabaev/** @file tr1/complex 31*f8a1b7d9SAlexander Kabaev * This is a TR1 C++ Library header. 32*f8a1b7d9SAlexander Kabaev */ 33*f8a1b7d9SAlexander Kabaev 34*f8a1b7d9SAlexander Kabaev#ifndef _TR1_COMPLEX 35*f8a1b7d9SAlexander Kabaev#define _TR1_COMPLEX 1 36*f8a1b7d9SAlexander Kabaev 37*f8a1b7d9SAlexander Kabaev#include "../complex" 38*f8a1b7d9SAlexander Kabaev#include <tr1/common.h> 39*f8a1b7d9SAlexander Kabaev 40*f8a1b7d9SAlexander Kabaev// namespace std::tr1 41*f8a1b7d9SAlexander Kabaevnamespace std 42*f8a1b7d9SAlexander Kabaev{ 43*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(tr1) 44*f8a1b7d9SAlexander Kabaev 45*f8a1b7d9SAlexander Kabaev // Forward declarations. 46*f8a1b7d9SAlexander Kabaev template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 47*f8a1b7d9SAlexander Kabaev template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 48*f8a1b7d9SAlexander Kabaev template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 49*f8a1b7d9SAlexander Kabaev 50*f8a1b7d9SAlexander Kabaev template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 51*f8a1b7d9SAlexander Kabaev template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 52*f8a1b7d9SAlexander Kabaev template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 53*f8a1b7d9SAlexander Kabaev template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); 54*f8a1b7d9SAlexander Kabaev 55*f8a1b7d9SAlexander Kabaev /// @brief acos(__z) [8.1.2]. 56*f8a1b7d9SAlexander Kabaev // Effects: Behaves the same as C99 function cacos, defined 57*f8a1b7d9SAlexander Kabaev // in subclause 7.3.5.1. 58*f8a1b7d9SAlexander Kabaev template<typename _Tp> 59*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 60*f8a1b7d9SAlexander Kabaev __complex_acos(const std::complex<_Tp>& __z) 61*f8a1b7d9SAlexander Kabaev { 62*f8a1b7d9SAlexander Kabaev const std::complex<_Tp> __t = std::tr1::asin(__z); 63*f8a1b7d9SAlexander Kabaev const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 64*f8a1b7d9SAlexander Kabaev return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 65*f8a1b7d9SAlexander Kabaev } 66*f8a1b7d9SAlexander Kabaev 67*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1 68*f8a1b7d9SAlexander Kabaev inline __complex__ float 69*f8a1b7d9SAlexander Kabaev __complex_acos(__complex__ float __z) 70*f8a1b7d9SAlexander Kabaev { return __builtin_cacosf(__z); } 71*f8a1b7d9SAlexander Kabaev 72*f8a1b7d9SAlexander Kabaev inline __complex__ double 73*f8a1b7d9SAlexander Kabaev __complex_acos(__complex__ double __z) 74*f8a1b7d9SAlexander Kabaev { return __builtin_cacos(__z); } 75*f8a1b7d9SAlexander Kabaev 76*f8a1b7d9SAlexander Kabaev inline __complex__ long double 77*f8a1b7d9SAlexander Kabaev __complex_acos(const __complex__ long double& __z) 78*f8a1b7d9SAlexander Kabaev { return __builtin_cacosl(__z); } 79*f8a1b7d9SAlexander Kabaev 80*f8a1b7d9SAlexander Kabaev template<typename _Tp> 81*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 82*f8a1b7d9SAlexander Kabaev acos(const std::complex<_Tp>& __z) 83*f8a1b7d9SAlexander Kabaev { return __complex_acos(__z.__rep()); } 84*f8a1b7d9SAlexander Kabaev#else 85*f8a1b7d9SAlexander Kabaev template<typename _Tp> 86*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 87*f8a1b7d9SAlexander Kabaev acos(const std::complex<_Tp>& __z) 88*f8a1b7d9SAlexander Kabaev { return __complex_acos(__z); } 89*f8a1b7d9SAlexander Kabaev#endif 90*f8a1b7d9SAlexander Kabaev 91*f8a1b7d9SAlexander Kabaev /// @brief asin(__z) [8.1.3]. 92*f8a1b7d9SAlexander Kabaev // Effects: Behaves the same as C99 function casin, defined 93*f8a1b7d9SAlexander Kabaev // in subclause 7.3.5.2. 94*f8a1b7d9SAlexander Kabaev template<typename _Tp> 95*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 96*f8a1b7d9SAlexander Kabaev __complex_asin(const std::complex<_Tp>& __z) 97*f8a1b7d9SAlexander Kabaev { 98*f8a1b7d9SAlexander Kabaev std::complex<_Tp> __t(-__z.imag(), __z.real()); 99*f8a1b7d9SAlexander Kabaev __t = std::tr1::asinh(__t); 100*f8a1b7d9SAlexander Kabaev return std::complex<_Tp>(__t.imag(), -__t.real()); 101*f8a1b7d9SAlexander Kabaev } 102*f8a1b7d9SAlexander Kabaev 103*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1 104*f8a1b7d9SAlexander Kabaev inline __complex__ float 105*f8a1b7d9SAlexander Kabaev __complex_asin(__complex__ float __z) 106*f8a1b7d9SAlexander Kabaev { return __builtin_casinf(__z); } 107*f8a1b7d9SAlexander Kabaev 108*f8a1b7d9SAlexander Kabaev inline __complex__ double 109*f8a1b7d9SAlexander Kabaev __complex_asin(__complex__ double __z) 110*f8a1b7d9SAlexander Kabaev { return __builtin_casin(__z); } 111*f8a1b7d9SAlexander Kabaev 112*f8a1b7d9SAlexander Kabaev inline __complex__ long double 113*f8a1b7d9SAlexander Kabaev __complex_asin(const __complex__ long double& __z) 114*f8a1b7d9SAlexander Kabaev { return __builtin_casinl(__z); } 115*f8a1b7d9SAlexander Kabaev 116*f8a1b7d9SAlexander Kabaev template<typename _Tp> 117*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 118*f8a1b7d9SAlexander Kabaev asin(const std::complex<_Tp>& __z) 119*f8a1b7d9SAlexander Kabaev { return __complex_asin(__z.__rep()); } 120*f8a1b7d9SAlexander Kabaev#else 121*f8a1b7d9SAlexander Kabaev template<typename _Tp> 122*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 123*f8a1b7d9SAlexander Kabaev asin(const std::complex<_Tp>& __z) 124*f8a1b7d9SAlexander Kabaev { return __complex_asin(__z); } 125*f8a1b7d9SAlexander Kabaev#endif 126*f8a1b7d9SAlexander Kabaev 127*f8a1b7d9SAlexander Kabaev /// @brief atan(__z) [8.1.4]. 128*f8a1b7d9SAlexander Kabaev // Effects: Behaves the same as C99 function catan, defined 129*f8a1b7d9SAlexander Kabaev // in subclause 7.3.5.3. 130*f8a1b7d9SAlexander Kabaev template<typename _Tp> 131*f8a1b7d9SAlexander Kabaev std::complex<_Tp> 132*f8a1b7d9SAlexander Kabaev __complex_atan(const std::complex<_Tp>& __z) 133*f8a1b7d9SAlexander Kabaev { 134*f8a1b7d9SAlexander Kabaev const _Tp __r2 = __z.real() * __z.real(); 135*f8a1b7d9SAlexander Kabaev const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 136*f8a1b7d9SAlexander Kabaev 137*f8a1b7d9SAlexander Kabaev _Tp __num = __z.imag() + _Tp(1.0); 138*f8a1b7d9SAlexander Kabaev _Tp __den = __z.imag() - _Tp(1.0); 139*f8a1b7d9SAlexander Kabaev 140*f8a1b7d9SAlexander Kabaev __num = __r2 + __num * __num; 141*f8a1b7d9SAlexander Kabaev __den = __r2 + __den * __den; 142*f8a1b7d9SAlexander Kabaev 143*f8a1b7d9SAlexander Kabaev return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 144*f8a1b7d9SAlexander Kabaev _Tp(0.25) * log(__num / __den)); 145*f8a1b7d9SAlexander Kabaev } 146*f8a1b7d9SAlexander Kabaev 147*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1 148*f8a1b7d9SAlexander Kabaev inline __complex__ float 149*f8a1b7d9SAlexander Kabaev __complex_atan(__complex__ float __z) 150*f8a1b7d9SAlexander Kabaev { return __builtin_catanf(__z); } 151*f8a1b7d9SAlexander Kabaev 152*f8a1b7d9SAlexander Kabaev inline __complex__ double 153*f8a1b7d9SAlexander Kabaev __complex_atan(__complex__ double __z) 154*f8a1b7d9SAlexander Kabaev { return __builtin_catan(__z); } 155*f8a1b7d9SAlexander Kabaev 156*f8a1b7d9SAlexander Kabaev inline __complex__ long double 157*f8a1b7d9SAlexander Kabaev __complex_atan(const __complex__ long double& __z) 158*f8a1b7d9SAlexander Kabaev { return __builtin_catanl(__z); } 159*f8a1b7d9SAlexander Kabaev 160*f8a1b7d9SAlexander Kabaev template<typename _Tp> 161*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 162*f8a1b7d9SAlexander Kabaev atan(const std::complex<_Tp>& __z) 163*f8a1b7d9SAlexander Kabaev { return __complex_atan(__z.__rep()); } 164*f8a1b7d9SAlexander Kabaev#else 165*f8a1b7d9SAlexander Kabaev template<typename _Tp> 166*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 167*f8a1b7d9SAlexander Kabaev atan(const std::complex<_Tp>& __z) 168*f8a1b7d9SAlexander Kabaev { return __complex_atan(__z); } 169*f8a1b7d9SAlexander Kabaev#endif 170*f8a1b7d9SAlexander Kabaev 171*f8a1b7d9SAlexander Kabaev /// @brief acosh(__z) [8.1.5]. 172*f8a1b7d9SAlexander Kabaev // Effects: Behaves the same as C99 function cacosh, defined 173*f8a1b7d9SAlexander Kabaev // in subclause 7.3.6.1. 174*f8a1b7d9SAlexander Kabaev template<typename _Tp> 175*f8a1b7d9SAlexander Kabaev std::complex<_Tp> 176*f8a1b7d9SAlexander Kabaev __complex_acosh(const std::complex<_Tp>& __z) 177*f8a1b7d9SAlexander Kabaev { 178*f8a1b7d9SAlexander Kabaev std::complex<_Tp> __t((__z.real() - __z.imag()) 179*f8a1b7d9SAlexander Kabaev * (__z.real() + __z.imag()) - _Tp(1.0), 180*f8a1b7d9SAlexander Kabaev _Tp(2.0) * __z.real() * __z.imag()); 181*f8a1b7d9SAlexander Kabaev __t = std::sqrt(__t); 182*f8a1b7d9SAlexander Kabaev 183*f8a1b7d9SAlexander Kabaev return std::log(__t + __z); 184*f8a1b7d9SAlexander Kabaev } 185*f8a1b7d9SAlexander Kabaev 186*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1 187*f8a1b7d9SAlexander Kabaev inline __complex__ float 188*f8a1b7d9SAlexander Kabaev __complex_acosh(__complex__ float __z) 189*f8a1b7d9SAlexander Kabaev { return __builtin_cacoshf(__z); } 190*f8a1b7d9SAlexander Kabaev 191*f8a1b7d9SAlexander Kabaev inline __complex__ double 192*f8a1b7d9SAlexander Kabaev __complex_acosh(__complex__ double __z) 193*f8a1b7d9SAlexander Kabaev { return __builtin_cacosh(__z); } 194*f8a1b7d9SAlexander Kabaev 195*f8a1b7d9SAlexander Kabaev inline __complex__ long double 196*f8a1b7d9SAlexander Kabaev __complex_acosh(const __complex__ long double& __z) 197*f8a1b7d9SAlexander Kabaev { return __builtin_cacoshl(__z); } 198*f8a1b7d9SAlexander Kabaev 199*f8a1b7d9SAlexander Kabaev template<typename _Tp> 200*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 201*f8a1b7d9SAlexander Kabaev acosh(const std::complex<_Tp>& __z) 202*f8a1b7d9SAlexander Kabaev { return __complex_acosh(__z.__rep()); } 203*f8a1b7d9SAlexander Kabaev#else 204*f8a1b7d9SAlexander Kabaev template<typename _Tp> 205*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 206*f8a1b7d9SAlexander Kabaev acosh(const std::complex<_Tp>& __z) 207*f8a1b7d9SAlexander Kabaev { return __complex_acosh(__z); } 208*f8a1b7d9SAlexander Kabaev#endif 209*f8a1b7d9SAlexander Kabaev 210*f8a1b7d9SAlexander Kabaev /// @brief asinh(__z) [8.1.6]. 211*f8a1b7d9SAlexander Kabaev // Effects: Behaves the same as C99 function casin, defined 212*f8a1b7d9SAlexander Kabaev // in subclause 7.3.6.2. 213*f8a1b7d9SAlexander Kabaev template<typename _Tp> 214*f8a1b7d9SAlexander Kabaev std::complex<_Tp> 215*f8a1b7d9SAlexander Kabaev __complex_asinh(const std::complex<_Tp>& __z) 216*f8a1b7d9SAlexander Kabaev { 217*f8a1b7d9SAlexander Kabaev std::complex<_Tp> __t((__z.real() - __z.imag()) 218*f8a1b7d9SAlexander Kabaev * (__z.real() + __z.imag()) + _Tp(1.0), 219*f8a1b7d9SAlexander Kabaev _Tp(2.0) * __z.real() * __z.imag()); 220*f8a1b7d9SAlexander Kabaev __t = std::sqrt(__t); 221*f8a1b7d9SAlexander Kabaev 222*f8a1b7d9SAlexander Kabaev return std::log(__t + __z); 223*f8a1b7d9SAlexander Kabaev } 224*f8a1b7d9SAlexander Kabaev 225*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1 226*f8a1b7d9SAlexander Kabaev inline __complex__ float 227*f8a1b7d9SAlexander Kabaev __complex_asinh(__complex__ float __z) 228*f8a1b7d9SAlexander Kabaev { return __builtin_casinhf(__z); } 229*f8a1b7d9SAlexander Kabaev 230*f8a1b7d9SAlexander Kabaev inline __complex__ double 231*f8a1b7d9SAlexander Kabaev __complex_asinh(__complex__ double __z) 232*f8a1b7d9SAlexander Kabaev { return __builtin_casinh(__z); } 233*f8a1b7d9SAlexander Kabaev 234*f8a1b7d9SAlexander Kabaev inline __complex__ long double 235*f8a1b7d9SAlexander Kabaev __complex_asinh(const __complex__ long double& __z) 236*f8a1b7d9SAlexander Kabaev { return __builtin_casinhl(__z); } 237*f8a1b7d9SAlexander Kabaev 238*f8a1b7d9SAlexander Kabaev template<typename _Tp> 239*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 240*f8a1b7d9SAlexander Kabaev asinh(const std::complex<_Tp>& __z) 241*f8a1b7d9SAlexander Kabaev { return __complex_asinh(__z.__rep()); } 242*f8a1b7d9SAlexander Kabaev#else 243*f8a1b7d9SAlexander Kabaev template<typename _Tp> 244*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 245*f8a1b7d9SAlexander Kabaev asinh(const std::complex<_Tp>& __z) 246*f8a1b7d9SAlexander Kabaev { return __complex_asinh(__z); } 247*f8a1b7d9SAlexander Kabaev#endif 248*f8a1b7d9SAlexander Kabaev 249*f8a1b7d9SAlexander Kabaev /// @brief atanh(__z) [8.1.7]. 250*f8a1b7d9SAlexander Kabaev // Effects: Behaves the same as C99 function catanh, defined 251*f8a1b7d9SAlexander Kabaev // in subclause 7.3.6.3. 252*f8a1b7d9SAlexander Kabaev template<typename _Tp> 253*f8a1b7d9SAlexander Kabaev std::complex<_Tp> 254*f8a1b7d9SAlexander Kabaev __complex_atanh(const std::complex<_Tp>& __z) 255*f8a1b7d9SAlexander Kabaev { 256*f8a1b7d9SAlexander Kabaev const _Tp __i2 = __z.imag() * __z.imag(); 257*f8a1b7d9SAlexander Kabaev const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 258*f8a1b7d9SAlexander Kabaev 259*f8a1b7d9SAlexander Kabaev _Tp __num = _Tp(1.0) + __z.real(); 260*f8a1b7d9SAlexander Kabaev _Tp __den = _Tp(1.0) - __z.real(); 261*f8a1b7d9SAlexander Kabaev 262*f8a1b7d9SAlexander Kabaev __num = __i2 + __num * __num; 263*f8a1b7d9SAlexander Kabaev __den = __i2 + __den * __den; 264*f8a1b7d9SAlexander Kabaev 265*f8a1b7d9SAlexander Kabaev return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 266*f8a1b7d9SAlexander Kabaev _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 267*f8a1b7d9SAlexander Kabaev } 268*f8a1b7d9SAlexander Kabaev 269*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1 270*f8a1b7d9SAlexander Kabaev inline __complex__ float 271*f8a1b7d9SAlexander Kabaev __complex_atanh(__complex__ float __z) 272*f8a1b7d9SAlexander Kabaev { return __builtin_catanhf(__z); } 273*f8a1b7d9SAlexander Kabaev 274*f8a1b7d9SAlexander Kabaev inline __complex__ double 275*f8a1b7d9SAlexander Kabaev __complex_atanh(__complex__ double __z) 276*f8a1b7d9SAlexander Kabaev { return __builtin_catanh(__z); } 277*f8a1b7d9SAlexander Kabaev 278*f8a1b7d9SAlexander Kabaev inline __complex__ long double 279*f8a1b7d9SAlexander Kabaev __complex_atanh(const __complex__ long double& __z) 280*f8a1b7d9SAlexander Kabaev { return __builtin_catanhl(__z); } 281*f8a1b7d9SAlexander Kabaev 282*f8a1b7d9SAlexander Kabaev template<typename _Tp> 283*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 284*f8a1b7d9SAlexander Kabaev atanh(const std::complex<_Tp>& __z) 285*f8a1b7d9SAlexander Kabaev { return __complex_atanh(__z.__rep()); } 286*f8a1b7d9SAlexander Kabaev#else 287*f8a1b7d9SAlexander Kabaev template<typename _Tp> 288*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 289*f8a1b7d9SAlexander Kabaev atanh(const std::complex<_Tp>& __z) 290*f8a1b7d9SAlexander Kabaev { return __complex_atanh(__z); } 291*f8a1b7d9SAlexander Kabaev#endif 292*f8a1b7d9SAlexander Kabaev 293*f8a1b7d9SAlexander Kabaev /// @brief fabs(__z) [8.1.8]. 294*f8a1b7d9SAlexander Kabaev // Effects: Behaves the same as C99 function cabs, defined 295*f8a1b7d9SAlexander Kabaev // in subclause 7.3.8.1. 296*f8a1b7d9SAlexander Kabaev template<typename _Tp> 297*f8a1b7d9SAlexander Kabaev inline std::complex<_Tp> 298*f8a1b7d9SAlexander Kabaev fabs(const std::complex<_Tp>& __z) 299*f8a1b7d9SAlexander Kabaev { return std::abs(__z); } 300*f8a1b7d9SAlexander Kabaev 301*f8a1b7d9SAlexander Kabaev 302*f8a1b7d9SAlexander Kabaev /// @brief Additional overloads [8.1.9]. 303*f8a1b7d9SAlexander Kabaev // 304*f8a1b7d9SAlexander Kabaev 305*f8a1b7d9SAlexander Kabaev // See common.h for the primary template. 306*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 307*f8a1b7d9SAlexander Kabaev struct __promote_2<std::complex<_Tp>, _Up> 308*f8a1b7d9SAlexander Kabaev { 309*f8a1b7d9SAlexander Kabaev public: 310*f8a1b7d9SAlexander Kabaev typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 311*f8a1b7d9SAlexander Kabaev }; 312*f8a1b7d9SAlexander Kabaev 313*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 314*f8a1b7d9SAlexander Kabaev struct __promote_2<_Tp, std::complex<_Up> > 315*f8a1b7d9SAlexander Kabaev { 316*f8a1b7d9SAlexander Kabaev public: 317*f8a1b7d9SAlexander Kabaev typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 318*f8a1b7d9SAlexander Kabaev }; 319*f8a1b7d9SAlexander Kabaev 320*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 321*f8a1b7d9SAlexander Kabaev struct __promote_2<std::complex<_Tp>, std::complex<_Up> > 322*f8a1b7d9SAlexander Kabaev { 323*f8a1b7d9SAlexander Kabaev public: 324*f8a1b7d9SAlexander Kabaev typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 325*f8a1b7d9SAlexander Kabaev }; 326*f8a1b7d9SAlexander Kabaev 327*f8a1b7d9SAlexander Kabaev 328*f8a1b7d9SAlexander Kabaev using std::arg; 329*f8a1b7d9SAlexander Kabaev 330*f8a1b7d9SAlexander Kabaev template<typename _Tp> 331*f8a1b7d9SAlexander Kabaev inline typename __promote<_Tp>::__type 332*f8a1b7d9SAlexander Kabaev arg(_Tp __x) 333*f8a1b7d9SAlexander Kabaev { 334*f8a1b7d9SAlexander Kabaev typedef typename __promote<_Tp>::__type __type; 335*f8a1b7d9SAlexander Kabaev return std::arg(std::complex<__type>(__x)); 336*f8a1b7d9SAlexander Kabaev } 337*f8a1b7d9SAlexander Kabaev 338*f8a1b7d9SAlexander Kabaev using std::conj; 339*f8a1b7d9SAlexander Kabaev 340*f8a1b7d9SAlexander Kabaev template<typename _Tp> 341*f8a1b7d9SAlexander Kabaev inline std::complex<typename __promote<_Tp>::__type> 342*f8a1b7d9SAlexander Kabaev conj(_Tp __x) 343*f8a1b7d9SAlexander Kabaev { return __x; } 344*f8a1b7d9SAlexander Kabaev 345*f8a1b7d9SAlexander Kabaev using std::imag; 346*f8a1b7d9SAlexander Kabaev 347*f8a1b7d9SAlexander Kabaev template<typename _Tp> 348*f8a1b7d9SAlexander Kabaev inline typename __promote<_Tp>::__type 349*f8a1b7d9SAlexander Kabaev imag(_Tp) 350*f8a1b7d9SAlexander Kabaev { return _Tp(); } 351*f8a1b7d9SAlexander Kabaev 352*f8a1b7d9SAlexander Kabaev using std::norm; 353*f8a1b7d9SAlexander Kabaev 354*f8a1b7d9SAlexander Kabaev template<typename _Tp> 355*f8a1b7d9SAlexander Kabaev inline typename __promote<_Tp>::__type 356*f8a1b7d9SAlexander Kabaev norm(_Tp __x) 357*f8a1b7d9SAlexander Kabaev { 358*f8a1b7d9SAlexander Kabaev typedef typename __promote<_Tp>::__type __type; 359*f8a1b7d9SAlexander Kabaev return __type(__x) * __type(__x); 360*f8a1b7d9SAlexander Kabaev } 361*f8a1b7d9SAlexander Kabaev 362*f8a1b7d9SAlexander Kabaev using std::polar; 363*f8a1b7d9SAlexander Kabaev 364*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 365*f8a1b7d9SAlexander Kabaev inline std::complex<typename __promote_2<_Tp, _Up>::__type> 366*f8a1b7d9SAlexander Kabaev polar(const _Tp& __rho, const _Up& __theta) 367*f8a1b7d9SAlexander Kabaev { 368*f8a1b7d9SAlexander Kabaev typedef typename __promote_2<_Tp, _Up>::__type __type; 369*f8a1b7d9SAlexander Kabaev return std::polar(__type(__rho), __type(__theta)); 370*f8a1b7d9SAlexander Kabaev } 371*f8a1b7d9SAlexander Kabaev 372*f8a1b7d9SAlexander Kabaev using std::pow; 373*f8a1b7d9SAlexander Kabaev 374*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 375*f8a1b7d9SAlexander Kabaev inline std::complex<typename __promote_2<_Tp, _Up>::__type> 376*f8a1b7d9SAlexander Kabaev pow(const std::complex<_Tp>& __x, const _Up& __y) 377*f8a1b7d9SAlexander Kabaev { 378*f8a1b7d9SAlexander Kabaev typedef typename __promote_2<_Tp, _Up>::__type __type; 379*f8a1b7d9SAlexander Kabaev return std::pow(std::complex<__type>(__x), __type(__y)); 380*f8a1b7d9SAlexander Kabaev } 381*f8a1b7d9SAlexander Kabaev 382*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 383*f8a1b7d9SAlexander Kabaev inline std::complex<typename __promote_2<_Tp, _Up>::__type> 384*f8a1b7d9SAlexander Kabaev pow(const _Tp& __x, const std::complex<_Up>& __y) 385*f8a1b7d9SAlexander Kabaev { 386*f8a1b7d9SAlexander Kabaev typedef typename __promote_2<_Tp, _Up>::__type __type; 387*f8a1b7d9SAlexander Kabaev return std::pow(__type(__x), std::complex<__type>(__y)); 388*f8a1b7d9SAlexander Kabaev } 389*f8a1b7d9SAlexander Kabaev 390*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 391*f8a1b7d9SAlexander Kabaev inline std::complex<typename __promote_2<_Tp, _Up>::__type> 392*f8a1b7d9SAlexander Kabaev pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) 393*f8a1b7d9SAlexander Kabaev { 394*f8a1b7d9SAlexander Kabaev typedef typename __promote_2<_Tp, _Up>::__type __type; 395*f8a1b7d9SAlexander Kabaev return std::pow(std::complex<__type>(__x), 396*f8a1b7d9SAlexander Kabaev std::complex<__type>(__y)); 397*f8a1b7d9SAlexander Kabaev } 398*f8a1b7d9SAlexander Kabaev 399*f8a1b7d9SAlexander Kabaev using std::real; 400*f8a1b7d9SAlexander Kabaev 401*f8a1b7d9SAlexander Kabaev template<typename _Tp> 402*f8a1b7d9SAlexander Kabaev inline typename __promote<_Tp>::__type 403*f8a1b7d9SAlexander Kabaev real(_Tp __x) 404*f8a1b7d9SAlexander Kabaev { return __x; } 405*f8a1b7d9SAlexander Kabaev 406*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE 407*f8a1b7d9SAlexander Kabaev} 408*f8a1b7d9SAlexander Kabaev 409*f8a1b7d9SAlexander Kabaev#endif 410