1e4b17023SJohn Marino// The template and inlines for the -*- C++ -*- complex number classes. 2e4b17023SJohn Marino 3*5ce9237cSJohn Marino// Copyright (C) 1997-2013 Free Software Foundation, Inc. 4e4b17023SJohn Marino// 5e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library. This library is free 6e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the 7e4b17023SJohn Marino// terms of the GNU General Public License as published by the 8e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option) 9e4b17023SJohn Marino// any later version. 10e4b17023SJohn Marino 11e4b17023SJohn Marino// This library is distributed in the hope that it will be useful, 12e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of 13e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e4b17023SJohn Marino// GNU General Public License for more details. 15e4b17023SJohn Marino 16e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional 17e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version 18e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation. 19e4b17023SJohn Marino 20e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and 21e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program; 22e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23e4b17023SJohn Marino// <http://www.gnu.org/licenses/>. 24e4b17023SJohn Marino 25e4b17023SJohn Marino/** @file include/complex 26e4b17023SJohn Marino * This is a Standard C++ Library header. 27e4b17023SJohn Marino */ 28e4b17023SJohn Marino 29e4b17023SJohn Marino// 30e4b17023SJohn Marino// ISO C++ 14882: 26.2 Complex Numbers 31e4b17023SJohn Marino// Note: this is not a conforming implementation. 32e4b17023SJohn Marino// Initially implemented by Ulrich Drepper <drepper@cygnus.com> 33e4b17023SJohn Marino// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 34e4b17023SJohn Marino// 35e4b17023SJohn Marino 36e4b17023SJohn Marino#ifndef _GLIBCXX_COMPLEX 37e4b17023SJohn Marino#define _GLIBCXX_COMPLEX 1 38e4b17023SJohn Marino 39e4b17023SJohn Marino#pragma GCC system_header 40e4b17023SJohn Marino 41e4b17023SJohn Marino#include <bits/c++config.h> 42e4b17023SJohn Marino#include <bits/cpp_type_traits.h> 43e4b17023SJohn Marino#include <ext/type_traits.h> 44e4b17023SJohn Marino#include <cmath> 45e4b17023SJohn Marino#include <sstream> 46e4b17023SJohn Marino 47e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 48e4b17023SJohn Marino{ 49e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 50e4b17023SJohn Marino 51e4b17023SJohn Marino /** 52e4b17023SJohn Marino * @defgroup complex_numbers Complex Numbers 53e4b17023SJohn Marino * @ingroup numerics 54e4b17023SJohn Marino * 55e4b17023SJohn Marino * Classes and functions for complex numbers. 56e4b17023SJohn Marino * @{ 57e4b17023SJohn Marino */ 58e4b17023SJohn Marino 59e4b17023SJohn Marino // Forward declarations. 60e4b17023SJohn Marino template<typename _Tp> class complex; 61e4b17023SJohn Marino template<> class complex<float>; 62e4b17023SJohn Marino template<> class complex<double>; 63e4b17023SJohn Marino template<> class complex<long double>; 64e4b17023SJohn Marino 65e4b17023SJohn Marino /// Return magnitude of @a z. 66e4b17023SJohn Marino template<typename _Tp> _Tp abs(const complex<_Tp>&); 67e4b17023SJohn Marino /// Return phase angle of @a z. 68e4b17023SJohn Marino template<typename _Tp> _Tp arg(const complex<_Tp>&); 69e4b17023SJohn Marino /// Return @a z magnitude squared. 70e4b17023SJohn Marino template<typename _Tp> _Tp norm(const complex<_Tp>&); 71e4b17023SJohn Marino 72e4b17023SJohn Marino /// Return complex conjugate of @a z. 73e4b17023SJohn Marino template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); 74e4b17023SJohn Marino /// Return complex with magnitude @a rho and angle @a theta. 75e4b17023SJohn Marino template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); 76e4b17023SJohn Marino 77e4b17023SJohn Marino // Transcendentals: 78e4b17023SJohn Marino /// Return complex cosine of @a z. 79e4b17023SJohn Marino template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); 80e4b17023SJohn Marino /// Return complex hyperbolic cosine of @a z. 81e4b17023SJohn Marino template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); 82e4b17023SJohn Marino /// Return complex base e exponential of @a z. 83e4b17023SJohn Marino template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); 84e4b17023SJohn Marino /// Return complex natural logarithm of @a z. 85e4b17023SJohn Marino template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); 86e4b17023SJohn Marino /// Return complex base 10 logarithm of @a z. 87e4b17023SJohn Marino template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); 88e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__ 89e4b17023SJohn Marino // DR 844. 90e4b17023SJohn Marino /// Return @a x to the @a y'th power. 91e4b17023SJohn Marino template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); 92e4b17023SJohn Marino#endif 93e4b17023SJohn Marino /// Return @a x to the @a y'th power. 94e4b17023SJohn Marino template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); 95e4b17023SJohn Marino /// Return @a x to the @a y'th power. 96e4b17023SJohn Marino template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 97e4b17023SJohn Marino const complex<_Tp>&); 98e4b17023SJohn Marino /// Return @a x to the @a y'th power. 99e4b17023SJohn Marino template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); 100e4b17023SJohn Marino /// Return complex sine of @a z. 101e4b17023SJohn Marino template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); 102e4b17023SJohn Marino /// Return complex hyperbolic sine of @a z. 103e4b17023SJohn Marino template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); 104e4b17023SJohn Marino /// Return complex square root of @a z. 105e4b17023SJohn Marino template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); 106e4b17023SJohn Marino /// Return complex tangent of @a z. 107e4b17023SJohn Marino template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); 108e4b17023SJohn Marino /// Return complex hyperbolic tangent of @a z. 109e4b17023SJohn Marino template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); 110e4b17023SJohn Marino 111e4b17023SJohn Marino 112e4b17023SJohn Marino // 26.2.2 Primary template class complex 113e4b17023SJohn Marino /** 114e4b17023SJohn Marino * Template to represent complex numbers. 115e4b17023SJohn Marino * 116e4b17023SJohn Marino * Specializations for float, double, and long double are part of the 117e4b17023SJohn Marino * library. Results with any other type are not guaranteed. 118e4b17023SJohn Marino * 119e4b17023SJohn Marino * @param Tp Type of real and imaginary values. 120e4b17023SJohn Marino */ 121e4b17023SJohn Marino template<typename _Tp> 122e4b17023SJohn Marino struct complex 123e4b17023SJohn Marino { 124e4b17023SJohn Marino /// Value typedef. 125e4b17023SJohn Marino typedef _Tp value_type; 126e4b17023SJohn Marino 127e4b17023SJohn Marino /// Default constructor. First parameter is x, second parameter is y. 128e4b17023SJohn Marino /// Unspecified parameters default to 0. 129e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp()) 130e4b17023SJohn Marino : _M_real(__r), _M_imag(__i) { } 131e4b17023SJohn Marino 132e4b17023SJohn Marino // Lets the compiler synthesize the copy constructor 133e4b17023SJohn Marino // complex (const complex<_Tp>&); 134e4b17023SJohn Marino /// Copy constructor. 135e4b17023SJohn Marino template<typename _Up> 136e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z) 137e4b17023SJohn Marino : _M_real(__z.real()), _M_imag(__z.imag()) { } 138e4b17023SJohn Marino 139e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 140e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 141e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 142e4b17023SJohn Marino constexpr _Tp 143e4b17023SJohn Marino real() { return _M_real; } 144e4b17023SJohn Marino 145e4b17023SJohn Marino constexpr _Tp 146e4b17023SJohn Marino imag() { return _M_imag; } 147e4b17023SJohn Marino#else 148e4b17023SJohn Marino /// Return real part of complex number. 149e4b17023SJohn Marino _Tp& 150e4b17023SJohn Marino real() { return _M_real; } 151e4b17023SJohn Marino 152e4b17023SJohn Marino /// Return real part of complex number. 153e4b17023SJohn Marino const _Tp& 154e4b17023SJohn Marino real() const { return _M_real; } 155e4b17023SJohn Marino 156e4b17023SJohn Marino /// Return imaginary part of complex number. 157e4b17023SJohn Marino _Tp& 158e4b17023SJohn Marino imag() { return _M_imag; } 159e4b17023SJohn Marino 160e4b17023SJohn Marino /// Return imaginary part of complex number. 161e4b17023SJohn Marino const _Tp& 162e4b17023SJohn Marino imag() const { return _M_imag; } 163e4b17023SJohn Marino#endif 164e4b17023SJohn Marino 165e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 166e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 167e4b17023SJohn Marino void 168e4b17023SJohn Marino real(_Tp __val) { _M_real = __val; } 169e4b17023SJohn Marino 170e4b17023SJohn Marino void 171e4b17023SJohn Marino imag(_Tp __val) { _M_imag = __val; } 172e4b17023SJohn Marino 173e4b17023SJohn Marino /// Assign this complex number to scalar @a t. 174e4b17023SJohn Marino complex<_Tp>& operator=(const _Tp&); 175e4b17023SJohn Marino 176e4b17023SJohn Marino /// Add @a t to this complex number. 177e4b17023SJohn Marino // 26.2.5/1 178e4b17023SJohn Marino complex<_Tp>& 179e4b17023SJohn Marino operator+=(const _Tp& __t) 180e4b17023SJohn Marino { 181e4b17023SJohn Marino _M_real += __t; 182e4b17023SJohn Marino return *this; 183e4b17023SJohn Marino } 184e4b17023SJohn Marino 185e4b17023SJohn Marino /// Subtract @a t from this complex number. 186e4b17023SJohn Marino // 26.2.5/3 187e4b17023SJohn Marino complex<_Tp>& 188e4b17023SJohn Marino operator-=(const _Tp& __t) 189e4b17023SJohn Marino { 190e4b17023SJohn Marino _M_real -= __t; 191e4b17023SJohn Marino return *this; 192e4b17023SJohn Marino } 193e4b17023SJohn Marino 194e4b17023SJohn Marino /// Multiply this complex number by @a t. 195e4b17023SJohn Marino complex<_Tp>& operator*=(const _Tp&); 196e4b17023SJohn Marino /// Divide this complex number by @a t. 197e4b17023SJohn Marino complex<_Tp>& operator/=(const _Tp&); 198e4b17023SJohn Marino 199e4b17023SJohn Marino // Lets the compiler synthesize the 200e4b17023SJohn Marino // copy and assignment operator 201e4b17023SJohn Marino // complex<_Tp>& operator= (const complex<_Tp>&); 202e4b17023SJohn Marino /// Assign this complex number to complex @a z. 203e4b17023SJohn Marino template<typename _Up> 204e4b17023SJohn Marino complex<_Tp>& operator=(const complex<_Up>&); 205e4b17023SJohn Marino /// Add @a z to this complex number. 206e4b17023SJohn Marino template<typename _Up> 207e4b17023SJohn Marino complex<_Tp>& operator+=(const complex<_Up>&); 208e4b17023SJohn Marino /// Subtract @a z from this complex number. 209e4b17023SJohn Marino template<typename _Up> 210e4b17023SJohn Marino complex<_Tp>& operator-=(const complex<_Up>&); 211e4b17023SJohn Marino /// Multiply this complex number by @a z. 212e4b17023SJohn Marino template<typename _Up> 213e4b17023SJohn Marino complex<_Tp>& operator*=(const complex<_Up>&); 214e4b17023SJohn Marino /// Divide this complex number by @a z. 215e4b17023SJohn Marino template<typename _Up> 216e4b17023SJohn Marino complex<_Tp>& operator/=(const complex<_Up>&); 217e4b17023SJohn Marino 218e4b17023SJohn Marino _GLIBCXX_USE_CONSTEXPR complex __rep() const 219e4b17023SJohn Marino { return *this; } 220e4b17023SJohn Marino 221e4b17023SJohn Marino private: 222e4b17023SJohn Marino _Tp _M_real; 223e4b17023SJohn Marino _Tp _M_imag; 224e4b17023SJohn Marino }; 225e4b17023SJohn Marino 226e4b17023SJohn Marino template<typename _Tp> 227e4b17023SJohn Marino complex<_Tp>& 228e4b17023SJohn Marino complex<_Tp>::operator=(const _Tp& __t) 229e4b17023SJohn Marino { 230e4b17023SJohn Marino _M_real = __t; 231e4b17023SJohn Marino _M_imag = _Tp(); 232e4b17023SJohn Marino return *this; 233e4b17023SJohn Marino } 234e4b17023SJohn Marino 235e4b17023SJohn Marino // 26.2.5/5 236e4b17023SJohn Marino template<typename _Tp> 237e4b17023SJohn Marino complex<_Tp>& 238e4b17023SJohn Marino complex<_Tp>::operator*=(const _Tp& __t) 239e4b17023SJohn Marino { 240e4b17023SJohn Marino _M_real *= __t; 241e4b17023SJohn Marino _M_imag *= __t; 242e4b17023SJohn Marino return *this; 243e4b17023SJohn Marino } 244e4b17023SJohn Marino 245e4b17023SJohn Marino // 26.2.5/7 246e4b17023SJohn Marino template<typename _Tp> 247e4b17023SJohn Marino complex<_Tp>& 248e4b17023SJohn Marino complex<_Tp>::operator/=(const _Tp& __t) 249e4b17023SJohn Marino { 250e4b17023SJohn Marino _M_real /= __t; 251e4b17023SJohn Marino _M_imag /= __t; 252e4b17023SJohn Marino return *this; 253e4b17023SJohn Marino } 254e4b17023SJohn Marino 255e4b17023SJohn Marino template<typename _Tp> 256e4b17023SJohn Marino template<typename _Up> 257e4b17023SJohn Marino complex<_Tp>& 258e4b17023SJohn Marino complex<_Tp>::operator=(const complex<_Up>& __z) 259e4b17023SJohn Marino { 260e4b17023SJohn Marino _M_real = __z.real(); 261e4b17023SJohn Marino _M_imag = __z.imag(); 262e4b17023SJohn Marino return *this; 263e4b17023SJohn Marino } 264e4b17023SJohn Marino 265e4b17023SJohn Marino // 26.2.5/9 266e4b17023SJohn Marino template<typename _Tp> 267e4b17023SJohn Marino template<typename _Up> 268e4b17023SJohn Marino complex<_Tp>& 269e4b17023SJohn Marino complex<_Tp>::operator+=(const complex<_Up>& __z) 270e4b17023SJohn Marino { 271e4b17023SJohn Marino _M_real += __z.real(); 272e4b17023SJohn Marino _M_imag += __z.imag(); 273e4b17023SJohn Marino return *this; 274e4b17023SJohn Marino } 275e4b17023SJohn Marino 276e4b17023SJohn Marino // 26.2.5/11 277e4b17023SJohn Marino template<typename _Tp> 278e4b17023SJohn Marino template<typename _Up> 279e4b17023SJohn Marino complex<_Tp>& 280e4b17023SJohn Marino complex<_Tp>::operator-=(const complex<_Up>& __z) 281e4b17023SJohn Marino { 282e4b17023SJohn Marino _M_real -= __z.real(); 283e4b17023SJohn Marino _M_imag -= __z.imag(); 284e4b17023SJohn Marino return *this; 285e4b17023SJohn Marino } 286e4b17023SJohn Marino 287e4b17023SJohn Marino // 26.2.5/13 288e4b17023SJohn Marino // XXX: This is a grammar school implementation. 289e4b17023SJohn Marino template<typename _Tp> 290e4b17023SJohn Marino template<typename _Up> 291e4b17023SJohn Marino complex<_Tp>& 292e4b17023SJohn Marino complex<_Tp>::operator*=(const complex<_Up>& __z) 293e4b17023SJohn Marino { 294e4b17023SJohn Marino const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); 295e4b17023SJohn Marino _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); 296e4b17023SJohn Marino _M_real = __r; 297e4b17023SJohn Marino return *this; 298e4b17023SJohn Marino } 299e4b17023SJohn Marino 300e4b17023SJohn Marino // 26.2.5/15 301e4b17023SJohn Marino // XXX: This is a grammar school implementation. 302e4b17023SJohn Marino template<typename _Tp> 303e4b17023SJohn Marino template<typename _Up> 304e4b17023SJohn Marino complex<_Tp>& 305e4b17023SJohn Marino complex<_Tp>::operator/=(const complex<_Up>& __z) 306e4b17023SJohn Marino { 307e4b17023SJohn Marino const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); 308e4b17023SJohn Marino const _Tp __n = std::norm(__z); 309e4b17023SJohn Marino _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; 310e4b17023SJohn Marino _M_real = __r / __n; 311e4b17023SJohn Marino return *this; 312e4b17023SJohn Marino } 313e4b17023SJohn Marino 314e4b17023SJohn Marino // Operators: 315e4b17023SJohn Marino //@{ 316e4b17023SJohn Marino /// Return new complex value @a x plus @a y. 317e4b17023SJohn Marino template<typename _Tp> 318e4b17023SJohn Marino inline complex<_Tp> 319e4b17023SJohn Marino operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 320e4b17023SJohn Marino { 321e4b17023SJohn Marino complex<_Tp> __r = __x; 322e4b17023SJohn Marino __r += __y; 323e4b17023SJohn Marino return __r; 324e4b17023SJohn Marino } 325e4b17023SJohn Marino 326e4b17023SJohn Marino template<typename _Tp> 327e4b17023SJohn Marino inline complex<_Tp> 328e4b17023SJohn Marino operator+(const complex<_Tp>& __x, const _Tp& __y) 329e4b17023SJohn Marino { 330e4b17023SJohn Marino complex<_Tp> __r = __x; 331e4b17023SJohn Marino __r += __y; 332e4b17023SJohn Marino return __r; 333e4b17023SJohn Marino } 334e4b17023SJohn Marino 335e4b17023SJohn Marino template<typename _Tp> 336e4b17023SJohn Marino inline complex<_Tp> 337e4b17023SJohn Marino operator+(const _Tp& __x, const complex<_Tp>& __y) 338e4b17023SJohn Marino { 339e4b17023SJohn Marino complex<_Tp> __r = __y; 340e4b17023SJohn Marino __r += __x; 341e4b17023SJohn Marino return __r; 342e4b17023SJohn Marino } 343e4b17023SJohn Marino //@} 344e4b17023SJohn Marino 345e4b17023SJohn Marino //@{ 346e4b17023SJohn Marino /// Return new complex value @a x minus @a y. 347e4b17023SJohn Marino template<typename _Tp> 348e4b17023SJohn Marino inline complex<_Tp> 349e4b17023SJohn Marino operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 350e4b17023SJohn Marino { 351e4b17023SJohn Marino complex<_Tp> __r = __x; 352e4b17023SJohn Marino __r -= __y; 353e4b17023SJohn Marino return __r; 354e4b17023SJohn Marino } 355e4b17023SJohn Marino 356e4b17023SJohn Marino template<typename _Tp> 357e4b17023SJohn Marino inline complex<_Tp> 358e4b17023SJohn Marino operator-(const complex<_Tp>& __x, const _Tp& __y) 359e4b17023SJohn Marino { 360e4b17023SJohn Marino complex<_Tp> __r = __x; 361e4b17023SJohn Marino __r -= __y; 362e4b17023SJohn Marino return __r; 363e4b17023SJohn Marino } 364e4b17023SJohn Marino 365e4b17023SJohn Marino template<typename _Tp> 366e4b17023SJohn Marino inline complex<_Tp> 367e4b17023SJohn Marino operator-(const _Tp& __x, const complex<_Tp>& __y) 368e4b17023SJohn Marino { 369e4b17023SJohn Marino complex<_Tp> __r(__x, -__y.imag()); 370e4b17023SJohn Marino __r -= __y.real(); 371e4b17023SJohn Marino return __r; 372e4b17023SJohn Marino } 373e4b17023SJohn Marino //@} 374e4b17023SJohn Marino 375e4b17023SJohn Marino //@{ 376e4b17023SJohn Marino /// Return new complex value @a x times @a y. 377e4b17023SJohn Marino template<typename _Tp> 378e4b17023SJohn Marino inline complex<_Tp> 379e4b17023SJohn Marino operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) 380e4b17023SJohn Marino { 381e4b17023SJohn Marino complex<_Tp> __r = __x; 382e4b17023SJohn Marino __r *= __y; 383e4b17023SJohn Marino return __r; 384e4b17023SJohn Marino } 385e4b17023SJohn Marino 386e4b17023SJohn Marino template<typename _Tp> 387e4b17023SJohn Marino inline complex<_Tp> 388e4b17023SJohn Marino operator*(const complex<_Tp>& __x, const _Tp& __y) 389e4b17023SJohn Marino { 390e4b17023SJohn Marino complex<_Tp> __r = __x; 391e4b17023SJohn Marino __r *= __y; 392e4b17023SJohn Marino return __r; 393e4b17023SJohn Marino } 394e4b17023SJohn Marino 395e4b17023SJohn Marino template<typename _Tp> 396e4b17023SJohn Marino inline complex<_Tp> 397e4b17023SJohn Marino operator*(const _Tp& __x, const complex<_Tp>& __y) 398e4b17023SJohn Marino { 399e4b17023SJohn Marino complex<_Tp> __r = __y; 400e4b17023SJohn Marino __r *= __x; 401e4b17023SJohn Marino return __r; 402e4b17023SJohn Marino } 403e4b17023SJohn Marino //@} 404e4b17023SJohn Marino 405e4b17023SJohn Marino //@{ 406e4b17023SJohn Marino /// Return new complex value @a x divided by @a y. 407e4b17023SJohn Marino template<typename _Tp> 408e4b17023SJohn Marino inline complex<_Tp> 409e4b17023SJohn Marino operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) 410e4b17023SJohn Marino { 411e4b17023SJohn Marino complex<_Tp> __r = __x; 412e4b17023SJohn Marino __r /= __y; 413e4b17023SJohn Marino return __r; 414e4b17023SJohn Marino } 415e4b17023SJohn Marino 416e4b17023SJohn Marino template<typename _Tp> 417e4b17023SJohn Marino inline complex<_Tp> 418e4b17023SJohn Marino operator/(const complex<_Tp>& __x, const _Tp& __y) 419e4b17023SJohn Marino { 420e4b17023SJohn Marino complex<_Tp> __r = __x; 421e4b17023SJohn Marino __r /= __y; 422e4b17023SJohn Marino return __r; 423e4b17023SJohn Marino } 424e4b17023SJohn Marino 425e4b17023SJohn Marino template<typename _Tp> 426e4b17023SJohn Marino inline complex<_Tp> 427e4b17023SJohn Marino operator/(const _Tp& __x, const complex<_Tp>& __y) 428e4b17023SJohn Marino { 429e4b17023SJohn Marino complex<_Tp> __r = __x; 430e4b17023SJohn Marino __r /= __y; 431e4b17023SJohn Marino return __r; 432e4b17023SJohn Marino } 433e4b17023SJohn Marino //@} 434e4b17023SJohn Marino 435e4b17023SJohn Marino /// Return @a x. 436e4b17023SJohn Marino template<typename _Tp> 437e4b17023SJohn Marino inline complex<_Tp> 438e4b17023SJohn Marino operator+(const complex<_Tp>& __x) 439e4b17023SJohn Marino { return __x; } 440e4b17023SJohn Marino 441e4b17023SJohn Marino /// Return complex negation of @a x. 442e4b17023SJohn Marino template<typename _Tp> 443e4b17023SJohn Marino inline complex<_Tp> 444e4b17023SJohn Marino operator-(const complex<_Tp>& __x) 445e4b17023SJohn Marino { return complex<_Tp>(-__x.real(), -__x.imag()); } 446e4b17023SJohn Marino 447e4b17023SJohn Marino //@{ 448e4b17023SJohn Marino /// Return true if @a x is equal to @a y. 449e4b17023SJohn Marino template<typename _Tp> 450e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR bool 451e4b17023SJohn Marino operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 452e4b17023SJohn Marino { return __x.real() == __y.real() && __x.imag() == __y.imag(); } 453e4b17023SJohn Marino 454e4b17023SJohn Marino template<typename _Tp> 455e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR bool 456e4b17023SJohn Marino operator==(const complex<_Tp>& __x, const _Tp& __y) 457e4b17023SJohn Marino { return __x.real() == __y && __x.imag() == _Tp(); } 458e4b17023SJohn Marino 459e4b17023SJohn Marino template<typename _Tp> 460e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR bool 461e4b17023SJohn Marino operator==(const _Tp& __x, const complex<_Tp>& __y) 462e4b17023SJohn Marino { return __x == __y.real() && _Tp() == __y.imag(); } 463e4b17023SJohn Marino //@} 464e4b17023SJohn Marino 465e4b17023SJohn Marino //@{ 466e4b17023SJohn Marino /// Return false if @a x is equal to @a y. 467e4b17023SJohn Marino template<typename _Tp> 468e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR bool 469e4b17023SJohn Marino operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 470e4b17023SJohn Marino { return __x.real() != __y.real() || __x.imag() != __y.imag(); } 471e4b17023SJohn Marino 472e4b17023SJohn Marino template<typename _Tp> 473e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR bool 474e4b17023SJohn Marino operator!=(const complex<_Tp>& __x, const _Tp& __y) 475e4b17023SJohn Marino { return __x.real() != __y || __x.imag() != _Tp(); } 476e4b17023SJohn Marino 477e4b17023SJohn Marino template<typename _Tp> 478e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR bool 479e4b17023SJohn Marino operator!=(const _Tp& __x, const complex<_Tp>& __y) 480e4b17023SJohn Marino { return __x != __y.real() || _Tp() != __y.imag(); } 481e4b17023SJohn Marino //@} 482e4b17023SJohn Marino 483e4b17023SJohn Marino /// Extraction operator for complex values. 484e4b17023SJohn Marino template<typename _Tp, typename _CharT, class _Traits> 485e4b17023SJohn Marino basic_istream<_CharT, _Traits>& 486e4b17023SJohn Marino operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 487e4b17023SJohn Marino { 488e4b17023SJohn Marino _Tp __re_x, __im_x; 489e4b17023SJohn Marino _CharT __ch; 490e4b17023SJohn Marino __is >> __ch; 491e4b17023SJohn Marino if (__ch == '(') 492e4b17023SJohn Marino { 493e4b17023SJohn Marino __is >> __re_x >> __ch; 494e4b17023SJohn Marino if (__ch == ',') 495e4b17023SJohn Marino { 496e4b17023SJohn Marino __is >> __im_x >> __ch; 497e4b17023SJohn Marino if (__ch == ')') 498e4b17023SJohn Marino __x = complex<_Tp>(__re_x, __im_x); 499e4b17023SJohn Marino else 500e4b17023SJohn Marino __is.setstate(ios_base::failbit); 501e4b17023SJohn Marino } 502e4b17023SJohn Marino else if (__ch == ')') 503e4b17023SJohn Marino __x = __re_x; 504e4b17023SJohn Marino else 505e4b17023SJohn Marino __is.setstate(ios_base::failbit); 506e4b17023SJohn Marino } 507e4b17023SJohn Marino else 508e4b17023SJohn Marino { 509e4b17023SJohn Marino __is.putback(__ch); 510e4b17023SJohn Marino __is >> __re_x; 511e4b17023SJohn Marino __x = __re_x; 512e4b17023SJohn Marino } 513e4b17023SJohn Marino return __is; 514e4b17023SJohn Marino } 515e4b17023SJohn Marino 516e4b17023SJohn Marino /// Insertion operator for complex values. 517e4b17023SJohn Marino template<typename _Tp, typename _CharT, class _Traits> 518e4b17023SJohn Marino basic_ostream<_CharT, _Traits>& 519e4b17023SJohn Marino operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 520e4b17023SJohn Marino { 521e4b17023SJohn Marino basic_ostringstream<_CharT, _Traits> __s; 522e4b17023SJohn Marino __s.flags(__os.flags()); 523e4b17023SJohn Marino __s.imbue(__os.getloc()); 524e4b17023SJohn Marino __s.precision(__os.precision()); 525e4b17023SJohn Marino __s << '(' << __x.real() << ',' << __x.imag() << ')'; 526e4b17023SJohn Marino return __os << __s.str(); 527e4b17023SJohn Marino } 528e4b17023SJohn Marino 529e4b17023SJohn Marino // Values 530e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 531e4b17023SJohn Marino template<typename _Tp> 532e4b17023SJohn Marino constexpr _Tp 533e4b17023SJohn Marino real(const complex<_Tp>& __z) 534e4b17023SJohn Marino { return __z.real(); } 535e4b17023SJohn Marino 536e4b17023SJohn Marino template<typename _Tp> 537e4b17023SJohn Marino constexpr _Tp 538e4b17023SJohn Marino imag(const complex<_Tp>& __z) 539e4b17023SJohn Marino { return __z.imag(); } 540e4b17023SJohn Marino#else 541e4b17023SJohn Marino template<typename _Tp> 542e4b17023SJohn Marino inline _Tp& 543e4b17023SJohn Marino real(complex<_Tp>& __z) 544e4b17023SJohn Marino { return __z.real(); } 545e4b17023SJohn Marino 546e4b17023SJohn Marino template<typename _Tp> 547e4b17023SJohn Marino inline const _Tp& 548e4b17023SJohn Marino real(const complex<_Tp>& __z) 549e4b17023SJohn Marino { return __z.real(); } 550e4b17023SJohn Marino 551e4b17023SJohn Marino template<typename _Tp> 552e4b17023SJohn Marino inline _Tp& 553e4b17023SJohn Marino imag(complex<_Tp>& __z) 554e4b17023SJohn Marino { return __z.imag(); } 555e4b17023SJohn Marino 556e4b17023SJohn Marino template<typename _Tp> 557e4b17023SJohn Marino inline const _Tp& 558e4b17023SJohn Marino imag(const complex<_Tp>& __z) 559e4b17023SJohn Marino { return __z.imag(); } 560e4b17023SJohn Marino#endif 561e4b17023SJohn Marino 562e4b17023SJohn Marino // 26.2.7/3 abs(__z): Returns the magnitude of __z. 563e4b17023SJohn Marino template<typename _Tp> 564e4b17023SJohn Marino inline _Tp 565e4b17023SJohn Marino __complex_abs(const complex<_Tp>& __z) 566e4b17023SJohn Marino { 567e4b17023SJohn Marino _Tp __x = __z.real(); 568e4b17023SJohn Marino _Tp __y = __z.imag(); 569e4b17023SJohn Marino const _Tp __s = std::max(abs(__x), abs(__y)); 570e4b17023SJohn Marino if (__s == _Tp()) // well ... 571e4b17023SJohn Marino return __s; 572e4b17023SJohn Marino __x /= __s; 573e4b17023SJohn Marino __y /= __s; 574e4b17023SJohn Marino return __s * sqrt(__x * __x + __y * __y); 575e4b17023SJohn Marino } 576e4b17023SJohn Marino 577e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 578e4b17023SJohn Marino inline float 579e4b17023SJohn Marino __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); } 580e4b17023SJohn Marino 581e4b17023SJohn Marino inline double 582e4b17023SJohn Marino __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); } 583e4b17023SJohn Marino 584e4b17023SJohn Marino inline long double 585e4b17023SJohn Marino __complex_abs(const __complex__ long double& __z) 586e4b17023SJohn Marino { return __builtin_cabsl(__z); } 587e4b17023SJohn Marino 588e4b17023SJohn Marino template<typename _Tp> 589e4b17023SJohn Marino inline _Tp 590e4b17023SJohn Marino abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); } 591e4b17023SJohn Marino#else 592e4b17023SJohn Marino template<typename _Tp> 593e4b17023SJohn Marino inline _Tp 594e4b17023SJohn Marino abs(const complex<_Tp>& __z) { return __complex_abs(__z); } 595e4b17023SJohn Marino#endif 596e4b17023SJohn Marino 597e4b17023SJohn Marino 598e4b17023SJohn Marino // 26.2.7/4: arg(__z): Returns the phase angle of __z. 599e4b17023SJohn Marino template<typename _Tp> 600e4b17023SJohn Marino inline _Tp 601e4b17023SJohn Marino __complex_arg(const complex<_Tp>& __z) 602e4b17023SJohn Marino { return atan2(__z.imag(), __z.real()); } 603e4b17023SJohn Marino 604e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 605e4b17023SJohn Marino inline float 606e4b17023SJohn Marino __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); } 607e4b17023SJohn Marino 608e4b17023SJohn Marino inline double 609e4b17023SJohn Marino __complex_arg(__complex__ double __z) { return __builtin_carg(__z); } 610e4b17023SJohn Marino 611e4b17023SJohn Marino inline long double 612e4b17023SJohn Marino __complex_arg(const __complex__ long double& __z) 613e4b17023SJohn Marino { return __builtin_cargl(__z); } 614e4b17023SJohn Marino 615e4b17023SJohn Marino template<typename _Tp> 616e4b17023SJohn Marino inline _Tp 617e4b17023SJohn Marino arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); } 618e4b17023SJohn Marino#else 619e4b17023SJohn Marino template<typename _Tp> 620e4b17023SJohn Marino inline _Tp 621e4b17023SJohn Marino arg(const complex<_Tp>& __z) { return __complex_arg(__z); } 622e4b17023SJohn Marino#endif 623e4b17023SJohn Marino 624e4b17023SJohn Marino // 26.2.7/5: norm(__z) returns the squared magnitude of __z. 625e4b17023SJohn Marino // As defined, norm() is -not- a norm is the common mathematical 626e4b17023SJohn Marino // sens used in numerics. The helper class _Norm_helper<> tries to 627e4b17023SJohn Marino // distinguish between builtin floating point and the rest, so as 628e4b17023SJohn Marino // to deliver an answer as close as possible to the real value. 629e4b17023SJohn Marino template<bool> 630e4b17023SJohn Marino struct _Norm_helper 631e4b17023SJohn Marino { 632e4b17023SJohn Marino template<typename _Tp> 633e4b17023SJohn Marino static inline _Tp _S_do_it(const complex<_Tp>& __z) 634e4b17023SJohn Marino { 635e4b17023SJohn Marino const _Tp __x = __z.real(); 636e4b17023SJohn Marino const _Tp __y = __z.imag(); 637e4b17023SJohn Marino return __x * __x + __y * __y; 638e4b17023SJohn Marino } 639e4b17023SJohn Marino }; 640e4b17023SJohn Marino 641e4b17023SJohn Marino template<> 642e4b17023SJohn Marino struct _Norm_helper<true> 643e4b17023SJohn Marino { 644e4b17023SJohn Marino template<typename _Tp> 645e4b17023SJohn Marino static inline _Tp _S_do_it(const complex<_Tp>& __z) 646e4b17023SJohn Marino { 647e4b17023SJohn Marino _Tp __res = std::abs(__z); 648e4b17023SJohn Marino return __res * __res; 649e4b17023SJohn Marino } 650e4b17023SJohn Marino }; 651e4b17023SJohn Marino 652e4b17023SJohn Marino template<typename _Tp> 653e4b17023SJohn Marino inline _Tp 654e4b17023SJohn Marino norm(const complex<_Tp>& __z) 655e4b17023SJohn Marino { 656e4b17023SJohn Marino return _Norm_helper<__is_floating<_Tp>::__value 657e4b17023SJohn Marino && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); 658e4b17023SJohn Marino } 659e4b17023SJohn Marino 660e4b17023SJohn Marino template<typename _Tp> 661e4b17023SJohn Marino inline complex<_Tp> 662e4b17023SJohn Marino polar(const _Tp& __rho, const _Tp& __theta) 663e4b17023SJohn Marino { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } 664e4b17023SJohn Marino 665e4b17023SJohn Marino template<typename _Tp> 666e4b17023SJohn Marino inline complex<_Tp> 667e4b17023SJohn Marino conj(const complex<_Tp>& __z) 668e4b17023SJohn Marino { return complex<_Tp>(__z.real(), -__z.imag()); } 669e4b17023SJohn Marino 670e4b17023SJohn Marino // Transcendentals 671e4b17023SJohn Marino 672e4b17023SJohn Marino // 26.2.8/1 cos(__z): Returns the cosine of __z. 673e4b17023SJohn Marino template<typename _Tp> 674e4b17023SJohn Marino inline complex<_Tp> 675e4b17023SJohn Marino __complex_cos(const complex<_Tp>& __z) 676e4b17023SJohn Marino { 677e4b17023SJohn Marino const _Tp __x = __z.real(); 678e4b17023SJohn Marino const _Tp __y = __z.imag(); 679e4b17023SJohn Marino return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); 680e4b17023SJohn Marino } 681e4b17023SJohn Marino 682e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 683e4b17023SJohn Marino inline __complex__ float 684e4b17023SJohn Marino __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); } 685e4b17023SJohn Marino 686e4b17023SJohn Marino inline __complex__ double 687e4b17023SJohn Marino __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); } 688e4b17023SJohn Marino 689e4b17023SJohn Marino inline __complex__ long double 690e4b17023SJohn Marino __complex_cos(const __complex__ long double& __z) 691e4b17023SJohn Marino { return __builtin_ccosl(__z); } 692e4b17023SJohn Marino 693e4b17023SJohn Marino template<typename _Tp> 694e4b17023SJohn Marino inline complex<_Tp> 695e4b17023SJohn Marino cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); } 696e4b17023SJohn Marino#else 697e4b17023SJohn Marino template<typename _Tp> 698e4b17023SJohn Marino inline complex<_Tp> 699e4b17023SJohn Marino cos(const complex<_Tp>& __z) { return __complex_cos(__z); } 700e4b17023SJohn Marino#endif 701e4b17023SJohn Marino 702e4b17023SJohn Marino // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z. 703e4b17023SJohn Marino template<typename _Tp> 704e4b17023SJohn Marino inline complex<_Tp> 705e4b17023SJohn Marino __complex_cosh(const complex<_Tp>& __z) 706e4b17023SJohn Marino { 707e4b17023SJohn Marino const _Tp __x = __z.real(); 708e4b17023SJohn Marino const _Tp __y = __z.imag(); 709e4b17023SJohn Marino return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); 710e4b17023SJohn Marino } 711e4b17023SJohn Marino 712e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 713e4b17023SJohn Marino inline __complex__ float 714e4b17023SJohn Marino __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); } 715e4b17023SJohn Marino 716e4b17023SJohn Marino inline __complex__ double 717e4b17023SJohn Marino __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); } 718e4b17023SJohn Marino 719e4b17023SJohn Marino inline __complex__ long double 720e4b17023SJohn Marino __complex_cosh(const __complex__ long double& __z) 721e4b17023SJohn Marino { return __builtin_ccoshl(__z); } 722e4b17023SJohn Marino 723e4b17023SJohn Marino template<typename _Tp> 724e4b17023SJohn Marino inline complex<_Tp> 725e4b17023SJohn Marino cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); } 726e4b17023SJohn Marino#else 727e4b17023SJohn Marino template<typename _Tp> 728e4b17023SJohn Marino inline complex<_Tp> 729e4b17023SJohn Marino cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } 730e4b17023SJohn Marino#endif 731e4b17023SJohn Marino 732e4b17023SJohn Marino // 26.2.8/3 exp(__z): Returns the complex base e exponential of x 733e4b17023SJohn Marino template<typename _Tp> 734e4b17023SJohn Marino inline complex<_Tp> 735e4b17023SJohn Marino __complex_exp(const complex<_Tp>& __z) 736e4b17023SJohn Marino { return std::polar(exp(__z.real()), __z.imag()); } 737e4b17023SJohn Marino 738e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 739e4b17023SJohn Marino inline __complex__ float 740e4b17023SJohn Marino __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } 741e4b17023SJohn Marino 742e4b17023SJohn Marino inline __complex__ double 743e4b17023SJohn Marino __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } 744e4b17023SJohn Marino 745e4b17023SJohn Marino inline __complex__ long double 746e4b17023SJohn Marino __complex_exp(const __complex__ long double& __z) 747e4b17023SJohn Marino { return __builtin_cexpl(__z); } 748e4b17023SJohn Marino 749e4b17023SJohn Marino template<typename _Tp> 750e4b17023SJohn Marino inline complex<_Tp> 751e4b17023SJohn Marino exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); } 752e4b17023SJohn Marino#else 753e4b17023SJohn Marino template<typename _Tp> 754e4b17023SJohn Marino inline complex<_Tp> 755e4b17023SJohn Marino exp(const complex<_Tp>& __z) { return __complex_exp(__z); } 756e4b17023SJohn Marino#endif 757e4b17023SJohn Marino 758e4b17023SJohn Marino // 26.2.8/5 log(__z): Returns the natural complex logarithm of __z. 759e4b17023SJohn Marino // The branch cut is along the negative axis. 760e4b17023SJohn Marino template<typename _Tp> 761e4b17023SJohn Marino inline complex<_Tp> 762e4b17023SJohn Marino __complex_log(const complex<_Tp>& __z) 763e4b17023SJohn Marino { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } 764e4b17023SJohn Marino 765e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 766e4b17023SJohn Marino inline __complex__ float 767e4b17023SJohn Marino __complex_log(__complex__ float __z) { return __builtin_clogf(__z); } 768e4b17023SJohn Marino 769e4b17023SJohn Marino inline __complex__ double 770e4b17023SJohn Marino __complex_log(__complex__ double __z) { return __builtin_clog(__z); } 771e4b17023SJohn Marino 772e4b17023SJohn Marino inline __complex__ long double 773e4b17023SJohn Marino __complex_log(const __complex__ long double& __z) 774e4b17023SJohn Marino { return __builtin_clogl(__z); } 775e4b17023SJohn Marino 776e4b17023SJohn Marino template<typename _Tp> 777e4b17023SJohn Marino inline complex<_Tp> 778e4b17023SJohn Marino log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); } 779e4b17023SJohn Marino#else 780e4b17023SJohn Marino template<typename _Tp> 781e4b17023SJohn Marino inline complex<_Tp> 782e4b17023SJohn Marino log(const complex<_Tp>& __z) { return __complex_log(__z); } 783e4b17023SJohn Marino#endif 784e4b17023SJohn Marino 785e4b17023SJohn Marino template<typename _Tp> 786e4b17023SJohn Marino inline complex<_Tp> 787e4b17023SJohn Marino log10(const complex<_Tp>& __z) 788e4b17023SJohn Marino { return std::log(__z) / log(_Tp(10.0)); } 789e4b17023SJohn Marino 790e4b17023SJohn Marino // 26.2.8/10 sin(__z): Returns the sine of __z. 791e4b17023SJohn Marino template<typename _Tp> 792e4b17023SJohn Marino inline complex<_Tp> 793e4b17023SJohn Marino __complex_sin(const complex<_Tp>& __z) 794e4b17023SJohn Marino { 795e4b17023SJohn Marino const _Tp __x = __z.real(); 796e4b17023SJohn Marino const _Tp __y = __z.imag(); 797e4b17023SJohn Marino return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 798e4b17023SJohn Marino } 799e4b17023SJohn Marino 800e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 801e4b17023SJohn Marino inline __complex__ float 802e4b17023SJohn Marino __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); } 803e4b17023SJohn Marino 804e4b17023SJohn Marino inline __complex__ double 805e4b17023SJohn Marino __complex_sin(__complex__ double __z) { return __builtin_csin(__z); } 806e4b17023SJohn Marino 807e4b17023SJohn Marino inline __complex__ long double 808e4b17023SJohn Marino __complex_sin(const __complex__ long double& __z) 809e4b17023SJohn Marino { return __builtin_csinl(__z); } 810e4b17023SJohn Marino 811e4b17023SJohn Marino template<typename _Tp> 812e4b17023SJohn Marino inline complex<_Tp> 813e4b17023SJohn Marino sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); } 814e4b17023SJohn Marino#else 815e4b17023SJohn Marino template<typename _Tp> 816e4b17023SJohn Marino inline complex<_Tp> 817e4b17023SJohn Marino sin(const complex<_Tp>& __z) { return __complex_sin(__z); } 818e4b17023SJohn Marino#endif 819e4b17023SJohn Marino 820e4b17023SJohn Marino // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z. 821e4b17023SJohn Marino template<typename _Tp> 822e4b17023SJohn Marino inline complex<_Tp> 823e4b17023SJohn Marino __complex_sinh(const complex<_Tp>& __z) 824e4b17023SJohn Marino { 825e4b17023SJohn Marino const _Tp __x = __z.real(); 826e4b17023SJohn Marino const _Tp __y = __z.imag(); 827e4b17023SJohn Marino return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); 828e4b17023SJohn Marino } 829e4b17023SJohn Marino 830e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 831e4b17023SJohn Marino inline __complex__ float 832e4b17023SJohn Marino __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); } 833e4b17023SJohn Marino 834e4b17023SJohn Marino inline __complex__ double 835e4b17023SJohn Marino __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); } 836e4b17023SJohn Marino 837e4b17023SJohn Marino inline __complex__ long double 838e4b17023SJohn Marino __complex_sinh(const __complex__ long double& __z) 839e4b17023SJohn Marino { return __builtin_csinhl(__z); } 840e4b17023SJohn Marino 841e4b17023SJohn Marino template<typename _Tp> 842e4b17023SJohn Marino inline complex<_Tp> 843e4b17023SJohn Marino sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); } 844e4b17023SJohn Marino#else 845e4b17023SJohn Marino template<typename _Tp> 846e4b17023SJohn Marino inline complex<_Tp> 847e4b17023SJohn Marino sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); } 848e4b17023SJohn Marino#endif 849e4b17023SJohn Marino 850e4b17023SJohn Marino // 26.2.8/13 sqrt(__z): Returns the complex square root of __z. 851e4b17023SJohn Marino // The branch cut is on the negative axis. 852e4b17023SJohn Marino template<typename _Tp> 853e4b17023SJohn Marino complex<_Tp> 854e4b17023SJohn Marino __complex_sqrt(const complex<_Tp>& __z) 855e4b17023SJohn Marino { 856e4b17023SJohn Marino _Tp __x = __z.real(); 857e4b17023SJohn Marino _Tp __y = __z.imag(); 858e4b17023SJohn Marino 859e4b17023SJohn Marino if (__x == _Tp()) 860e4b17023SJohn Marino { 861e4b17023SJohn Marino _Tp __t = sqrt(abs(__y) / 2); 862e4b17023SJohn Marino return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); 863e4b17023SJohn Marino } 864e4b17023SJohn Marino else 865e4b17023SJohn Marino { 866e4b17023SJohn Marino _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); 867e4b17023SJohn Marino _Tp __u = __t / 2; 868e4b17023SJohn Marino return __x > _Tp() 869e4b17023SJohn Marino ? complex<_Tp>(__u, __y / __t) 870e4b17023SJohn Marino : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); 871e4b17023SJohn Marino } 872e4b17023SJohn Marino } 873e4b17023SJohn Marino 874e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 875e4b17023SJohn Marino inline __complex__ float 876e4b17023SJohn Marino __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); } 877e4b17023SJohn Marino 878e4b17023SJohn Marino inline __complex__ double 879e4b17023SJohn Marino __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); } 880e4b17023SJohn Marino 881e4b17023SJohn Marino inline __complex__ long double 882e4b17023SJohn Marino __complex_sqrt(const __complex__ long double& __z) 883e4b17023SJohn Marino { return __builtin_csqrtl(__z); } 884e4b17023SJohn Marino 885e4b17023SJohn Marino template<typename _Tp> 886e4b17023SJohn Marino inline complex<_Tp> 887e4b17023SJohn Marino sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); } 888e4b17023SJohn Marino#else 889e4b17023SJohn Marino template<typename _Tp> 890e4b17023SJohn Marino inline complex<_Tp> 891e4b17023SJohn Marino sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); } 892e4b17023SJohn Marino#endif 893e4b17023SJohn Marino 894e4b17023SJohn Marino // 26.2.8/14 tan(__z): Return the complex tangent of __z. 895e4b17023SJohn Marino 896e4b17023SJohn Marino template<typename _Tp> 897e4b17023SJohn Marino inline complex<_Tp> 898e4b17023SJohn Marino __complex_tan(const complex<_Tp>& __z) 899e4b17023SJohn Marino { return std::sin(__z) / std::cos(__z); } 900e4b17023SJohn Marino 901e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 902e4b17023SJohn Marino inline __complex__ float 903e4b17023SJohn Marino __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); } 904e4b17023SJohn Marino 905e4b17023SJohn Marino inline __complex__ double 906e4b17023SJohn Marino __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); } 907e4b17023SJohn Marino 908e4b17023SJohn Marino inline __complex__ long double 909e4b17023SJohn Marino __complex_tan(const __complex__ long double& __z) 910e4b17023SJohn Marino { return __builtin_ctanl(__z); } 911e4b17023SJohn Marino 912e4b17023SJohn Marino template<typename _Tp> 913e4b17023SJohn Marino inline complex<_Tp> 914e4b17023SJohn Marino tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); } 915e4b17023SJohn Marino#else 916e4b17023SJohn Marino template<typename _Tp> 917e4b17023SJohn Marino inline complex<_Tp> 918e4b17023SJohn Marino tan(const complex<_Tp>& __z) { return __complex_tan(__z); } 919e4b17023SJohn Marino#endif 920e4b17023SJohn Marino 921e4b17023SJohn Marino 922e4b17023SJohn Marino // 26.2.8/15 tanh(__z): Returns the hyperbolic tangent of __z. 923e4b17023SJohn Marino 924e4b17023SJohn Marino template<typename _Tp> 925e4b17023SJohn Marino inline complex<_Tp> 926e4b17023SJohn Marino __complex_tanh(const complex<_Tp>& __z) 927e4b17023SJohn Marino { return std::sinh(__z) / std::cosh(__z); } 928e4b17023SJohn Marino 929e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 930e4b17023SJohn Marino inline __complex__ float 931e4b17023SJohn Marino __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); } 932e4b17023SJohn Marino 933e4b17023SJohn Marino inline __complex__ double 934e4b17023SJohn Marino __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); } 935e4b17023SJohn Marino 936e4b17023SJohn Marino inline __complex__ long double 937e4b17023SJohn Marino __complex_tanh(const __complex__ long double& __z) 938e4b17023SJohn Marino { return __builtin_ctanhl(__z); } 939e4b17023SJohn Marino 940e4b17023SJohn Marino template<typename _Tp> 941e4b17023SJohn Marino inline complex<_Tp> 942e4b17023SJohn Marino tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); } 943e4b17023SJohn Marino#else 944e4b17023SJohn Marino template<typename _Tp> 945e4b17023SJohn Marino inline complex<_Tp> 946e4b17023SJohn Marino tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); } 947e4b17023SJohn Marino#endif 948e4b17023SJohn Marino 949e4b17023SJohn Marino 950e4b17023SJohn Marino // 26.2.8/9 pow(__x, __y): Returns the complex power base of __x 951e4b17023SJohn Marino // raised to the __y-th power. The branch 952e4b17023SJohn Marino // cut is on the negative axis. 953e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__ 954e4b17023SJohn Marino template<typename _Tp> 955e4b17023SJohn Marino complex<_Tp> 956e4b17023SJohn Marino __complex_pow_unsigned(complex<_Tp> __x, unsigned __n) 957e4b17023SJohn Marino { 958e4b17023SJohn Marino complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(1); 959e4b17023SJohn Marino 960e4b17023SJohn Marino while (__n >>= 1) 961e4b17023SJohn Marino { 962e4b17023SJohn Marino __x *= __x; 963e4b17023SJohn Marino if (__n % 2) 964e4b17023SJohn Marino __y *= __x; 965e4b17023SJohn Marino } 966e4b17023SJohn Marino 967e4b17023SJohn Marino return __y; 968e4b17023SJohn Marino } 969e4b17023SJohn Marino 970e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 971e4b17023SJohn Marino // DR 844. complex pow return type is ambiguous. 972e4b17023SJohn Marino template<typename _Tp> 973e4b17023SJohn Marino inline complex<_Tp> 974e4b17023SJohn Marino pow(const complex<_Tp>& __z, int __n) 975e4b17023SJohn Marino { 976e4b17023SJohn Marino return __n < 0 977*5ce9237cSJohn Marino ? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n) 978e4b17023SJohn Marino : std::__complex_pow_unsigned(__z, __n); 979e4b17023SJohn Marino } 980e4b17023SJohn Marino#endif 981e4b17023SJohn Marino 982e4b17023SJohn Marino template<typename _Tp> 983e4b17023SJohn Marino complex<_Tp> 984e4b17023SJohn Marino pow(const complex<_Tp>& __x, const _Tp& __y) 985e4b17023SJohn Marino { 986e4b17023SJohn Marino#ifndef _GLIBCXX_USE_C99_COMPLEX 987e4b17023SJohn Marino if (__x == _Tp()) 988e4b17023SJohn Marino return _Tp(); 989e4b17023SJohn Marino#endif 990e4b17023SJohn Marino if (__x.imag() == _Tp() && __x.real() > _Tp()) 991e4b17023SJohn Marino return pow(__x.real(), __y); 992e4b17023SJohn Marino 993e4b17023SJohn Marino complex<_Tp> __t = std::log(__x); 994e4b17023SJohn Marino return std::polar(exp(__y * __t.real()), __y * __t.imag()); 995e4b17023SJohn Marino } 996e4b17023SJohn Marino 997e4b17023SJohn Marino template<typename _Tp> 998e4b17023SJohn Marino inline complex<_Tp> 999e4b17023SJohn Marino __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 1000e4b17023SJohn Marino { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } 1001e4b17023SJohn Marino 1002e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 1003e4b17023SJohn Marino inline __complex__ float 1004e4b17023SJohn Marino __complex_pow(__complex__ float __x, __complex__ float __y) 1005e4b17023SJohn Marino { return __builtin_cpowf(__x, __y); } 1006e4b17023SJohn Marino 1007e4b17023SJohn Marino inline __complex__ double 1008e4b17023SJohn Marino __complex_pow(__complex__ double __x, __complex__ double __y) 1009e4b17023SJohn Marino { return __builtin_cpow(__x, __y); } 1010e4b17023SJohn Marino 1011e4b17023SJohn Marino inline __complex__ long double 1012e4b17023SJohn Marino __complex_pow(const __complex__ long double& __x, 1013e4b17023SJohn Marino const __complex__ long double& __y) 1014e4b17023SJohn Marino { return __builtin_cpowl(__x, __y); } 1015e4b17023SJohn Marino 1016e4b17023SJohn Marino template<typename _Tp> 1017e4b17023SJohn Marino inline complex<_Tp> 1018e4b17023SJohn Marino pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 1019e4b17023SJohn Marino { return __complex_pow(__x.__rep(), __y.__rep()); } 1020e4b17023SJohn Marino#else 1021e4b17023SJohn Marino template<typename _Tp> 1022e4b17023SJohn Marino inline complex<_Tp> 1023e4b17023SJohn Marino pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 1024e4b17023SJohn Marino { return __complex_pow(__x, __y); } 1025e4b17023SJohn Marino#endif 1026e4b17023SJohn Marino 1027e4b17023SJohn Marino template<typename _Tp> 1028e4b17023SJohn Marino inline complex<_Tp> 1029e4b17023SJohn Marino pow(const _Tp& __x, const complex<_Tp>& __y) 1030e4b17023SJohn Marino { 1031e4b17023SJohn Marino return __x > _Tp() ? std::polar(pow(__x, __y.real()), 1032e4b17023SJohn Marino __y.imag() * log(__x)) 1033e4b17023SJohn Marino : std::pow(complex<_Tp>(__x), __y); 1034e4b17023SJohn Marino } 1035e4b17023SJohn Marino 1036e4b17023SJohn Marino /// 26.2.3 complex specializations 1037e4b17023SJohn Marino /// complex<float> specialization 1038e4b17023SJohn Marino template<> 1039e4b17023SJohn Marino struct complex<float> 1040e4b17023SJohn Marino { 1041e4b17023SJohn Marino typedef float value_type; 1042e4b17023SJohn Marino typedef __complex__ float _ComplexT; 1043e4b17023SJohn Marino 1044e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } 1045e4b17023SJohn Marino 1046e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(float __r = 0.0f, float __i = 0.0f) 1047e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 1048e4b17023SJohn Marino : _M_value{ __r, __i } { } 1049e4b17023SJohn Marino#else 1050e4b17023SJohn Marino { 1051e4b17023SJohn Marino __real__ _M_value = __r; 1052e4b17023SJohn Marino __imag__ _M_value = __i; 1053e4b17023SJohn Marino } 1054e4b17023SJohn Marino#endif 1055e4b17023SJohn Marino 1056e4b17023SJohn Marino explicit _GLIBCXX_CONSTEXPR complex(const complex<double>&); 1057e4b17023SJohn Marino explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&); 1058e4b17023SJohn Marino 1059e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 1060e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 1061e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 1062e4b17023SJohn Marino constexpr float 1063e4b17023SJohn Marino real() { return __real__ _M_value; } 1064e4b17023SJohn Marino 1065e4b17023SJohn Marino constexpr float 1066e4b17023SJohn Marino imag() { return __imag__ _M_value; } 1067e4b17023SJohn Marino#else 1068e4b17023SJohn Marino float& 1069e4b17023SJohn Marino real() { return __real__ _M_value; } 1070e4b17023SJohn Marino 1071e4b17023SJohn Marino const float& 1072e4b17023SJohn Marino real() const { return __real__ _M_value; } 1073e4b17023SJohn Marino 1074e4b17023SJohn Marino float& 1075e4b17023SJohn Marino imag() { return __imag__ _M_value; } 1076e4b17023SJohn Marino 1077e4b17023SJohn Marino const float& 1078e4b17023SJohn Marino imag() const { return __imag__ _M_value; } 1079e4b17023SJohn Marino#endif 1080e4b17023SJohn Marino 1081e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 1082e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 1083e4b17023SJohn Marino void 1084e4b17023SJohn Marino real(float __val) { __real__ _M_value = __val; } 1085e4b17023SJohn Marino 1086e4b17023SJohn Marino void 1087e4b17023SJohn Marino imag(float __val) { __imag__ _M_value = __val; } 1088e4b17023SJohn Marino 1089e4b17023SJohn Marino complex& 1090e4b17023SJohn Marino operator=(float __f) 1091e4b17023SJohn Marino { 1092e4b17023SJohn Marino _M_value = __f; 1093e4b17023SJohn Marino return *this; 1094e4b17023SJohn Marino } 1095e4b17023SJohn Marino 1096e4b17023SJohn Marino complex& 1097e4b17023SJohn Marino operator+=(float __f) 1098e4b17023SJohn Marino { 1099e4b17023SJohn Marino _M_value += __f; 1100e4b17023SJohn Marino return *this; 1101e4b17023SJohn Marino } 1102e4b17023SJohn Marino 1103e4b17023SJohn Marino complex& 1104e4b17023SJohn Marino operator-=(float __f) 1105e4b17023SJohn Marino { 1106e4b17023SJohn Marino _M_value -= __f; 1107e4b17023SJohn Marino return *this; 1108e4b17023SJohn Marino } 1109e4b17023SJohn Marino 1110e4b17023SJohn Marino complex& 1111e4b17023SJohn Marino operator*=(float __f) 1112e4b17023SJohn Marino { 1113e4b17023SJohn Marino _M_value *= __f; 1114e4b17023SJohn Marino return *this; 1115e4b17023SJohn Marino } 1116e4b17023SJohn Marino 1117e4b17023SJohn Marino complex& 1118e4b17023SJohn Marino operator/=(float __f) 1119e4b17023SJohn Marino { 1120e4b17023SJohn Marino _M_value /= __f; 1121e4b17023SJohn Marino return *this; 1122e4b17023SJohn Marino } 1123e4b17023SJohn Marino 1124e4b17023SJohn Marino // Let the compiler synthesize the copy and assignment 1125e4b17023SJohn Marino // operator. It always does a pretty good job. 1126e4b17023SJohn Marino // complex& operator=(const complex&); 1127e4b17023SJohn Marino 1128e4b17023SJohn Marino template<typename _Tp> 1129e4b17023SJohn Marino complex& 1130e4b17023SJohn Marino operator=(const complex<_Tp>& __z) 1131e4b17023SJohn Marino { 1132e4b17023SJohn Marino __real__ _M_value = __z.real(); 1133e4b17023SJohn Marino __imag__ _M_value = __z.imag(); 1134e4b17023SJohn Marino return *this; 1135e4b17023SJohn Marino } 1136e4b17023SJohn Marino 1137e4b17023SJohn Marino template<typename _Tp> 1138e4b17023SJohn Marino complex& 1139e4b17023SJohn Marino operator+=(const complex<_Tp>& __z) 1140e4b17023SJohn Marino { 1141e4b17023SJohn Marino __real__ _M_value += __z.real(); 1142e4b17023SJohn Marino __imag__ _M_value += __z.imag(); 1143e4b17023SJohn Marino return *this; 1144e4b17023SJohn Marino } 1145e4b17023SJohn Marino 1146e4b17023SJohn Marino template<class _Tp> 1147e4b17023SJohn Marino complex& 1148e4b17023SJohn Marino operator-=(const complex<_Tp>& __z) 1149e4b17023SJohn Marino { 1150e4b17023SJohn Marino __real__ _M_value -= __z.real(); 1151e4b17023SJohn Marino __imag__ _M_value -= __z.imag(); 1152e4b17023SJohn Marino return *this; 1153e4b17023SJohn Marino } 1154e4b17023SJohn Marino 1155e4b17023SJohn Marino template<class _Tp> 1156e4b17023SJohn Marino complex& 1157e4b17023SJohn Marino operator*=(const complex<_Tp>& __z) 1158e4b17023SJohn Marino { 1159e4b17023SJohn Marino _ComplexT __t; 1160e4b17023SJohn Marino __real__ __t = __z.real(); 1161e4b17023SJohn Marino __imag__ __t = __z.imag(); 1162e4b17023SJohn Marino _M_value *= __t; 1163e4b17023SJohn Marino return *this; 1164e4b17023SJohn Marino } 1165e4b17023SJohn Marino 1166e4b17023SJohn Marino template<class _Tp> 1167e4b17023SJohn Marino complex& 1168e4b17023SJohn Marino operator/=(const complex<_Tp>& __z) 1169e4b17023SJohn Marino { 1170e4b17023SJohn Marino _ComplexT __t; 1171e4b17023SJohn Marino __real__ __t = __z.real(); 1172e4b17023SJohn Marino __imag__ __t = __z.imag(); 1173e4b17023SJohn Marino _M_value /= __t; 1174e4b17023SJohn Marino return *this; 1175e4b17023SJohn Marino } 1176e4b17023SJohn Marino 1177e4b17023SJohn Marino _GLIBCXX_USE_CONSTEXPR _ComplexT __rep() const { return _M_value; } 1178e4b17023SJohn Marino 1179e4b17023SJohn Marino private: 1180e4b17023SJohn Marino _ComplexT _M_value; 1181e4b17023SJohn Marino }; 1182e4b17023SJohn Marino 1183e4b17023SJohn Marino /// 26.2.3 complex specializations 1184e4b17023SJohn Marino /// complex<double> specialization 1185e4b17023SJohn Marino template<> 1186e4b17023SJohn Marino struct complex<double> 1187e4b17023SJohn Marino { 1188e4b17023SJohn Marino typedef double value_type; 1189e4b17023SJohn Marino typedef __complex__ double _ComplexT; 1190e4b17023SJohn Marino 1191e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } 1192e4b17023SJohn Marino 1193e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(double __r = 0.0, double __i = 0.0) 1194e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 1195e4b17023SJohn Marino : _M_value{ __r, __i } { } 1196e4b17023SJohn Marino#else 1197e4b17023SJohn Marino { 1198e4b17023SJohn Marino __real__ _M_value = __r; 1199e4b17023SJohn Marino __imag__ _M_value = __i; 1200e4b17023SJohn Marino } 1201e4b17023SJohn Marino#endif 1202e4b17023SJohn Marino 1203e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(const complex<float>& __z) 1204e4b17023SJohn Marino : _M_value(__z.__rep()) { } 1205e4b17023SJohn Marino 1206e4b17023SJohn Marino explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&); 1207e4b17023SJohn Marino 1208e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 1209e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 1210e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 1211e4b17023SJohn Marino constexpr double 1212e4b17023SJohn Marino real() { return __real__ _M_value; } 1213e4b17023SJohn Marino 1214e4b17023SJohn Marino constexpr double 1215e4b17023SJohn Marino imag() { return __imag__ _M_value; } 1216e4b17023SJohn Marino#else 1217e4b17023SJohn Marino double& 1218e4b17023SJohn Marino real() { return __real__ _M_value; } 1219e4b17023SJohn Marino 1220e4b17023SJohn Marino const double& 1221e4b17023SJohn Marino real() const { return __real__ _M_value; } 1222e4b17023SJohn Marino 1223e4b17023SJohn Marino double& 1224e4b17023SJohn Marino imag() { return __imag__ _M_value; } 1225e4b17023SJohn Marino 1226e4b17023SJohn Marino const double& 1227e4b17023SJohn Marino imag() const { return __imag__ _M_value; } 1228e4b17023SJohn Marino#endif 1229e4b17023SJohn Marino 1230e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 1231e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 1232e4b17023SJohn Marino void 1233e4b17023SJohn Marino real(double __val) { __real__ _M_value = __val; } 1234e4b17023SJohn Marino 1235e4b17023SJohn Marino void 1236e4b17023SJohn Marino imag(double __val) { __imag__ _M_value = __val; } 1237e4b17023SJohn Marino 1238e4b17023SJohn Marino complex& 1239e4b17023SJohn Marino operator=(double __d) 1240e4b17023SJohn Marino { 1241e4b17023SJohn Marino _M_value = __d; 1242e4b17023SJohn Marino return *this; 1243e4b17023SJohn Marino } 1244e4b17023SJohn Marino 1245e4b17023SJohn Marino complex& 1246e4b17023SJohn Marino operator+=(double __d) 1247e4b17023SJohn Marino { 1248e4b17023SJohn Marino _M_value += __d; 1249e4b17023SJohn Marino return *this; 1250e4b17023SJohn Marino } 1251e4b17023SJohn Marino 1252e4b17023SJohn Marino complex& 1253e4b17023SJohn Marino operator-=(double __d) 1254e4b17023SJohn Marino { 1255e4b17023SJohn Marino _M_value -= __d; 1256e4b17023SJohn Marino return *this; 1257e4b17023SJohn Marino } 1258e4b17023SJohn Marino 1259e4b17023SJohn Marino complex& 1260e4b17023SJohn Marino operator*=(double __d) 1261e4b17023SJohn Marino { 1262e4b17023SJohn Marino _M_value *= __d; 1263e4b17023SJohn Marino return *this; 1264e4b17023SJohn Marino } 1265e4b17023SJohn Marino 1266e4b17023SJohn Marino complex& 1267e4b17023SJohn Marino operator/=(double __d) 1268e4b17023SJohn Marino { 1269e4b17023SJohn Marino _M_value /= __d; 1270e4b17023SJohn Marino return *this; 1271e4b17023SJohn Marino } 1272e4b17023SJohn Marino 1273e4b17023SJohn Marino // The compiler will synthesize this, efficiently. 1274e4b17023SJohn Marino // complex& operator=(const complex&); 1275e4b17023SJohn Marino 1276e4b17023SJohn Marino template<typename _Tp> 1277e4b17023SJohn Marino complex& 1278e4b17023SJohn Marino operator=(const complex<_Tp>& __z) 1279e4b17023SJohn Marino { 1280e4b17023SJohn Marino __real__ _M_value = __z.real(); 1281e4b17023SJohn Marino __imag__ _M_value = __z.imag(); 1282e4b17023SJohn Marino return *this; 1283e4b17023SJohn Marino } 1284e4b17023SJohn Marino 1285e4b17023SJohn Marino template<typename _Tp> 1286e4b17023SJohn Marino complex& 1287e4b17023SJohn Marino operator+=(const complex<_Tp>& __z) 1288e4b17023SJohn Marino { 1289e4b17023SJohn Marino __real__ _M_value += __z.real(); 1290e4b17023SJohn Marino __imag__ _M_value += __z.imag(); 1291e4b17023SJohn Marino return *this; 1292e4b17023SJohn Marino } 1293e4b17023SJohn Marino 1294e4b17023SJohn Marino template<typename _Tp> 1295e4b17023SJohn Marino complex& 1296e4b17023SJohn Marino operator-=(const complex<_Tp>& __z) 1297e4b17023SJohn Marino { 1298e4b17023SJohn Marino __real__ _M_value -= __z.real(); 1299e4b17023SJohn Marino __imag__ _M_value -= __z.imag(); 1300e4b17023SJohn Marino return *this; 1301e4b17023SJohn Marino } 1302e4b17023SJohn Marino 1303e4b17023SJohn Marino template<typename _Tp> 1304e4b17023SJohn Marino complex& 1305e4b17023SJohn Marino operator*=(const complex<_Tp>& __z) 1306e4b17023SJohn Marino { 1307e4b17023SJohn Marino _ComplexT __t; 1308e4b17023SJohn Marino __real__ __t = __z.real(); 1309e4b17023SJohn Marino __imag__ __t = __z.imag(); 1310e4b17023SJohn Marino _M_value *= __t; 1311e4b17023SJohn Marino return *this; 1312e4b17023SJohn Marino } 1313e4b17023SJohn Marino 1314e4b17023SJohn Marino template<typename _Tp> 1315e4b17023SJohn Marino complex& 1316e4b17023SJohn Marino operator/=(const complex<_Tp>& __z) 1317e4b17023SJohn Marino { 1318e4b17023SJohn Marino _ComplexT __t; 1319e4b17023SJohn Marino __real__ __t = __z.real(); 1320e4b17023SJohn Marino __imag__ __t = __z.imag(); 1321e4b17023SJohn Marino _M_value /= __t; 1322e4b17023SJohn Marino return *this; 1323e4b17023SJohn Marino } 1324e4b17023SJohn Marino 1325e4b17023SJohn Marino _GLIBCXX_USE_CONSTEXPR _ComplexT __rep() const { return _M_value; } 1326e4b17023SJohn Marino 1327e4b17023SJohn Marino private: 1328e4b17023SJohn Marino _ComplexT _M_value; 1329e4b17023SJohn Marino }; 1330e4b17023SJohn Marino 1331e4b17023SJohn Marino /// 26.2.3 complex specializations 1332e4b17023SJohn Marino /// complex<long double> specialization 1333e4b17023SJohn Marino template<> 1334e4b17023SJohn Marino struct complex<long double> 1335e4b17023SJohn Marino { 1336e4b17023SJohn Marino typedef long double value_type; 1337e4b17023SJohn Marino typedef __complex__ long double _ComplexT; 1338e4b17023SJohn Marino 1339e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } 1340e4b17023SJohn Marino 1341e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(long double __r = 0.0L, 1342e4b17023SJohn Marino long double __i = 0.0L) 1343e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 1344e4b17023SJohn Marino : _M_value{ __r, __i } { } 1345e4b17023SJohn Marino#else 1346e4b17023SJohn Marino { 1347e4b17023SJohn Marino __real__ _M_value = __r; 1348e4b17023SJohn Marino __imag__ _M_value = __i; 1349e4b17023SJohn Marino } 1350e4b17023SJohn Marino#endif 1351e4b17023SJohn Marino 1352e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(const complex<float>& __z) 1353e4b17023SJohn Marino : _M_value(__z.__rep()) { } 1354e4b17023SJohn Marino 1355e4b17023SJohn Marino _GLIBCXX_CONSTEXPR complex(const complex<double>& __z) 1356e4b17023SJohn Marino : _M_value(__z.__rep()) { } 1357e4b17023SJohn Marino 1358e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 1359e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 1360e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 1361e4b17023SJohn Marino constexpr long double 1362e4b17023SJohn Marino real() { return __real__ _M_value; } 1363e4b17023SJohn Marino 1364e4b17023SJohn Marino constexpr long double 1365e4b17023SJohn Marino imag() { return __imag__ _M_value; } 1366e4b17023SJohn Marino#else 1367e4b17023SJohn Marino long double& 1368e4b17023SJohn Marino real() { return __real__ _M_value; } 1369e4b17023SJohn Marino 1370e4b17023SJohn Marino const long double& 1371e4b17023SJohn Marino real() const { return __real__ _M_value; } 1372e4b17023SJohn Marino 1373e4b17023SJohn Marino long double& 1374e4b17023SJohn Marino imag() { return __imag__ _M_value; } 1375e4b17023SJohn Marino 1376e4b17023SJohn Marino const long double& 1377e4b17023SJohn Marino imag() const { return __imag__ _M_value; } 1378e4b17023SJohn Marino#endif 1379e4b17023SJohn Marino 1380e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 1381e4b17023SJohn Marino // DR 387. std::complex over-encapsulated. 1382e4b17023SJohn Marino void 1383e4b17023SJohn Marino real(long double __val) { __real__ _M_value = __val; } 1384e4b17023SJohn Marino 1385e4b17023SJohn Marino void 1386e4b17023SJohn Marino imag(long double __val) { __imag__ _M_value = __val; } 1387e4b17023SJohn Marino 1388e4b17023SJohn Marino complex& 1389e4b17023SJohn Marino operator=(long double __r) 1390e4b17023SJohn Marino { 1391e4b17023SJohn Marino _M_value = __r; 1392e4b17023SJohn Marino return *this; 1393e4b17023SJohn Marino } 1394e4b17023SJohn Marino 1395e4b17023SJohn Marino complex& 1396e4b17023SJohn Marino operator+=(long double __r) 1397e4b17023SJohn Marino { 1398e4b17023SJohn Marino _M_value += __r; 1399e4b17023SJohn Marino return *this; 1400e4b17023SJohn Marino } 1401e4b17023SJohn Marino 1402e4b17023SJohn Marino complex& 1403e4b17023SJohn Marino operator-=(long double __r) 1404e4b17023SJohn Marino { 1405e4b17023SJohn Marino _M_value -= __r; 1406e4b17023SJohn Marino return *this; 1407e4b17023SJohn Marino } 1408e4b17023SJohn Marino 1409e4b17023SJohn Marino complex& 1410e4b17023SJohn Marino operator*=(long double __r) 1411e4b17023SJohn Marino { 1412e4b17023SJohn Marino _M_value *= __r; 1413e4b17023SJohn Marino return *this; 1414e4b17023SJohn Marino } 1415e4b17023SJohn Marino 1416e4b17023SJohn Marino complex& 1417e4b17023SJohn Marino operator/=(long double __r) 1418e4b17023SJohn Marino { 1419e4b17023SJohn Marino _M_value /= __r; 1420e4b17023SJohn Marino return *this; 1421e4b17023SJohn Marino } 1422e4b17023SJohn Marino 1423e4b17023SJohn Marino // The compiler knows how to do this efficiently 1424e4b17023SJohn Marino // complex& operator=(const complex&); 1425e4b17023SJohn Marino 1426e4b17023SJohn Marino template<typename _Tp> 1427e4b17023SJohn Marino complex& 1428e4b17023SJohn Marino operator=(const complex<_Tp>& __z) 1429e4b17023SJohn Marino { 1430e4b17023SJohn Marino __real__ _M_value = __z.real(); 1431e4b17023SJohn Marino __imag__ _M_value = __z.imag(); 1432e4b17023SJohn Marino return *this; 1433e4b17023SJohn Marino } 1434e4b17023SJohn Marino 1435e4b17023SJohn Marino template<typename _Tp> 1436e4b17023SJohn Marino complex& 1437e4b17023SJohn Marino operator+=(const complex<_Tp>& __z) 1438e4b17023SJohn Marino { 1439e4b17023SJohn Marino __real__ _M_value += __z.real(); 1440e4b17023SJohn Marino __imag__ _M_value += __z.imag(); 1441e4b17023SJohn Marino return *this; 1442e4b17023SJohn Marino } 1443e4b17023SJohn Marino 1444e4b17023SJohn Marino template<typename _Tp> 1445e4b17023SJohn Marino complex& 1446e4b17023SJohn Marino operator-=(const complex<_Tp>& __z) 1447e4b17023SJohn Marino { 1448e4b17023SJohn Marino __real__ _M_value -= __z.real(); 1449e4b17023SJohn Marino __imag__ _M_value -= __z.imag(); 1450e4b17023SJohn Marino return *this; 1451e4b17023SJohn Marino } 1452e4b17023SJohn Marino 1453e4b17023SJohn Marino template<typename _Tp> 1454e4b17023SJohn Marino complex& 1455e4b17023SJohn Marino operator*=(const complex<_Tp>& __z) 1456e4b17023SJohn Marino { 1457e4b17023SJohn Marino _ComplexT __t; 1458e4b17023SJohn Marino __real__ __t = __z.real(); 1459e4b17023SJohn Marino __imag__ __t = __z.imag(); 1460e4b17023SJohn Marino _M_value *= __t; 1461e4b17023SJohn Marino return *this; 1462e4b17023SJohn Marino } 1463e4b17023SJohn Marino 1464e4b17023SJohn Marino template<typename _Tp> 1465e4b17023SJohn Marino complex& 1466e4b17023SJohn Marino operator/=(const complex<_Tp>& __z) 1467e4b17023SJohn Marino { 1468e4b17023SJohn Marino _ComplexT __t; 1469e4b17023SJohn Marino __real__ __t = __z.real(); 1470e4b17023SJohn Marino __imag__ __t = __z.imag(); 1471e4b17023SJohn Marino _M_value /= __t; 1472e4b17023SJohn Marino return *this; 1473e4b17023SJohn Marino } 1474e4b17023SJohn Marino 1475e4b17023SJohn Marino _GLIBCXX_USE_CONSTEXPR _ComplexT __rep() const { return _M_value; } 1476e4b17023SJohn Marino 1477e4b17023SJohn Marino private: 1478e4b17023SJohn Marino _ComplexT _M_value; 1479e4b17023SJohn Marino }; 1480e4b17023SJohn Marino 1481e4b17023SJohn Marino // These bits have to be at the end of this file, so that the 1482e4b17023SJohn Marino // specializations have all been defined. 1483e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR 1484e4b17023SJohn Marino complex<float>::complex(const complex<double>& __z) 1485e4b17023SJohn Marino : _M_value(__z.__rep()) { } 1486e4b17023SJohn Marino 1487e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR 1488e4b17023SJohn Marino complex<float>::complex(const complex<long double>& __z) 1489e4b17023SJohn Marino : _M_value(__z.__rep()) { } 1490e4b17023SJohn Marino 1491e4b17023SJohn Marino inline _GLIBCXX_CONSTEXPR 1492e4b17023SJohn Marino complex<double>::complex(const complex<long double>& __z) 1493e4b17023SJohn Marino : _M_value(__z.__rep()) { } 1494e4b17023SJohn Marino 1495e4b17023SJohn Marino // Inhibit implicit instantiations for required instantiations, 1496e4b17023SJohn Marino // which are defined via explicit instantiations elsewhere. 1497e4b17023SJohn Marino // NB: This syntax is a GNU extension. 1498e4b17023SJohn Marino#if _GLIBCXX_EXTERN_TEMPLATE 1499e4b17023SJohn Marino extern template istream& operator>>(istream&, complex<float>&); 1500e4b17023SJohn Marino extern template ostream& operator<<(ostream&, const complex<float>&); 1501e4b17023SJohn Marino extern template istream& operator>>(istream&, complex<double>&); 1502e4b17023SJohn Marino extern template ostream& operator<<(ostream&, const complex<double>&); 1503e4b17023SJohn Marino extern template istream& operator>>(istream&, complex<long double>&); 1504e4b17023SJohn Marino extern template ostream& operator<<(ostream&, const complex<long double>&); 1505e4b17023SJohn Marino 1506e4b17023SJohn Marino#ifdef _GLIBCXX_USE_WCHAR_T 1507e4b17023SJohn Marino extern template wistream& operator>>(wistream&, complex<float>&); 1508e4b17023SJohn Marino extern template wostream& operator<<(wostream&, const complex<float>&); 1509e4b17023SJohn Marino extern template wistream& operator>>(wistream&, complex<double>&); 1510e4b17023SJohn Marino extern template wostream& operator<<(wostream&, const complex<double>&); 1511e4b17023SJohn Marino extern template wistream& operator>>(wistream&, complex<long double>&); 1512e4b17023SJohn Marino extern template wostream& operator<<(wostream&, const complex<long double>&); 1513e4b17023SJohn Marino#endif 1514e4b17023SJohn Marino#endif 1515e4b17023SJohn Marino 1516e4b17023SJohn Marino // @} group complex_numbers 1517e4b17023SJohn Marino 1518e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 1519e4b17023SJohn Marino} // namespace 1520e4b17023SJohn Marino 1521e4b17023SJohn Marinonamespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 1522e4b17023SJohn Marino{ 1523e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 1524e4b17023SJohn Marino 1525e4b17023SJohn Marino // See ext/type_traits.h for the primary template. 1526e4b17023SJohn Marino template<typename _Tp, typename _Up> 1527e4b17023SJohn Marino struct __promote_2<std::complex<_Tp>, _Up> 1528e4b17023SJohn Marino { 1529e4b17023SJohn Marino public: 1530e4b17023SJohn Marino typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 1531e4b17023SJohn Marino }; 1532e4b17023SJohn Marino 1533e4b17023SJohn Marino template<typename _Tp, typename _Up> 1534e4b17023SJohn Marino struct __promote_2<_Tp, std::complex<_Up> > 1535e4b17023SJohn Marino { 1536e4b17023SJohn Marino public: 1537e4b17023SJohn Marino typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 1538e4b17023SJohn Marino }; 1539e4b17023SJohn Marino 1540e4b17023SJohn Marino template<typename _Tp, typename _Up> 1541e4b17023SJohn Marino struct __promote_2<std::complex<_Tp>, std::complex<_Up> > 1542e4b17023SJohn Marino { 1543e4b17023SJohn Marino public: 1544e4b17023SJohn Marino typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type; 1545e4b17023SJohn Marino }; 1546e4b17023SJohn Marino 1547e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 1548e4b17023SJohn Marino} // namespace 1549e4b17023SJohn Marino 1550e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 1551e4b17023SJohn Marino 1552e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 1553e4b17023SJohn Marino{ 1554e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 1555e4b17023SJohn Marino 1556e4b17023SJohn Marino // Forward declarations. 1557e4b17023SJohn Marino template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 1558e4b17023SJohn Marino template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 1559e4b17023SJohn Marino template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 1560e4b17023SJohn Marino 1561e4b17023SJohn Marino template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 1562e4b17023SJohn Marino template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 1563e4b17023SJohn Marino template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 1564e4b17023SJohn Marino // DR 595. 1565e4b17023SJohn Marino template<typename _Tp> _Tp fabs(const std::complex<_Tp>&); 1566e4b17023SJohn Marino 1567e4b17023SJohn Marino template<typename _Tp> 1568e4b17023SJohn Marino inline std::complex<_Tp> 1569e4b17023SJohn Marino __complex_acos(const std::complex<_Tp>& __z) 1570e4b17023SJohn Marino { 1571e4b17023SJohn Marino const std::complex<_Tp> __t = std::asin(__z); 1572e4b17023SJohn Marino const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 1573e4b17023SJohn Marino return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 1574e4b17023SJohn Marino } 1575e4b17023SJohn Marino 1576e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1 1577e4b17023SJohn Marino inline __complex__ float 1578e4b17023SJohn Marino __complex_acos(__complex__ float __z) 1579e4b17023SJohn Marino { return __builtin_cacosf(__z); } 1580e4b17023SJohn Marino 1581e4b17023SJohn Marino inline __complex__ double 1582e4b17023SJohn Marino __complex_acos(__complex__ double __z) 1583e4b17023SJohn Marino { return __builtin_cacos(__z); } 1584e4b17023SJohn Marino 1585e4b17023SJohn Marino inline __complex__ long double 1586e4b17023SJohn Marino __complex_acos(const __complex__ long double& __z) 1587e4b17023SJohn Marino { return __builtin_cacosl(__z); } 1588e4b17023SJohn Marino 1589e4b17023SJohn Marino template<typename _Tp> 1590e4b17023SJohn Marino inline std::complex<_Tp> 1591e4b17023SJohn Marino acos(const std::complex<_Tp>& __z) 1592e4b17023SJohn Marino { return __complex_acos(__z.__rep()); } 1593e4b17023SJohn Marino#else 1594e4b17023SJohn Marino /// acos(__z) [8.1.2]. 1595e4b17023SJohn Marino // Effects: Behaves the same as C99 function cacos, defined 1596e4b17023SJohn Marino // in subclause 7.3.5.1. 1597e4b17023SJohn Marino template<typename _Tp> 1598e4b17023SJohn Marino inline std::complex<_Tp> 1599e4b17023SJohn Marino acos(const std::complex<_Tp>& __z) 1600e4b17023SJohn Marino { return __complex_acos(__z); } 1601e4b17023SJohn Marino#endif 1602e4b17023SJohn Marino 1603e4b17023SJohn Marino template<typename _Tp> 1604e4b17023SJohn Marino inline std::complex<_Tp> 1605e4b17023SJohn Marino __complex_asin(const std::complex<_Tp>& __z) 1606e4b17023SJohn Marino { 1607e4b17023SJohn Marino std::complex<_Tp> __t(-__z.imag(), __z.real()); 1608e4b17023SJohn Marino __t = std::asinh(__t); 1609e4b17023SJohn Marino return std::complex<_Tp>(__t.imag(), -__t.real()); 1610e4b17023SJohn Marino } 1611e4b17023SJohn Marino 1612e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1 1613e4b17023SJohn Marino inline __complex__ float 1614e4b17023SJohn Marino __complex_asin(__complex__ float __z) 1615e4b17023SJohn Marino { return __builtin_casinf(__z); } 1616e4b17023SJohn Marino 1617e4b17023SJohn Marino inline __complex__ double 1618e4b17023SJohn Marino __complex_asin(__complex__ double __z) 1619e4b17023SJohn Marino { return __builtin_casin(__z); } 1620e4b17023SJohn Marino 1621e4b17023SJohn Marino inline __complex__ long double 1622e4b17023SJohn Marino __complex_asin(const __complex__ long double& __z) 1623e4b17023SJohn Marino { return __builtin_casinl(__z); } 1624e4b17023SJohn Marino 1625e4b17023SJohn Marino template<typename _Tp> 1626e4b17023SJohn Marino inline std::complex<_Tp> 1627e4b17023SJohn Marino asin(const std::complex<_Tp>& __z) 1628e4b17023SJohn Marino { return __complex_asin(__z.__rep()); } 1629e4b17023SJohn Marino#else 1630e4b17023SJohn Marino /// asin(__z) [8.1.3]. 1631e4b17023SJohn Marino // Effects: Behaves the same as C99 function casin, defined 1632e4b17023SJohn Marino // in subclause 7.3.5.2. 1633e4b17023SJohn Marino template<typename _Tp> 1634e4b17023SJohn Marino inline std::complex<_Tp> 1635e4b17023SJohn Marino asin(const std::complex<_Tp>& __z) 1636e4b17023SJohn Marino { return __complex_asin(__z); } 1637e4b17023SJohn Marino#endif 1638e4b17023SJohn Marino 1639e4b17023SJohn Marino template<typename _Tp> 1640e4b17023SJohn Marino std::complex<_Tp> 1641e4b17023SJohn Marino __complex_atan(const std::complex<_Tp>& __z) 1642e4b17023SJohn Marino { 1643e4b17023SJohn Marino const _Tp __r2 = __z.real() * __z.real(); 1644e4b17023SJohn Marino const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 1645e4b17023SJohn Marino 1646e4b17023SJohn Marino _Tp __num = __z.imag() + _Tp(1.0); 1647e4b17023SJohn Marino _Tp __den = __z.imag() - _Tp(1.0); 1648e4b17023SJohn Marino 1649e4b17023SJohn Marino __num = __r2 + __num * __num; 1650e4b17023SJohn Marino __den = __r2 + __den * __den; 1651e4b17023SJohn Marino 1652e4b17023SJohn Marino return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 1653e4b17023SJohn Marino _Tp(0.25) * log(__num / __den)); 1654e4b17023SJohn Marino } 1655e4b17023SJohn Marino 1656e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1 1657e4b17023SJohn Marino inline __complex__ float 1658e4b17023SJohn Marino __complex_atan(__complex__ float __z) 1659e4b17023SJohn Marino { return __builtin_catanf(__z); } 1660e4b17023SJohn Marino 1661e4b17023SJohn Marino inline __complex__ double 1662e4b17023SJohn Marino __complex_atan(__complex__ double __z) 1663e4b17023SJohn Marino { return __builtin_catan(__z); } 1664e4b17023SJohn Marino 1665e4b17023SJohn Marino inline __complex__ long double 1666e4b17023SJohn Marino __complex_atan(const __complex__ long double& __z) 1667e4b17023SJohn Marino { return __builtin_catanl(__z); } 1668e4b17023SJohn Marino 1669e4b17023SJohn Marino template<typename _Tp> 1670e4b17023SJohn Marino inline std::complex<_Tp> 1671e4b17023SJohn Marino atan(const std::complex<_Tp>& __z) 1672e4b17023SJohn Marino { return __complex_atan(__z.__rep()); } 1673e4b17023SJohn Marino#else 1674e4b17023SJohn Marino /// atan(__z) [8.1.4]. 1675e4b17023SJohn Marino // Effects: Behaves the same as C99 function catan, defined 1676e4b17023SJohn Marino // in subclause 7.3.5.3. 1677e4b17023SJohn Marino template<typename _Tp> 1678e4b17023SJohn Marino inline std::complex<_Tp> 1679e4b17023SJohn Marino atan(const std::complex<_Tp>& __z) 1680e4b17023SJohn Marino { return __complex_atan(__z); } 1681e4b17023SJohn Marino#endif 1682e4b17023SJohn Marino 1683e4b17023SJohn Marino template<typename _Tp> 1684e4b17023SJohn Marino std::complex<_Tp> 1685e4b17023SJohn Marino __complex_acosh(const std::complex<_Tp>& __z) 1686e4b17023SJohn Marino { 1687e4b17023SJohn Marino // Kahan's formula. 1688e4b17023SJohn Marino return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0))) 1689e4b17023SJohn Marino + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0)))); 1690e4b17023SJohn Marino } 1691e4b17023SJohn Marino 1692e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1 1693e4b17023SJohn Marino inline __complex__ float 1694e4b17023SJohn Marino __complex_acosh(__complex__ float __z) 1695e4b17023SJohn Marino { return __builtin_cacoshf(__z); } 1696e4b17023SJohn Marino 1697e4b17023SJohn Marino inline __complex__ double 1698e4b17023SJohn Marino __complex_acosh(__complex__ double __z) 1699e4b17023SJohn Marino { return __builtin_cacosh(__z); } 1700e4b17023SJohn Marino 1701e4b17023SJohn Marino inline __complex__ long double 1702e4b17023SJohn Marino __complex_acosh(const __complex__ long double& __z) 1703e4b17023SJohn Marino { return __builtin_cacoshl(__z); } 1704e4b17023SJohn Marino 1705e4b17023SJohn Marino template<typename _Tp> 1706e4b17023SJohn Marino inline std::complex<_Tp> 1707e4b17023SJohn Marino acosh(const std::complex<_Tp>& __z) 1708e4b17023SJohn Marino { return __complex_acosh(__z.__rep()); } 1709e4b17023SJohn Marino#else 1710e4b17023SJohn Marino /// acosh(__z) [8.1.5]. 1711e4b17023SJohn Marino // Effects: Behaves the same as C99 function cacosh, defined 1712e4b17023SJohn Marino // in subclause 7.3.6.1. 1713e4b17023SJohn Marino template<typename _Tp> 1714e4b17023SJohn Marino inline std::complex<_Tp> 1715e4b17023SJohn Marino acosh(const std::complex<_Tp>& __z) 1716e4b17023SJohn Marino { return __complex_acosh(__z); } 1717e4b17023SJohn Marino#endif 1718e4b17023SJohn Marino 1719e4b17023SJohn Marino template<typename _Tp> 1720e4b17023SJohn Marino std::complex<_Tp> 1721e4b17023SJohn Marino __complex_asinh(const std::complex<_Tp>& __z) 1722e4b17023SJohn Marino { 1723e4b17023SJohn Marino std::complex<_Tp> __t((__z.real() - __z.imag()) 1724e4b17023SJohn Marino * (__z.real() + __z.imag()) + _Tp(1.0), 1725e4b17023SJohn Marino _Tp(2.0) * __z.real() * __z.imag()); 1726e4b17023SJohn Marino __t = std::sqrt(__t); 1727e4b17023SJohn Marino 1728e4b17023SJohn Marino return std::log(__t + __z); 1729e4b17023SJohn Marino } 1730e4b17023SJohn Marino 1731e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1 1732e4b17023SJohn Marino inline __complex__ float 1733e4b17023SJohn Marino __complex_asinh(__complex__ float __z) 1734e4b17023SJohn Marino { return __builtin_casinhf(__z); } 1735e4b17023SJohn Marino 1736e4b17023SJohn Marino inline __complex__ double 1737e4b17023SJohn Marino __complex_asinh(__complex__ double __z) 1738e4b17023SJohn Marino { return __builtin_casinh(__z); } 1739e4b17023SJohn Marino 1740e4b17023SJohn Marino inline __complex__ long double 1741e4b17023SJohn Marino __complex_asinh(const __complex__ long double& __z) 1742e4b17023SJohn Marino { return __builtin_casinhl(__z); } 1743e4b17023SJohn Marino 1744e4b17023SJohn Marino template<typename _Tp> 1745e4b17023SJohn Marino inline std::complex<_Tp> 1746e4b17023SJohn Marino asinh(const std::complex<_Tp>& __z) 1747e4b17023SJohn Marino { return __complex_asinh(__z.__rep()); } 1748e4b17023SJohn Marino#else 1749e4b17023SJohn Marino /// asinh(__z) [8.1.6]. 1750e4b17023SJohn Marino // Effects: Behaves the same as C99 function casin, defined 1751e4b17023SJohn Marino // in subclause 7.3.6.2. 1752e4b17023SJohn Marino template<typename _Tp> 1753e4b17023SJohn Marino inline std::complex<_Tp> 1754e4b17023SJohn Marino asinh(const std::complex<_Tp>& __z) 1755e4b17023SJohn Marino { return __complex_asinh(__z); } 1756e4b17023SJohn Marino#endif 1757e4b17023SJohn Marino 1758e4b17023SJohn Marino template<typename _Tp> 1759e4b17023SJohn Marino std::complex<_Tp> 1760e4b17023SJohn Marino __complex_atanh(const std::complex<_Tp>& __z) 1761e4b17023SJohn Marino { 1762e4b17023SJohn Marino const _Tp __i2 = __z.imag() * __z.imag(); 1763e4b17023SJohn Marino const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 1764e4b17023SJohn Marino 1765e4b17023SJohn Marino _Tp __num = _Tp(1.0) + __z.real(); 1766e4b17023SJohn Marino _Tp __den = _Tp(1.0) - __z.real(); 1767e4b17023SJohn Marino 1768e4b17023SJohn Marino __num = __i2 + __num * __num; 1769e4b17023SJohn Marino __den = __i2 + __den * __den; 1770e4b17023SJohn Marino 1771e4b17023SJohn Marino return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 1772e4b17023SJohn Marino _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 1773e4b17023SJohn Marino } 1774e4b17023SJohn Marino 1775e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1 1776e4b17023SJohn Marino inline __complex__ float 1777e4b17023SJohn Marino __complex_atanh(__complex__ float __z) 1778e4b17023SJohn Marino { return __builtin_catanhf(__z); } 1779e4b17023SJohn Marino 1780e4b17023SJohn Marino inline __complex__ double 1781e4b17023SJohn Marino __complex_atanh(__complex__ double __z) 1782e4b17023SJohn Marino { return __builtin_catanh(__z); } 1783e4b17023SJohn Marino 1784e4b17023SJohn Marino inline __complex__ long double 1785e4b17023SJohn Marino __complex_atanh(const __complex__ long double& __z) 1786e4b17023SJohn Marino { return __builtin_catanhl(__z); } 1787e4b17023SJohn Marino 1788e4b17023SJohn Marino template<typename _Tp> 1789e4b17023SJohn Marino inline std::complex<_Tp> 1790e4b17023SJohn Marino atanh(const std::complex<_Tp>& __z) 1791e4b17023SJohn Marino { return __complex_atanh(__z.__rep()); } 1792e4b17023SJohn Marino#else 1793e4b17023SJohn Marino /// atanh(__z) [8.1.7]. 1794e4b17023SJohn Marino // Effects: Behaves the same as C99 function catanh, defined 1795e4b17023SJohn Marino // in subclause 7.3.6.3. 1796e4b17023SJohn Marino template<typename _Tp> 1797e4b17023SJohn Marino inline std::complex<_Tp> 1798e4b17023SJohn Marino atanh(const std::complex<_Tp>& __z) 1799e4b17023SJohn Marino { return __complex_atanh(__z); } 1800e4b17023SJohn Marino#endif 1801e4b17023SJohn Marino 1802e4b17023SJohn Marino template<typename _Tp> 1803e4b17023SJohn Marino inline _Tp 1804e4b17023SJohn Marino /// fabs(__z) [8.1.8]. 1805e4b17023SJohn Marino // Effects: Behaves the same as C99 function cabs, defined 1806e4b17023SJohn Marino // in subclause 7.3.8.1. 1807e4b17023SJohn Marino fabs(const std::complex<_Tp>& __z) 1808e4b17023SJohn Marino { return std::abs(__z); } 1809e4b17023SJohn Marino 1810e4b17023SJohn Marino /// Additional overloads [8.1.9]. 1811e4b17023SJohn Marino template<typename _Tp> 1812e4b17023SJohn Marino inline typename __gnu_cxx::__promote<_Tp>::__type 1813e4b17023SJohn Marino arg(_Tp __x) 1814e4b17023SJohn Marino { 1815e4b17023SJohn Marino typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 1816e4b17023SJohn Marino#if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) 1817e4b17023SJohn Marino return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L) 1818e4b17023SJohn Marino : __type(); 1819e4b17023SJohn Marino#else 1820e4b17023SJohn Marino return std::arg(std::complex<__type>(__x)); 1821e4b17023SJohn Marino#endif 1822e4b17023SJohn Marino } 1823e4b17023SJohn Marino 1824e4b17023SJohn Marino template<typename _Tp> 1825e4b17023SJohn Marino inline typename __gnu_cxx::__promote<_Tp>::__type 1826e4b17023SJohn Marino imag(_Tp) 1827e4b17023SJohn Marino { return _Tp(); } 1828e4b17023SJohn Marino 1829e4b17023SJohn Marino template<typename _Tp> 1830e4b17023SJohn Marino inline typename __gnu_cxx::__promote<_Tp>::__type 1831e4b17023SJohn Marino norm(_Tp __x) 1832e4b17023SJohn Marino { 1833e4b17023SJohn Marino typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 1834e4b17023SJohn Marino return __type(__x) * __type(__x); 1835e4b17023SJohn Marino } 1836e4b17023SJohn Marino 1837e4b17023SJohn Marino template<typename _Tp> 1838e4b17023SJohn Marino inline typename __gnu_cxx::__promote<_Tp>::__type 1839e4b17023SJohn Marino real(_Tp __x) 1840e4b17023SJohn Marino { return __x; } 1841e4b17023SJohn Marino 1842e4b17023SJohn Marino template<typename _Tp, typename _Up> 1843e4b17023SJohn Marino inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 1844e4b17023SJohn Marino pow(const std::complex<_Tp>& __x, const _Up& __y) 1845e4b17023SJohn Marino { 1846e4b17023SJohn Marino typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 1847e4b17023SJohn Marino return std::pow(std::complex<__type>(__x), __type(__y)); 1848e4b17023SJohn Marino } 1849e4b17023SJohn Marino 1850e4b17023SJohn Marino template<typename _Tp, typename _Up> 1851e4b17023SJohn Marino inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 1852e4b17023SJohn Marino pow(const _Tp& __x, const std::complex<_Up>& __y) 1853e4b17023SJohn Marino { 1854e4b17023SJohn Marino typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 1855e4b17023SJohn Marino return std::pow(__type(__x), std::complex<__type>(__y)); 1856e4b17023SJohn Marino } 1857e4b17023SJohn Marino 1858e4b17023SJohn Marino template<typename _Tp, typename _Up> 1859e4b17023SJohn Marino inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 1860e4b17023SJohn Marino pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) 1861e4b17023SJohn Marino { 1862e4b17023SJohn Marino typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 1863e4b17023SJohn Marino return std::pow(std::complex<__type>(__x), 1864e4b17023SJohn Marino std::complex<__type>(__y)); 1865e4b17023SJohn Marino } 1866e4b17023SJohn Marino 1867e4b17023SJohn Marino // Forward declarations. 1868e4b17023SJohn Marino // DR 781. 1869e4b17023SJohn Marino template<typename _Tp> std::complex<_Tp> proj(const std::complex<_Tp>&); 1870e4b17023SJohn Marino 1871e4b17023SJohn Marino template<typename _Tp> 1872e4b17023SJohn Marino std::complex<_Tp> 1873e4b17023SJohn Marino __complex_proj(const std::complex<_Tp>& __z) 1874e4b17023SJohn Marino { 1875e4b17023SJohn Marino const _Tp __den = (__z.real() * __z.real() 1876e4b17023SJohn Marino + __z.imag() * __z.imag() + _Tp(1.0)); 1877e4b17023SJohn Marino 1878e4b17023SJohn Marino return std::complex<_Tp>((_Tp(2.0) * __z.real()) / __den, 1879e4b17023SJohn Marino (_Tp(2.0) * __z.imag()) / __den); 1880e4b17023SJohn Marino } 1881e4b17023SJohn Marino 1882e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX 1883e4b17023SJohn Marino inline __complex__ float 1884e4b17023SJohn Marino __complex_proj(__complex__ float __z) 1885e4b17023SJohn Marino { return __builtin_cprojf(__z); } 1886e4b17023SJohn Marino 1887e4b17023SJohn Marino inline __complex__ double 1888e4b17023SJohn Marino __complex_proj(__complex__ double __z) 1889e4b17023SJohn Marino { return __builtin_cproj(__z); } 1890e4b17023SJohn Marino 1891e4b17023SJohn Marino inline __complex__ long double 1892e4b17023SJohn Marino __complex_proj(const __complex__ long double& __z) 1893e4b17023SJohn Marino { return __builtin_cprojl(__z); } 1894e4b17023SJohn Marino 1895e4b17023SJohn Marino template<typename _Tp> 1896e4b17023SJohn Marino inline std::complex<_Tp> 1897e4b17023SJohn Marino proj(const std::complex<_Tp>& __z) 1898e4b17023SJohn Marino { return __complex_proj(__z.__rep()); } 1899e4b17023SJohn Marino#else 1900e4b17023SJohn Marino template<typename _Tp> 1901e4b17023SJohn Marino inline std::complex<_Tp> 1902e4b17023SJohn Marino proj(const std::complex<_Tp>& __z) 1903e4b17023SJohn Marino { return __complex_proj(__z); } 1904e4b17023SJohn Marino#endif 1905e4b17023SJohn Marino 1906e4b17023SJohn Marino // DR 1137. 1907e4b17023SJohn Marino template<typename _Tp> 1908e4b17023SJohn Marino inline typename __gnu_cxx::__promote<_Tp>::__type 1909e4b17023SJohn Marino proj(_Tp __x) 1910e4b17023SJohn Marino { return __x; } 1911e4b17023SJohn Marino 1912e4b17023SJohn Marino template<typename _Tp> 1913e4b17023SJohn Marino inline typename __gnu_cxx::__promote<_Tp>::__type 1914e4b17023SJohn Marino conj(_Tp __x) 1915e4b17023SJohn Marino { return __x; } 1916e4b17023SJohn Marino 1917e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 1918e4b17023SJohn Marino} // namespace 1919e4b17023SJohn Marino 1920e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__ 1921e4b17023SJohn Marino 1922e4b17023SJohn Marino#endif /* _GLIBCXX_COMPLEX */ 1923