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 <[email protected]> 35 // Improved by Gabriel Dos Reis <[email protected]> 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 53 namespace 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>::_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 inline complex<_Tp> 569 pow(const complex<_Tp>& __x, const _Tp& __y) 570 { 571 return exp(__y * log(__x)); 572 } 573 574 template<typename _Tp> 575 inline complex<_Tp> 576 pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 577 { 578 return exp(__y * log(__x)); 579 } 580 581 template<typename _Tp> 582 inline complex<_Tp> 583 pow(const _Tp& __x, const complex<_Tp>& __y) 584 { 585 return exp(__y * log(__x)); 586 } 587 588 // 26.2.3 complex specializations 589 // complex<float> specialization 590 template<> class complex<float> 591 { 592 public: 593 typedef float value_type; 594 595 complex(float = 0.0f, float = 0.0f); 596 #ifdef _GLIBCPP_BUGGY_COMPLEX 597 complex(const complex& __z) : _M_value(__z._M_value) { } 598 #endif 599 explicit complex(const complex<double>&); 600 explicit complex(const complex<long double>&); 601 602 float real() const; 603 float imag() const; 604 605 complex<float>& operator=(float); 606 complex<float>& operator+=(float); 607 complex<float>& operator-=(float); 608 complex<float>& operator*=(float); 609 complex<float>& operator/=(float); 610 611 // Let's the compiler synthetize the copy and assignment 612 // operator. It always does a pretty good job. 613 // complex& operator= (const complex&); 614 template<typename _Tp> 615 complex<float>&operator=(const complex<_Tp>&); 616 template<typename _Tp> 617 complex<float>& operator+=(const complex<_Tp>&); 618 template<class _Tp> 619 complex<float>& operator-=(const complex<_Tp>&); 620 template<class _Tp> 621 complex<float>& operator*=(const complex<_Tp>&); 622 template<class _Tp> 623 complex<float>&operator/=(const complex<_Tp>&); 624 625 private: 626 typedef __complex__ float _ComplexT; 627 _ComplexT _M_value; 628 629 complex(_ComplexT __z) : _M_value(__z) { } 630 631 friend class complex<double>; 632 friend class complex<long double>; 633 }; 634 635 inline float 636 complex<float>::real() const 637 { return __real__ _M_value; } 638 639 inline float 640 complex<float>::imag() const 641 { return __imag__ _M_value; } 642 643 inline 644 complex<float>::complex(float r, float i) 645 { 646 __real__ _M_value = r; 647 __imag__ _M_value = i; 648 } 649 650 inline complex<float>& 651 complex<float>::operator=(float __f) 652 { 653 __real__ _M_value = __f; 654 __imag__ _M_value = 0.0f; 655 return *this; 656 } 657 658 inline complex<float>& 659 complex<float>::operator+=(float __f) 660 { 661 __real__ _M_value += __f; 662 return *this; 663 } 664 665 inline complex<float>& 666 complex<float>::operator-=(float __f) 667 { 668 __real__ _M_value -= __f; 669 return *this; 670 } 671 672 inline complex<float>& 673 complex<float>::operator*=(float __f) 674 { 675 _M_value *= __f; 676 return *this; 677 } 678 679 inline complex<float>& 680 complex<float>::operator/=(float __f) 681 { 682 _M_value /= __f; 683 return *this; 684 } 685 686 template<typename _Tp> 687 inline complex<float>& 688 complex<float>::operator=(const complex<_Tp>& __z) 689 { 690 __real__ _M_value = __z.real(); 691 __imag__ _M_value = __z.imag(); 692 return *this; 693 } 694 695 template<typename _Tp> 696 inline complex<float>& 697 complex<float>::operator+=(const complex<_Tp>& __z) 698 { 699 __real__ _M_value += __z.real(); 700 __imag__ _M_value += __z.imag(); 701 return *this; 702 } 703 704 template<typename _Tp> 705 inline complex<float>& 706 complex<float>::operator-=(const complex<_Tp>& __z) 707 { 708 __real__ _M_value -= __z.real(); 709 __imag__ _M_value -= __z.imag(); 710 return *this; 711 } 712 713 template<typename _Tp> 714 inline complex<float>& 715 complex<float>::operator*=(const complex<_Tp>& __z) 716 { 717 _ComplexT __t; 718 __real__ __t = __z.real(); 719 __imag__ __t = __z.imag(); 720 _M_value *= __t; 721 return *this; 722 } 723 724 template<typename _Tp> 725 inline complex<float>& 726 complex<float>::operator/=(const complex<_Tp>& __z) 727 { 728 _ComplexT __t; 729 __real__ __t = __z.real(); 730 __imag__ __t = __z.imag(); 731 _M_value /= __t; 732 return *this; 733 } 734 735 // 26.2.3 complex specializations 736 // complex<double> specialization 737 template<> class complex<double> 738 { 739 public: 740 typedef double value_type; 741 742 complex(double =0.0, double =0.0); 743 #ifdef _GLIBCPP_BUGGY_COMPLEX 744 complex(const complex& __z) : _M_value(__z._M_value) { } 745 #endif 746 complex(const complex<float>&); 747 explicit complex(const complex<long double>&); 748 749 double real() const; 750 double imag() const; 751 752 complex<double>& operator=(double); 753 complex<double>& operator+=(double); 754 complex<double>& operator-=(double); 755 complex<double>& operator*=(double); 756 complex<double>& operator/=(double); 757 758 // The compiler will synthetize this, efficiently. 759 // complex& operator= (const complex&); 760 template<typename _Tp> 761 complex<double>& operator=(const complex<_Tp>&); 762 template<typename _Tp> 763 complex<double>& operator+=(const complex<_Tp>&); 764 template<typename _Tp> 765 complex<double>& operator-=(const complex<_Tp>&); 766 template<typename _Tp> 767 complex<double>& operator*=(const complex<_Tp>&); 768 template<typename _Tp> 769 complex<double>& operator/=(const complex<_Tp>&); 770 771 private: 772 typedef __complex__ double _ComplexT; 773 _ComplexT _M_value; 774 775 complex(_ComplexT __z) : _M_value(__z) { } 776 777 friend class complex<float>; 778 friend class complex<long double>; 779 }; 780 781 inline double 782 complex<double>::real() const 783 { return __real__ _M_value; } 784 785 inline double 786 complex<double>::imag() const 787 { return __imag__ _M_value; } 788 789 inline 790 complex<double>::complex(double __r, double __i) 791 { 792 __real__ _M_value = __r; 793 __imag__ _M_value = __i; 794 } 795 796 inline complex<double>& 797 complex<double>::operator=(double __d) 798 { 799 __real__ _M_value = __d; 800 __imag__ _M_value = 0.0; 801 return *this; 802 } 803 804 inline complex<double>& 805 complex<double>::operator+=(double __d) 806 { 807 __real__ _M_value += __d; 808 return *this; 809 } 810 811 inline complex<double>& 812 complex<double>::operator-=(double __d) 813 { 814 __real__ _M_value -= __d; 815 return *this; 816 } 817 818 inline complex<double>& 819 complex<double>::operator*=(double __d) 820 { 821 _M_value *= __d; 822 return *this; 823 } 824 825 inline complex<double>& 826 complex<double>::operator/=(double __d) 827 { 828 _M_value /= __d; 829 return *this; 830 } 831 832 template<typename _Tp> 833 inline complex<double>& 834 complex<double>::operator=(const complex<_Tp>& __z) 835 { 836 __real__ _M_value = __z.real(); 837 __imag__ _M_value = __z.imag(); 838 return *this; 839 } 840 841 template<typename _Tp> 842 inline complex<double>& 843 complex<double>::operator+=(const complex<_Tp>& __z) 844 { 845 __real__ _M_value += __z.real(); 846 __imag__ _M_value += __z.imag(); 847 return *this; 848 } 849 850 template<typename _Tp> 851 inline complex<double>& 852 complex<double>::operator-=(const complex<_Tp>& __z) 853 { 854 __real__ _M_value -= __z.real(); 855 __imag__ _M_value -= __z.imag(); 856 return *this; 857 } 858 859 template<typename _Tp> 860 inline complex<double>& 861 complex<double>::operator*=(const complex<_Tp>& __z) 862 { 863 _ComplexT __t; 864 __real__ __t = __z.real(); 865 __imag__ __t = __z.imag(); 866 _M_value *= __t; 867 return *this; 868 } 869 870 template<typename _Tp> 871 inline complex<double>& 872 complex<double>::operator/=(const complex<_Tp>& __z) 873 { 874 _ComplexT __t; 875 __real__ __t = __z.real(); 876 __imag__ __t = __z.imag(); 877 _M_value /= __t; 878 return *this; 879 } 880 881 // 26.2.3 complex specializations 882 // complex<long double> specialization 883 template<> class complex<long double> 884 { 885 public: 886 typedef long double value_type; 887 888 complex(long double = 0.0L, long double = 0.0L); 889 #ifdef _GLIBCPP_BUGGY_COMPLEX 890 complex(const complex& __z) : _M_value(__z._M_value) { } 891 #endif 892 complex(const complex<float>&); 893 complex(const complex<double>&); 894 895 long double real() const; 896 long double imag() const; 897 898 complex<long double>& operator= (long double); 899 complex<long double>& operator+= (long double); 900 complex<long double>& operator-= (long double); 901 complex<long double>& operator*= (long double); 902 complex<long double>& operator/= (long double); 903 904 // The compiler knows how to do this efficiently 905 // complex& operator= (const complex&); 906 template<typename _Tp> 907 complex<long double>& operator=(const complex<_Tp>&); 908 template<typename _Tp> 909 complex<long double>& operator+=(const complex<_Tp>&); 910 template<typename _Tp> 911 complex<long double>& operator-=(const complex<_Tp>&); 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 917 private: 918 typedef __complex__ long double _ComplexT; 919 _ComplexT _M_value; 920 921 complex(_ComplexT __z) : _M_value(__z) { } 922 923 friend class complex<float>; 924 friend class complex<double>; 925 }; 926 927 inline 928 complex<long double>::complex(long double __r, long double __i) 929 { 930 __real__ _M_value = __r; 931 __imag__ _M_value = __i; 932 } 933 934 inline long double 935 complex<long double>::real() const 936 { return __real__ _M_value; } 937 938 inline long double 939 complex<long double>::imag() const 940 { return __imag__ _M_value; } 941 942 inline complex<long double>& 943 complex<long double>::operator=(long double __r) 944 { 945 __real__ _M_value = __r; 946 __imag__ _M_value = 0.0L; 947 return *this; 948 } 949 950 inline complex<long double>& 951 complex<long double>::operator+=(long double __r) 952 { 953 __real__ _M_value += __r; 954 return *this; 955 } 956 957 inline complex<long double>& 958 complex<long double>::operator-=(long double __r) 959 { 960 __real__ _M_value -= __r; 961 return *this; 962 } 963 964 inline complex<long double>& 965 complex<long double>::operator*=(long double __r) 966 { 967 _M_value *= __r; 968 return *this; 969 } 970 971 inline complex<long double>& 972 complex<long double>::operator/=(long double __r) 973 { 974 _M_value /= __r; 975 return *this; 976 } 977 978 template<typename _Tp> 979 inline complex<long double>& 980 complex<long double>::operator=(const complex<_Tp>& __z) 981 { 982 __real__ _M_value = __z.real(); 983 __imag__ _M_value = __z.imag(); 984 return *this; 985 } 986 987 template<typename _Tp> 988 inline complex<long double>& 989 complex<long double>::operator+=(const complex<_Tp>& __z) 990 { 991 __real__ _M_value += __z.real(); 992 __imag__ _M_value += __z.imag(); 993 return *this; 994 } 995 996 template<typename _Tp> 997 inline complex<long double>& 998 complex<long double>::operator-=(const complex<_Tp>& __z) 999 { 1000 __real__ _M_value -= __z.real(); 1001 __imag__ _M_value -= __z.imag(); 1002 return *this; 1003 } 1004 1005 template<typename _Tp> 1006 inline complex<long double>& 1007 complex<long double>::operator*=(const complex<_Tp>& __z) 1008 { 1009 _ComplexT __t; 1010 __real__ __t = __z.real(); 1011 __imag__ __t = __z.imag(); 1012 _M_value *= __t; 1013 return *this; 1014 } 1015 1016 template<typename _Tp> 1017 inline complex<long double>& 1018 complex<long double>::operator/=(const complex<_Tp>& __z) 1019 { 1020 _ComplexT __t; 1021 __real__ __t = __z.real(); 1022 __imag__ __t = __z.imag(); 1023 _M_value /= __t; 1024 return *this; 1025 } 1026 1027 // These bits have to be at the end of this file, so that the 1028 // specializations have all been defined. 1029 // ??? No, they have to be there because of compiler limitation at 1030 // inlining. It suffices that class specializations be defined. 1031 inline 1032 complex<float>::complex(const complex<double>& __z) 1033 : _M_value(_ComplexT(__z._M_value)) { } 1034 1035 inline 1036 complex<float>::complex(const complex<long double>& __z) 1037 : _M_value(_ComplexT(__z._M_value)) { } 1038 1039 inline 1040 complex<double>::complex(const complex<float>& __z) 1041 : _M_value(_ComplexT(__z._M_value)) { } 1042 1043 inline 1044 complex<double>::complex(const complex<long double>& __z) 1045 { 1046 __real__ _M_value = __z.real(); 1047 __imag__ _M_value = __z.imag(); 1048 } 1049 1050 inline 1051 complex<long double>::complex(const complex<float>& __z) 1052 : _M_value(_ComplexT(__z._M_value)) { } 1053 1054 inline 1055 complex<long double>::complex(const complex<double>& __z) 1056 : _M_value(_ComplexT(__z._M_value)) { } 1057 } // namespace std 1058 1059 #endif /* _CPP_COMPLEX */ 1060