1// The template and inlines for the -*- C++ -*- complex number classes. 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 2, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING. If not, write to the Free 19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20// USA. 21 22// As a special exception, you may use this file as part of a free software 23// library without restriction. Specifically, if other files instantiate 24// templates or use macros or inline functions from this file, or you compile 25// this file and link it with other files to produce an executable, this 26// file does not by itself cause the resulting executable to be covered by 27// the GNU General Public License. This exception does not however 28// invalidate any other reasons why the executable file might be covered by 29// the GNU General Public License. 30 31// 32// ISO C++ 14882: 26.2 Complex Numbers 33// Note: this is not a conforming implementation. 34// Initially implemented by Ulrich Drepper <drepper@cygnus.com> 35// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 36// 37 38/** @file complex 39 * This is a Standard C++ Library header. You should @c #include this header 40 * in your programs, rather than any of the "st[dl]_*.h" implementation files. 41 */ 42 43#ifndef _CPP_COMPLEX 44#define _CPP_COMPLEX 1 45 46#pragma GCC system_header 47 48#include <bits/c++config.h> 49#include <bits/cpp_type_traits.h> 50#include <cmath> 51#include <sstream> 52 53namespace std 54{ 55 // Forward declarations 56 template<typename _Tp> class complex; 57 template<> class complex<float>; 58 template<> class complex<double>; 59 template<> class complex<long double>; 60 61 template<typename _Tp> _Tp abs(const complex<_Tp>&); 62 template<typename _Tp> _Tp arg(const complex<_Tp>&); 63 template<typename _Tp> _Tp norm(const complex<_Tp>&); 64 65 template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); 66 template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); 67 68 // Transcendentals: 69 template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); 70 template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); 71 template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); 72 template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); 73 template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); 74 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); 75 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); 76 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 77 const complex<_Tp>&); 78 template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); 79 template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); 80 template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); 81 template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); 82 template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); 83 template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); 84 85 86 // 26.2.2 Primary template class complex 87 template<typename _Tp> 88 class complex 89 { 90 public: 91 typedef _Tp value_type; 92 93 complex(const _Tp& = _Tp(), const _Tp & = _Tp()); 94 95 // Let's the compiler synthetize the copy constructor 96 // complex (const complex<_Tp>&); 97 template<typename _Up> 98 complex(const complex<_Up>&); 99 100 _Tp real() const; 101 _Tp imag() const; 102 103 complex<_Tp>& operator=(const _Tp&); 104 complex<_Tp>& operator+=(const _Tp&); 105 complex<_Tp>& operator-=(const _Tp&); 106 complex<_Tp>& operator*=(const _Tp&); 107 complex<_Tp>& operator/=(const _Tp&); 108 109 // Let's the compiler synthetize the 110 // copy and assignment operator 111 // complex<_Tp>& operator= (const complex<_Tp>&); 112 template<typename _Up> 113 complex<_Tp>& operator=(const complex<_Up>&); 114 template<typename _Up> 115 complex<_Tp>& operator+=(const complex<_Up>&); 116 template<typename _Up> 117 complex<_Tp>& operator-=(const complex<_Up>&); 118 template<typename _Up> 119 complex<_Tp>& operator*=(const complex<_Up>&); 120 template<typename _Up> 121 complex<_Tp>& operator/=(const complex<_Up>&); 122 123 private: 124 _Tp _M_real, _M_imag; 125 }; 126 127 template<typename _Tp> 128 inline _Tp 129 complex<_Tp>::real() const { return _M_real; } 130 131 template<typename _Tp> 132 inline _Tp 133 complex<_Tp>::imag() const { return _M_imag; } 134 135 template<typename _Tp> 136 inline 137 complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) 138 : _M_real(__r), _M_imag(__i) { } 139 140 template<typename _Tp> 141 template<typename _Up> 142 inline 143 complex<_Tp>::complex(const complex<_Up>& __z) 144 : _M_real(__z.real()), _M_imag(__z.imag()) { } 145 146 template<typename _Tp> 147 complex<_Tp>& 148 complex<_Tp>::operator=(const _Tp& __t) 149 { 150 _M_real = __t; 151 _M_imag = _Tp(); 152 return *this; 153 } 154 155 // 26.2.5/1 156 template<typename _Tp> 157 inline complex<_Tp>& 158 complex<_Tp>::operator+=(const _Tp& __t) 159 { 160 _M_real += __t; 161 return *this; 162 } 163 164 // 26.2.5/3 165 template<typename _Tp> 166 inline complex<_Tp>& 167 complex<_Tp>::operator-=(const _Tp& __t) 168 { 169 _M_real -= __t; 170 return *this; 171 } 172 173 // 26.2.5/5 174 template<typename _Tp> 175 complex<_Tp>& 176 complex<_Tp>::operator*=(const _Tp& __t) 177 { 178 _M_real *= __t; 179 _M_imag *= __t; 180 return *this; 181 } 182 183 // 26.2.5/7 184 template<typename _Tp> 185 complex<_Tp>& 186 complex<_Tp>::operator/=(const _Tp& __t) 187 { 188 _M_real /= __t; 189 _M_imag /= __t; 190 return *this; 191 } 192 193 template<typename _Tp> 194 template<typename _Up> 195 complex<_Tp>& 196 complex<_Tp>::operator=(const complex<_Up>& __z) 197 { 198 _M_real = __z.real(); 199 _M_imag = __z.imag(); 200 return *this; 201 } 202 203 // 26.2.5/9 204 template<typename _Tp> 205 template<typename _Up> 206 complex<_Tp>& 207 complex<_Tp>::operator+=(const complex<_Up>& __z) 208 { 209 _M_real += __z.real(); 210 _M_imag += __z.imag(); 211 return *this; 212 } 213 214 // 26.2.5/11 215 template<typename _Tp> 216 template<typename _Up> 217 complex<_Tp>& 218 complex<_Tp>::operator-=(const complex<_Up>& __z) 219 { 220 _M_real -= __z.real(); 221 _M_imag -= __z.imag(); 222 return *this; 223 } 224 225 // 26.2.5/13 226 // XXX: This is a grammar school implementation. 227 template<typename _Tp> 228 template<typename _Up> 229 complex<_Tp>& 230 complex<_Tp>::operator*=(const complex<_Up>& __z) 231 { 232 const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); 233 _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); 234 _M_real = __r; 235 return *this; 236 } 237 238 // 26.2.5/15 239 // XXX: This is a grammar school implementation. 240 template<typename _Tp> 241 template<typename _Up> 242 complex<_Tp>& 243 complex<_Tp>::operator/=(const complex<_Up>& __z) 244 { 245 const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); 246 const _Tp __n = norm(__z); 247 _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; 248 _M_real = __r / __n; 249 return *this; 250 } 251 252 // Operators: 253 template<typename _Tp> 254 inline complex<_Tp> 255 operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 256 { return complex<_Tp> (__x) += __y; } 257 258 template<typename _Tp> 259 inline complex<_Tp> 260 operator+(const complex<_Tp>& __x, const _Tp& __y) 261 { return complex<_Tp> (__x) += __y; } 262 263 template<typename _Tp> 264 inline complex<_Tp> 265 operator+(const _Tp& __x, const complex<_Tp>& __y) 266 { return complex<_Tp> (__y) += __x; } 267 268 template<typename _Tp> 269 inline complex<_Tp> 270 operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 271 { return complex<_Tp> (__x) -= __y; } 272 273 template<typename _Tp> 274 inline complex<_Tp> 275 operator-(const complex<_Tp>& __x, const _Tp& __y) 276 { return complex<_Tp> (__x) -= __y; } 277 278 template<typename _Tp> 279 inline complex<_Tp> 280 operator-(const _Tp& __x, const complex<_Tp>& __y) 281 { return complex<_Tp> (__x) -= __y; } 282 283 template<typename _Tp> 284 inline complex<_Tp> 285 operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) 286 { return complex<_Tp> (__x) *= __y; } 287 288 template<typename _Tp> 289 inline complex<_Tp> 290 operator*(const complex<_Tp>& __x, const _Tp& __y) 291 { return complex<_Tp> (__x) *= __y; } 292 293 template<typename _Tp> 294 inline complex<_Tp> 295 operator*(const _Tp& __x, const complex<_Tp>& __y) 296 { return complex<_Tp> (__y) *= __x; } 297 298 template<typename _Tp> 299 inline complex<_Tp> 300 operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) 301 { return complex<_Tp> (__x) /= __y; } 302 303 template<typename _Tp> 304 inline complex<_Tp> 305 operator/(const complex<_Tp>& __x, const _Tp& __y) 306 { return complex<_Tp> (__x) /= __y; } 307 308 template<typename _Tp> 309 inline complex<_Tp> 310 operator/(const _Tp& __x, const complex<_Tp>& __y) 311 { return complex<_Tp> (__x) /= __y; } 312 313 template<typename _Tp> 314 inline complex<_Tp> 315 operator+(const complex<_Tp>& __x) 316 { return __x; } 317 318 template<typename _Tp> 319 inline complex<_Tp> 320 operator-(const complex<_Tp>& __x) 321 { return complex<_Tp>(-__x.real(), -__x.imag()); } 322 323 template<typename _Tp> 324 inline bool 325 operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 326 { return __x.real() == __y.real() && __x.imag() == __y.imag(); } 327 328 template<typename _Tp> 329 inline bool 330 operator==(const complex<_Tp>& __x, const _Tp& __y) 331 { return __x.real() == __y && __x.imag() == _Tp(); } 332 333 template<typename _Tp> 334 inline bool 335 operator==(const _Tp& __x, const complex<_Tp>& __y) 336 { return __x == __y.real() && _Tp() == __y.imag(); } 337 338 template<typename _Tp> 339 inline bool 340 operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 341 { return __x.real() != __y.real() || __x.imag() != __y.imag(); } 342 343 template<typename _Tp> 344 inline bool 345 operator!=(const complex<_Tp>& __x, const _Tp& __y) 346 { return __x.real() != __y || __x.imag() != _Tp(); } 347 348 template<typename _Tp> 349 inline bool 350 operator!=(const _Tp& __x, const complex<_Tp>& __y) 351 { return __x != __y.real() || _Tp() != __y.imag(); } 352 353 template<typename _Tp, typename _CharT, class _Traits> 354 basic_istream<_CharT, _Traits>& 355 operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 356 { 357 _Tp __re_x, __im_x; 358 _CharT __ch; 359 __is >> __ch; 360 if (__ch == '(') 361 { 362 __is >> __re_x >> __ch; 363 if (__ch == ',') 364 { 365 __is >> __im_x >> __ch; 366 if (__ch == ')') 367 __x = complex<_Tp>(__re_x, __im_x); 368 else 369 __is.setstate(ios_base::failbit); 370 } 371 else if (__ch == ')') 372 __x = complex<_Tp>(__re_x, _Tp(0)); 373 else 374 __is.setstate(ios_base::failbit); 375 } 376 else 377 { 378 __is.putback(__ch); 379 __is >> __re_x; 380 __x = complex<_Tp>(__re_x, _Tp(0)); 381 } 382 return __is; 383 } 384 385 template<typename _Tp, typename _CharT, class _Traits> 386 basic_ostream<_CharT, _Traits>& 387 operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 388 { 389 basic_ostringstream<_CharT, _Traits> __s; 390 __s.flags(__os.flags()); 391 __s.imbue(__os.getloc()); 392 __s.precision(__os.precision()); 393 __s << '(' << __x.real() << ',' << __x.imag() << ')'; 394 return __os << __s.str(); 395 } 396 397 // Values 398 template<typename _Tp> 399 inline _Tp 400 real(const complex<_Tp>& __z) 401 { return __z.real(); } 402 403 template<typename _Tp> 404 inline _Tp 405 imag(const complex<_Tp>& __z) 406 { return __z.imag(); } 407 408 template<typename _Tp> 409 inline _Tp 410 abs(const complex<_Tp>& __z) 411 { 412 _Tp __x = __z.real(); 413 _Tp __y = __z.imag(); 414 const _Tp __s = max(abs(__x), abs(__y)); 415 if (__s == _Tp()) // well ... 416 return __s; 417 __x /= __s; 418 __y /= __s; 419 return __s * sqrt(__x * __x + __y * __y); 420 } 421 422 template<typename _Tp> 423 inline _Tp 424 arg(const complex<_Tp>& __z) 425 { return atan2(__z.imag(), __z.real()); } 426 427 // 26.2.7/5: norm(__z) returns the squared magintude of __z. 428 // As defined, norm() is -not- a norm is the common mathematical 429 // sens used in numerics. The helper class _Norm_helper<> tries to 430 // distinguish between builtin floating point and the rest, so as 431 // to deliver an answer as close as possible to the real value. 432 template<bool> 433 struct _Norm_helper 434 { 435 template<typename _Tp> 436 static inline _Tp _S_do_it(const complex<_Tp>& __z) 437 { 438 const _Tp __x = __z.real(); 439 const _Tp __y = __z.imag(); 440 return __x * __x + __y * __y; 441 } 442 }; 443 444 template<> 445 struct _Norm_helper<true> 446 { 447 template<typename _Tp> 448 static inline _Tp _S_do_it(const complex<_Tp>& __z) 449 { 450 _Tp __res = abs(__z); 451 return __res * __res; 452 } 453 }; 454 455 template<typename _Tp> 456 inline _Tp 457 norm(const complex<_Tp>& __z) 458 { 459 return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCPP_FAST_MATH>::_S_do_it(__z); 460 } 461 462 template<typename _Tp> 463 inline complex<_Tp> 464 polar(const _Tp& __rho, const _Tp& __theta) 465 { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } 466 467 template<typename _Tp> 468 inline complex<_Tp> 469 conj(const complex<_Tp>& __z) 470 { return complex<_Tp>(__z.real(), -__z.imag()); } 471 472 // Transcendentals 473 template<typename _Tp> 474 inline complex<_Tp> 475 cos(const complex<_Tp>& __z) 476 { 477 const _Tp __x = __z.real(); 478 const _Tp __y = __z.imag(); 479 return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); 480 } 481 482 template<typename _Tp> 483 inline complex<_Tp> 484 cosh(const complex<_Tp>& __z) 485 { 486 const _Tp __x = __z.real(); 487 const _Tp __y = __z.imag(); 488 return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); 489 } 490 491 template<typename _Tp> 492 inline complex<_Tp> 493 exp(const complex<_Tp>& __z) 494 { return polar(exp(__z.real()), __z.imag()); } 495 496 template<typename _Tp> 497 inline complex<_Tp> 498 log(const complex<_Tp>& __z) 499 { return complex<_Tp>(log(abs(__z)), arg(__z)); } 500 501 template<typename _Tp> 502 inline complex<_Tp> 503 log10(const complex<_Tp>& __z) 504 { return log(__z) / log(_Tp(10.0)); } 505 506 template<typename _Tp> 507 inline complex<_Tp> 508 sin(const complex<_Tp>& __z) 509 { 510 const _Tp __x = __z.real(); 511 const _Tp __y = __z.imag(); 512 return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 513 } 514 515 template<typename _Tp> 516 inline complex<_Tp> 517 sinh(const complex<_Tp>& __z) 518 { 519 const _Tp __x = __z.real(); 520 const _Tp __y = __z.imag(); 521 return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); 522 } 523 524 template<typename _Tp> 525 complex<_Tp> 526 sqrt(const complex<_Tp>& __z) 527 { 528 _Tp __x = __z.real(); 529 _Tp __y = __z.imag(); 530 531 if (__x == _Tp()) 532 { 533 _Tp __t = sqrt(abs(__y) / 2); 534 return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); 535 } 536 else 537 { 538 _Tp __t = sqrt(2 * (abs(__z) + abs(__x))); 539 _Tp __u = __t / 2; 540 return __x > _Tp() 541 ? complex<_Tp>(__u, __y / __t) 542 : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); 543 } 544 } 545 546 template<typename _Tp> 547 inline complex<_Tp> 548 tan(const complex<_Tp>& __z) 549 { 550 return sin(__z) / cos(__z); 551 } 552 553 template<typename _Tp> 554 inline complex<_Tp> 555 tanh(const complex<_Tp>& __z) 556 { 557 return sinh(__z) / cosh(__z); 558 } 559 560 template<typename _Tp> 561 inline complex<_Tp> 562 pow(const complex<_Tp>& __z, int __n) 563 { 564 return __pow_helper(__z, __n); 565 } 566 567 template<typename _Tp> 568 complex<_Tp> 569 pow(const complex<_Tp>& __x, const _Tp& __y) 570 { 571 if (__x.imag() == _Tp()) 572 return pow(__x.real(), __y); 573 574 complex<_Tp> __t = log(__x); 575 return polar(exp(__y * __t.real()), __y * __t.imag()); 576 } 577 578 template<typename _Tp> 579 inline complex<_Tp> 580 pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 581 { 582 return __x == _Tp() ? _Tp() : exp(__y * log(__x)); 583 } 584 585 template<typename _Tp> 586 inline complex<_Tp> 587 pow(const _Tp& __x, const complex<_Tp>& __y) 588 { 589 return __x == _Tp() 590 ? _Tp() 591 : polar(pow(__x, __y.real()), __y.imag() * log(__x)); 592 } 593 594 // 26.2.3 complex specializations 595 // complex<float> specialization 596 template<> class complex<float> 597 { 598 public: 599 typedef float value_type; 600 601 complex(float = 0.0f, float = 0.0f); 602#ifdef _GLIBCPP_BUGGY_COMPLEX 603 complex(const complex& __z) : _M_value(__z._M_value) { } 604#endif 605 explicit complex(const complex<double>&); 606 explicit complex(const complex<long double>&); 607 608 float real() const; 609 float imag() const; 610 611 complex<float>& operator=(float); 612 complex<float>& operator+=(float); 613 complex<float>& operator-=(float); 614 complex<float>& operator*=(float); 615 complex<float>& operator/=(float); 616 617 // Let's the compiler synthetize the copy and assignment 618 // operator. It always does a pretty good job. 619 // complex& operator= (const complex&); 620 template<typename _Tp> 621 complex<float>&operator=(const complex<_Tp>&); 622 template<typename _Tp> 623 complex<float>& operator+=(const complex<_Tp>&); 624 template<class _Tp> 625 complex<float>& operator-=(const complex<_Tp>&); 626 template<class _Tp> 627 complex<float>& operator*=(const complex<_Tp>&); 628 template<class _Tp> 629 complex<float>&operator/=(const complex<_Tp>&); 630 631 private: 632 typedef __complex__ float _ComplexT; 633 _ComplexT _M_value; 634 635 complex(_ComplexT __z) : _M_value(__z) { } 636 637 friend class complex<double>; 638 friend class complex<long double>; 639 }; 640 641 inline float 642 complex<float>::real() const 643 { return __real__ _M_value; } 644 645 inline float 646 complex<float>::imag() const 647 { return __imag__ _M_value; } 648 649 inline 650 complex<float>::complex(float r, float i) 651 { 652 __real__ _M_value = r; 653 __imag__ _M_value = i; 654 } 655 656 inline complex<float>& 657 complex<float>::operator=(float __f) 658 { 659 __real__ _M_value = __f; 660 __imag__ _M_value = 0.0f; 661 return *this; 662 } 663 664 inline complex<float>& 665 complex<float>::operator+=(float __f) 666 { 667 __real__ _M_value += __f; 668 return *this; 669 } 670 671 inline complex<float>& 672 complex<float>::operator-=(float __f) 673 { 674 __real__ _M_value -= __f; 675 return *this; 676 } 677 678 inline complex<float>& 679 complex<float>::operator*=(float __f) 680 { 681 _M_value *= __f; 682 return *this; 683 } 684 685 inline complex<float>& 686 complex<float>::operator/=(float __f) 687 { 688 _M_value /= __f; 689 return *this; 690 } 691 692 template<typename _Tp> 693 inline complex<float>& 694 complex<float>::operator=(const complex<_Tp>& __z) 695 { 696 __real__ _M_value = __z.real(); 697 __imag__ _M_value = __z.imag(); 698 return *this; 699 } 700 701 template<typename _Tp> 702 inline complex<float>& 703 complex<float>::operator+=(const complex<_Tp>& __z) 704 { 705 __real__ _M_value += __z.real(); 706 __imag__ _M_value += __z.imag(); 707 return *this; 708 } 709 710 template<typename _Tp> 711 inline complex<float>& 712 complex<float>::operator-=(const complex<_Tp>& __z) 713 { 714 __real__ _M_value -= __z.real(); 715 __imag__ _M_value -= __z.imag(); 716 return *this; 717 } 718 719 template<typename _Tp> 720 inline complex<float>& 721 complex<float>::operator*=(const complex<_Tp>& __z) 722 { 723 _ComplexT __t; 724 __real__ __t = __z.real(); 725 __imag__ __t = __z.imag(); 726 _M_value *= __t; 727 return *this; 728 } 729 730 template<typename _Tp> 731 inline complex<float>& 732 complex<float>::operator/=(const complex<_Tp>& __z) 733 { 734 _ComplexT __t; 735 __real__ __t = __z.real(); 736 __imag__ __t = __z.imag(); 737 _M_value /= __t; 738 return *this; 739 } 740 741 // 26.2.3 complex specializations 742 // complex<double> specialization 743 template<> class complex<double> 744 { 745 public: 746 typedef double value_type; 747 748 complex(double =0.0, double =0.0); 749#ifdef _GLIBCPP_BUGGY_COMPLEX 750 complex(const complex& __z) : _M_value(__z._M_value) { } 751#endif 752 complex(const complex<float>&); 753 explicit complex(const complex<long double>&); 754 755 double real() const; 756 double imag() const; 757 758 complex<double>& operator=(double); 759 complex<double>& operator+=(double); 760 complex<double>& operator-=(double); 761 complex<double>& operator*=(double); 762 complex<double>& operator/=(double); 763 764 // The compiler will synthetize this, efficiently. 765 // complex& operator= (const complex&); 766 template<typename _Tp> 767 complex<double>& operator=(const complex<_Tp>&); 768 template<typename _Tp> 769 complex<double>& operator+=(const complex<_Tp>&); 770 template<typename _Tp> 771 complex<double>& operator-=(const complex<_Tp>&); 772 template<typename _Tp> 773 complex<double>& operator*=(const complex<_Tp>&); 774 template<typename _Tp> 775 complex<double>& operator/=(const complex<_Tp>&); 776 777 private: 778 typedef __complex__ double _ComplexT; 779 _ComplexT _M_value; 780 781 complex(_ComplexT __z) : _M_value(__z) { } 782 783 friend class complex<float>; 784 friend class complex<long double>; 785 }; 786 787 inline double 788 complex<double>::real() const 789 { return __real__ _M_value; } 790 791 inline double 792 complex<double>::imag() const 793 { return __imag__ _M_value; } 794 795 inline 796 complex<double>::complex(double __r, double __i) 797 { 798 __real__ _M_value = __r; 799 __imag__ _M_value = __i; 800 } 801 802 inline complex<double>& 803 complex<double>::operator=(double __d) 804 { 805 __real__ _M_value = __d; 806 __imag__ _M_value = 0.0; 807 return *this; 808 } 809 810 inline complex<double>& 811 complex<double>::operator+=(double __d) 812 { 813 __real__ _M_value += __d; 814 return *this; 815 } 816 817 inline complex<double>& 818 complex<double>::operator-=(double __d) 819 { 820 __real__ _M_value -= __d; 821 return *this; 822 } 823 824 inline complex<double>& 825 complex<double>::operator*=(double __d) 826 { 827 _M_value *= __d; 828 return *this; 829 } 830 831 inline complex<double>& 832 complex<double>::operator/=(double __d) 833 { 834 _M_value /= __d; 835 return *this; 836 } 837 838 template<typename _Tp> 839 inline complex<double>& 840 complex<double>::operator=(const complex<_Tp>& __z) 841 { 842 __real__ _M_value = __z.real(); 843 __imag__ _M_value = __z.imag(); 844 return *this; 845 } 846 847 template<typename _Tp> 848 inline complex<double>& 849 complex<double>::operator+=(const complex<_Tp>& __z) 850 { 851 __real__ _M_value += __z.real(); 852 __imag__ _M_value += __z.imag(); 853 return *this; 854 } 855 856 template<typename _Tp> 857 inline complex<double>& 858 complex<double>::operator-=(const complex<_Tp>& __z) 859 { 860 __real__ _M_value -= __z.real(); 861 __imag__ _M_value -= __z.imag(); 862 return *this; 863 } 864 865 template<typename _Tp> 866 inline complex<double>& 867 complex<double>::operator*=(const complex<_Tp>& __z) 868 { 869 _ComplexT __t; 870 __real__ __t = __z.real(); 871 __imag__ __t = __z.imag(); 872 _M_value *= __t; 873 return *this; 874 } 875 876 template<typename _Tp> 877 inline complex<double>& 878 complex<double>::operator/=(const complex<_Tp>& __z) 879 { 880 _ComplexT __t; 881 __real__ __t = __z.real(); 882 __imag__ __t = __z.imag(); 883 _M_value /= __t; 884 return *this; 885 } 886 887 // 26.2.3 complex specializations 888 // complex<long double> specialization 889 template<> class complex<long double> 890 { 891 public: 892 typedef long double value_type; 893 894 complex(long double = 0.0L, long double = 0.0L); 895#ifdef _GLIBCPP_BUGGY_COMPLEX 896 complex(const complex& __z) : _M_value(__z._M_value) { } 897#endif 898 complex(const complex<float>&); 899 complex(const complex<double>&); 900 901 long double real() const; 902 long double imag() const; 903 904 complex<long double>& operator= (long double); 905 complex<long double>& operator+= (long double); 906 complex<long double>& operator-= (long double); 907 complex<long double>& operator*= (long double); 908 complex<long double>& operator/= (long double); 909 910 // The compiler knows how to do this efficiently 911 // complex& operator= (const complex&); 912 template<typename _Tp> 913 complex<long double>& operator=(const complex<_Tp>&); 914 template<typename _Tp> 915 complex<long double>& operator+=(const complex<_Tp>&); 916 template<typename _Tp> 917 complex<long double>& operator-=(const complex<_Tp>&); 918 template<typename _Tp> 919 complex<long double>& operator*=(const complex<_Tp>&); 920 template<typename _Tp> 921 complex<long double>& operator/=(const complex<_Tp>&); 922 923 private: 924 typedef __complex__ long double _ComplexT; 925 _ComplexT _M_value; 926 927 complex(_ComplexT __z) : _M_value(__z) { } 928 929 friend class complex<float>; 930 friend class complex<double>; 931 }; 932 933 inline 934 complex<long double>::complex(long double __r, long double __i) 935 { 936 __real__ _M_value = __r; 937 __imag__ _M_value = __i; 938 } 939 940 inline long double 941 complex<long double>::real() const 942 { return __real__ _M_value; } 943 944 inline long double 945 complex<long double>::imag() const 946 { return __imag__ _M_value; } 947 948 inline complex<long double>& 949 complex<long double>::operator=(long double __r) 950 { 951 __real__ _M_value = __r; 952 __imag__ _M_value = 0.0L; 953 return *this; 954 } 955 956 inline complex<long double>& 957 complex<long double>::operator+=(long double __r) 958 { 959 __real__ _M_value += __r; 960 return *this; 961 } 962 963 inline complex<long double>& 964 complex<long double>::operator-=(long double __r) 965 { 966 __real__ _M_value -= __r; 967 return *this; 968 } 969 970 inline complex<long double>& 971 complex<long double>::operator*=(long double __r) 972 { 973 _M_value *= __r; 974 return *this; 975 } 976 977 inline complex<long double>& 978 complex<long double>::operator/=(long double __r) 979 { 980 _M_value /= __r; 981 return *this; 982 } 983 984 template<typename _Tp> 985 inline complex<long double>& 986 complex<long double>::operator=(const complex<_Tp>& __z) 987 { 988 __real__ _M_value = __z.real(); 989 __imag__ _M_value = __z.imag(); 990 return *this; 991 } 992 993 template<typename _Tp> 994 inline complex<long double>& 995 complex<long double>::operator+=(const complex<_Tp>& __z) 996 { 997 __real__ _M_value += __z.real(); 998 __imag__ _M_value += __z.imag(); 999 return *this; 1000 } 1001 1002 template<typename _Tp> 1003 inline complex<long double>& 1004 complex<long double>::operator-=(const complex<_Tp>& __z) 1005 { 1006 __real__ _M_value -= __z.real(); 1007 __imag__ _M_value -= __z.imag(); 1008 return *this; 1009 } 1010 1011 template<typename _Tp> 1012 inline complex<long double>& 1013 complex<long double>::operator*=(const complex<_Tp>& __z) 1014 { 1015 _ComplexT __t; 1016 __real__ __t = __z.real(); 1017 __imag__ __t = __z.imag(); 1018 _M_value *= __t; 1019 return *this; 1020 } 1021 1022 template<typename _Tp> 1023 inline complex<long double>& 1024 complex<long double>::operator/=(const complex<_Tp>& __z) 1025 { 1026 _ComplexT __t; 1027 __real__ __t = __z.real(); 1028 __imag__ __t = __z.imag(); 1029 _M_value /= __t; 1030 return *this; 1031 } 1032 1033 // These bits have to be at the end of this file, so that the 1034 // specializations have all been defined. 1035 // ??? No, they have to be there because of compiler limitation at 1036 // inlining. It suffices that class specializations be defined. 1037 inline 1038 complex<float>::complex(const complex<double>& __z) 1039 : _M_value(_ComplexT(__z._M_value)) { } 1040 1041 inline 1042 complex<float>::complex(const complex<long double>& __z) 1043 : _M_value(_ComplexT(__z._M_value)) { } 1044 1045 inline 1046 complex<double>::complex(const complex<float>& __z) 1047 : _M_value(_ComplexT(__z._M_value)) { } 1048 1049 inline 1050 complex<double>::complex(const complex<long double>& __z) 1051 { 1052 __real__ _M_value = __z.real(); 1053 __imag__ _M_value = __z.imag(); 1054 } 1055 1056 inline 1057 complex<long double>::complex(const complex<float>& __z) 1058 : _M_value(_ComplexT(__z._M_value)) { } 1059 1060 inline 1061 complex<long double>::complex(const complex<double>& __z) 1062 : _M_value(_ComplexT(__z._M_value)) { } 1063} // namespace std 1064 1065#endif /* _CPP_COMPLEX */ 1066