complex

Go to the documentation of this file.
00001 // The template and inlines for the -*- C++ -*- complex number classes.
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 //
00032 // ISO C++ 14882: 26.2  Complex Numbers
00033 // Note: this is not a conforming implementation.
00034 // Initially implemented by Ulrich Drepper <drepper@cygnus.com>
00035 // Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
00036 //
00037 
00043 #ifndef _GLIBCXX_COMPLEX
00044 #define _GLIBCXX_COMPLEX 1
00045 
00046 #pragma GCC system_header
00047 
00048 #include <bits/c++config.h>
00049 #include <bits/cpp_type_traits.h>
00050 #include <cmath>
00051 #include <sstream>
00052 
00053 namespace std
00054 {
00055   // Forward declarations
00056   template<typename _Tp> class complex;
00057   template<> class complex<float>;
00058   template<> class complex<double>;
00059   template<> class complex<long double>;
00060 
00062   template<typename _Tp> _Tp abs(const complex<_Tp>&);
00064   template<typename _Tp> _Tp arg(const complex<_Tp>&);
00066   template<typename _Tp> _Tp norm(const complex<_Tp>&);
00067 
00069   template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&);
00071   template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
00072 
00073   // Transcendentals:
00075   template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&);
00077   template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&);
00079   template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&);
00081   template<typename _Tp> complex<_Tp> log(const complex<_Tp>&);
00083   template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&);
00085   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int);
00087   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&);
00089   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 
00090                        const complex<_Tp>&);
00092   template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&);
00094   template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&);
00096   template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&);
00098   template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&);
00100   template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&);
00102   template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&);
00104     
00105     
00106   // 26.2.2  Primary template class complex
00115   template<typename _Tp>
00116     class complex
00117     {
00118     public:
00120       typedef _Tp value_type;
00121       
00124       complex(const _Tp& = _Tp(), const _Tp & = _Tp());
00125 
00126       // Lets the compiler synthesize the copy constructor   
00127       // complex (const complex<_Tp>&);
00129       template<typename _Up>
00130         complex(const complex<_Up>&);
00131 
00133       _Tp& real(); 
00135       const _Tp& real() const;
00137       _Tp& imag();
00139       const _Tp& imag() const;
00140 
00142       complex<_Tp>& operator=(const _Tp&);
00144       complex<_Tp>& operator+=(const _Tp&);
00146       complex<_Tp>& operator-=(const _Tp&);
00148       complex<_Tp>& operator*=(const _Tp&);
00150       complex<_Tp>& operator/=(const _Tp&);
00151 
00152       // Lets the compiler synthesize the
00153       // copy and assignment operator
00154       // complex<_Tp>& operator= (const complex<_Tp>&);
00156       template<typename _Up>
00157         complex<_Tp>& operator=(const complex<_Up>&);
00159       template<typename _Up>
00160         complex<_Tp>& operator+=(const complex<_Up>&);
00162       template<typename _Up>
00163         complex<_Tp>& operator-=(const complex<_Up>&);
00165       template<typename _Up>
00166         complex<_Tp>& operator*=(const complex<_Up>&);
00168       template<typename _Up>
00169         complex<_Tp>& operator/=(const complex<_Up>&);
00170 
00171     private:
00172       _Tp _M_real;
00173       _Tp _M_imag;
00174     };
00175 
00176   template<typename _Tp>
00177     inline _Tp&
00178     complex<_Tp>::real() { return _M_real; }
00179 
00180   template<typename _Tp>
00181     inline const _Tp&
00182     complex<_Tp>::real() const { return _M_real; }
00183 
00184   template<typename _Tp>
00185     inline _Tp&
00186     complex<_Tp>::imag() { return _M_imag; }
00187 
00188   template<typename _Tp>
00189     inline const _Tp&
00190     complex<_Tp>::imag() const { return _M_imag; }
00191 
00192   template<typename _Tp>
00193     inline 
00194     complex<_Tp>::complex(const _Tp& __r, const _Tp& __i)
00195     : _M_real(__r), _M_imag(__i) { }
00196 
00197   template<typename _Tp>
00198     template<typename _Up>
00199     inline 
00200     complex<_Tp>::complex(const complex<_Up>& __z)
00201     : _M_real(__z.real()), _M_imag(__z.imag()) { }
00202         
00203   template<typename _Tp>
00204     complex<_Tp>&
00205     complex<_Tp>::operator=(const _Tp& __t)
00206     {
00207      _M_real = __t;
00208      _M_imag = _Tp();
00209      return *this;
00210     } 
00211 
00212   // 26.2.5/1
00213   template<typename _Tp>
00214     inline complex<_Tp>&
00215     complex<_Tp>::operator+=(const _Tp& __t)
00216     {
00217       _M_real += __t;
00218       return *this;
00219     }
00220 
00221   // 26.2.5/3
00222   template<typename _Tp>
00223     inline complex<_Tp>&
00224     complex<_Tp>::operator-=(const _Tp& __t)
00225     {
00226       _M_real -= __t;
00227       return *this;
00228     }
00229 
00230   // 26.2.5/5
00231   template<typename _Tp>
00232     complex<_Tp>&
00233     complex<_Tp>::operator*=(const _Tp& __t)
00234     {
00235       _M_real *= __t;
00236       _M_imag *= __t;
00237       return *this;
00238     }
00239 
00240   // 26.2.5/7
00241   template<typename _Tp>
00242     complex<_Tp>&
00243     complex<_Tp>::operator/=(const _Tp& __t)
00244     {
00245       _M_real /= __t;
00246       _M_imag /= __t;
00247       return *this;
00248     }
00249 
00250   template<typename _Tp>
00251     template<typename _Up>
00252     complex<_Tp>&
00253     complex<_Tp>::operator=(const complex<_Up>& __z)
00254     {
00255       _M_real = __z.real();
00256       _M_imag = __z.imag();
00257       return *this;
00258     }
00259 
00260   // 26.2.5/9
00261   template<typename _Tp>
00262     template<typename _Up>
00263     complex<_Tp>&
00264     complex<_Tp>::operator+=(const complex<_Up>& __z)
00265     {
00266       _M_real += __z.real();
00267       _M_imag += __z.imag();
00268       return *this;
00269     }
00270 
00271   // 26.2.5/11
00272   template<typename _Tp>
00273     template<typename _Up>
00274     complex<_Tp>&
00275     complex<_Tp>::operator-=(const complex<_Up>& __z)
00276     {
00277       _M_real -= __z.real();
00278       _M_imag -= __z.imag();
00279       return *this;
00280     }
00281 
00282   // 26.2.5/13
00283   // XXX: This is a grammar school implementation.
00284   template<typename _Tp>
00285     template<typename _Up>
00286     complex<_Tp>&
00287     complex<_Tp>::operator*=(const complex<_Up>& __z)
00288     {
00289       const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
00290       _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
00291       _M_real = __r;
00292       return *this;
00293     }
00294 
00295   // 26.2.5/15
00296   // XXX: This is a grammar school implementation.
00297   template<typename _Tp>
00298     template<typename _Up>
00299     complex<_Tp>&
00300     complex<_Tp>::operator/=(const complex<_Up>& __z)
00301     {
00302       const _Tp __r =  _M_real * __z.real() + _M_imag * __z.imag();
00303       const _Tp __n = std::norm(__z);
00304       _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n;
00305       _M_real = __r / __n;
00306       return *this;
00307     }
00308     
00309   // Operators:
00311 
00312   template<typename _Tp>
00313     inline complex<_Tp>
00314     operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
00315     {
00316       complex<_Tp> __r = __x;
00317       __r += __y;
00318       return __r;
00319     }
00320 
00321   template<typename _Tp>
00322     inline complex<_Tp>
00323     operator+(const complex<_Tp>& __x, const _Tp& __y)
00324     {
00325       complex<_Tp> __r = __x;
00326       __r.real() += __y;
00327       return __r;
00328     }
00329 
00330   template<typename _Tp>
00331     inline complex<_Tp>
00332     operator+(const _Tp& __x, const complex<_Tp>& __y)
00333     {
00334       complex<_Tp> __r = __y;
00335       __r.real() += __x;
00336       return __r;
00337     }
00339 
00341 
00342   template<typename _Tp>
00343     inline complex<_Tp>
00344     operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
00345     {
00346       complex<_Tp> __r = __x;
00347       __r -= __y;
00348       return __r;
00349     }
00350     
00351   template<typename _Tp>
00352     inline complex<_Tp>
00353     operator-(const complex<_Tp>& __x, const _Tp& __y)
00354     {
00355       complex<_Tp> __r = __x;
00356       __r.real() -= __y;
00357       return __r;
00358     }
00359 
00360   template<typename _Tp>
00361     inline complex<_Tp>
00362     operator-(const _Tp& __x, const complex<_Tp>& __y)
00363     {
00364       complex<_Tp> __r(__x, -__y.imag());
00365       __r.real() -= __y.real();
00366       return __r;
00367     }
00369 
00371 
00372   template<typename _Tp>
00373     inline complex<_Tp>
00374     operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
00375     {
00376       complex<_Tp> __r = __x;
00377       __r *= __y;
00378       return __r;
00379     }
00380 
00381   template<typename _Tp>
00382     inline complex<_Tp>
00383     operator*(const complex<_Tp>& __x, const _Tp& __y)
00384     {
00385       complex<_Tp> __r = __x;
00386       __r *= __y;
00387       return __r;
00388     }
00389 
00390   template<typename _Tp>
00391     inline complex<_Tp>
00392     operator*(const _Tp& __x, const complex<_Tp>& __y)
00393     {
00394       complex<_Tp> __r = __y;
00395       __r *= __x;
00396       return __r;
00397     }
00399 
00401 
00402   template<typename _Tp>
00403     inline complex<_Tp>
00404     operator/(const complex<_Tp>& __x, const complex<_Tp>& __y)
00405     {
00406       complex<_Tp> __r = __x;
00407       __r /= __y;
00408       return __r;
00409     }
00410     
00411   template<typename _Tp>
00412     inline complex<_Tp>
00413     operator/(const complex<_Tp>& __x, const _Tp& __y)
00414     {
00415       complex<_Tp> __r = __x;
00416       __r /= __y;
00417       return __r;
00418     }
00419 
00420   template<typename _Tp>
00421     inline complex<_Tp>
00422     operator/(const _Tp& __x, const complex<_Tp>& __y)
00423     {
00424       complex<_Tp> __r = __x;
00425       __r /= __y;
00426       return __r;
00427     }
00429 
00431   template<typename _Tp>
00432     inline complex<_Tp>
00433     operator+(const complex<_Tp>& __x)
00434     { return __x; }
00435 
00437   template<typename _Tp>
00438     inline complex<_Tp>
00439     operator-(const complex<_Tp>& __x)
00440     {  return complex<_Tp>(-__x.real(), -__x.imag()); }
00441 
00443 
00444   template<typename _Tp>
00445     inline bool
00446     operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
00447     { return __x.real() == __y.real() && __x.imag() == __y.imag(); }
00448 
00449   template<typename _Tp>
00450     inline bool
00451     operator==(const complex<_Tp>& __x, const _Tp& __y)
00452     { return __x.real() == __y && __x.imag() == _Tp(); }
00453 
00454   template<typename _Tp>
00455     inline bool
00456     operator==(const _Tp& __x, const complex<_Tp>& __y)
00457     { return __x == __y.real() && _Tp() == __y.imag(); }
00459 
00461 
00462   template<typename _Tp>
00463     inline bool
00464     operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
00465     { return __x.real() != __y.real() || __x.imag() != __y.imag(); }
00466 
00467   template<typename _Tp>
00468     inline bool
00469     operator!=(const complex<_Tp>& __x, const _Tp& __y)
00470     { return __x.real() != __y || __x.imag() != _Tp(); }
00471 
00472   template<typename _Tp>
00473     inline bool
00474     operator!=(const _Tp& __x, const complex<_Tp>& __y)
00475     { return __x != __y.real() || _Tp() != __y.imag(); }
00477 
00479   template<typename _Tp, typename _CharT, class _Traits>
00480     basic_istream<_CharT, _Traits>&
00481     operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
00482     {
00483       _Tp __re_x, __im_x;
00484       _CharT __ch;
00485       __is >> __ch;
00486       if (__ch == '(') 
00487     {
00488       __is >> __re_x >> __ch;
00489       if (__ch == ',') 
00490         {
00491           __is >> __im_x >> __ch;
00492           if (__ch == ')') 
00493         __x = complex<_Tp>(__re_x, __im_x);
00494           else
00495         __is.setstate(ios_base::failbit);
00496         }
00497       else if (__ch == ')') 
00498         __x = __re_x;
00499       else
00500         __is.setstate(ios_base::failbit);
00501     }
00502       else 
00503     {
00504       __is.putback(__ch);
00505       __is >> __re_x;
00506       __x = __re_x;
00507     }
00508       return __is;
00509     }
00510 
00512   template<typename _Tp, typename _CharT, class _Traits>
00513     basic_ostream<_CharT, _Traits>&
00514     operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
00515     {
00516       basic_ostringstream<_CharT, _Traits> __s;
00517       __s.flags(__os.flags());
00518       __s.imbue(__os.getloc());
00519       __s.precision(__os.precision());
00520       __s << '(' << __x.real() << ',' << __x.imag() << ')';
00521       return __os << __s.str();
00522     }
00523 
00524   // Values
00525   template<typename _Tp>
00526     inline _Tp&
00527     real(complex<_Tp>& __z)
00528     { return __z.real(); }
00529     
00530   template<typename _Tp>
00531     inline const _Tp&
00532     real(const complex<_Tp>& __z)
00533     { return __z.real(); }
00534     
00535   template<typename _Tp>
00536     inline _Tp&
00537     imag(complex<_Tp>& __z)
00538     { return __z.imag(); }
00539     
00540   template<typename _Tp>
00541     inline const _Tp&
00542     imag(const complex<_Tp>& __z)
00543     { return __z.imag(); }
00544 
00545   template<typename _Tp>
00546     inline _Tp
00547     abs(const complex<_Tp>& __z)
00548     {
00549       _Tp __x = __z.real();
00550       _Tp __y = __z.imag();
00551       const _Tp __s = std::max(abs(__x), abs(__y));
00552       if (__s == _Tp())  // well ...
00553         return __s;
00554       __x /= __s; 
00555       __y /= __s;
00556       return __s * sqrt(__x * __x + __y * __y);
00557     }
00558 
00559   template<typename _Tp>
00560     inline _Tp
00561     arg(const complex<_Tp>& __z)
00562     { return atan2(__z.imag(), __z.real()); }
00563 
00564   // 26.2.7/5: norm(__z) returns the squared magintude of __z.
00565   //     As defined, norm() is -not- a norm is the common mathematical
00566   //     sens used in numerics.  The helper class _Norm_helper<> tries to
00567   //     distinguish between builtin floating point and the rest, so as
00568   //     to deliver an answer as close as possible to the real value.
00569   template<bool>
00570     struct _Norm_helper
00571     {
00572       template<typename _Tp>
00573         static inline _Tp _S_do_it(const complex<_Tp>& __z)
00574         {
00575           const _Tp __x = __z.real();
00576           const _Tp __y = __z.imag();
00577           return __x * __x + __y * __y;
00578         }
00579     };
00580 
00581   template<>
00582     struct _Norm_helper<true>
00583     {
00584       template<typename _Tp>
00585         static inline _Tp _S_do_it(const complex<_Tp>& __z)
00586         {
00587           _Tp __res = std::abs(__z);
00588           return __res * __res;
00589         }
00590     };
00591   
00592   template<typename _Tp>
00593     inline _Tp
00594     norm(const complex<_Tp>& __z)
00595     {
00596       return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCXX_FAST_MATH>::_S_do_it(__z);
00597     }
00598 
00599   template<typename _Tp>
00600     inline complex<_Tp>
00601     polar(const _Tp& __rho, const _Tp& __theta)
00602     { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); }
00603 
00604   template<typename _Tp>
00605     inline complex<_Tp>
00606     conj(const complex<_Tp>& __z)
00607     { return complex<_Tp>(__z.real(), -__z.imag()); }
00608   
00609   // Transcendentals
00610   template<typename _Tp>
00611     inline complex<_Tp>
00612     cos(const complex<_Tp>& __z)
00613     {
00614       const _Tp __x = __z.real();
00615       const _Tp __y = __z.imag();
00616       return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y));
00617     }
00618 
00619   template<typename _Tp>
00620     inline complex<_Tp>
00621     cosh(const complex<_Tp>& __z)
00622     {
00623       const _Tp __x = __z.real();
00624       const _Tp __y = __z.imag();
00625       return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y));
00626     }
00627 
00628   template<typename _Tp>
00629     inline complex<_Tp>
00630     exp(const complex<_Tp>& __z)
00631     { return std::polar(exp(__z.real()), __z.imag()); }
00632 
00633   template<typename _Tp>
00634     inline complex<_Tp>
00635     log(const complex<_Tp>& __z)
00636     { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); }
00637 
00638   template<typename _Tp>
00639     inline complex<_Tp>
00640     log10(const complex<_Tp>& __z)
00641     { return std::log(__z) / log(_Tp(10.0)); }
00642 
00643   template<typename _Tp>
00644     inline complex<_Tp>
00645     sin(const complex<_Tp>& __z)
00646     {
00647       const _Tp __x = __z.real();
00648       const _Tp __y = __z.imag();
00649       return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 
00650     }
00651 
00652   template<typename _Tp>
00653     inline complex<_Tp>
00654     sinh(const complex<_Tp>& __z)
00655     {
00656       const _Tp __x = __z.real();
00657       const _Tp  __y = __z.imag();
00658       return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y));
00659     }
00660 
00661   template<typename _Tp>
00662     complex<_Tp>
00663     sqrt(const complex<_Tp>& __z)
00664     {
00665       _Tp __x = __z.real();
00666       _Tp __y = __z.imag();
00667 
00668       if (__x == _Tp())
00669         {
00670           _Tp __t = sqrt(abs(__y) / 2);
00671           return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
00672         }
00673       else
00674         {
00675           _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x)));
00676           _Tp __u = __t / 2;
00677           return __x > _Tp()
00678             ? complex<_Tp>(__u, __y / __t)
00679             : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
00680         }
00681     }
00682 
00683   template<typename _Tp>
00684     inline complex<_Tp>
00685     tan(const complex<_Tp>& __z)
00686     {
00687       return std::sin(__z) / std::cos(__z);
00688     }
00689 
00690   template<typename _Tp>
00691     inline complex<_Tp>
00692     tanh(const complex<_Tp>& __z)
00693     {
00694       return std::sinh(__z) / std::cosh(__z);
00695     }
00696 
00697   template<typename _Tp>
00698     inline complex<_Tp>
00699     pow(const complex<_Tp>& __z, int __n)
00700     {
00701       return std::__pow_helper(__z, __n);
00702     }
00703 
00704   template<typename _Tp>
00705     complex<_Tp>
00706     pow(const complex<_Tp>& __x, const _Tp& __y)
00707     {
00708       if (__x.imag() == _Tp() && __x.real() > _Tp())
00709         return pow(__x.real(), __y);
00710 
00711       complex<_Tp> __t = std::log(__x);
00712       return std::polar(exp(__y * __t.real()), __y * __t.imag());
00713     }
00714 
00715   template<typename _Tp>
00716     inline complex<_Tp>
00717     pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
00718     {
00719       return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x));
00720     }
00721 
00722   template<typename _Tp>
00723     inline complex<_Tp>
00724     pow(const _Tp& __x, const complex<_Tp>& __y)
00725     {
00726       return __x > _Tp() ? std::polar(pow(__x, __y.real()),
00727                       __y.imag() * log(__x))
00728                      : std::pow(complex<_Tp>(__x, _Tp()), __y);
00729     }
00730 
00731   // 26.2.3  complex specializations
00732   // complex<float> specialization
00733   template<> class complex<float>
00734   {
00735   public:
00736     typedef float value_type;
00737     
00738     complex(float = 0.0f, float = 0.0f);
00739 
00740     explicit complex(const complex<double>&);
00741     explicit complex(const complex<long double>&);
00742 
00743     float& real();
00744     const float& real() const;
00745     float& imag();
00746     const float& imag() const;
00747 
00748     complex<float>& operator=(float);
00749     complex<float>& operator+=(float);
00750     complex<float>& operator-=(float);
00751     complex<float>& operator*=(float);
00752     complex<float>& operator/=(float);
00753         
00754     // Let's the compiler synthetize the copy and assignment
00755     // operator.  It always does a pretty good job.
00756     // complex& operator= (const complex&);
00757     template<typename _Tp>
00758       complex<float>&operator=(const complex<_Tp>&);
00759     template<typename _Tp>
00760       complex<float>& operator+=(const complex<_Tp>&);
00761     template<class _Tp>
00762       complex<float>& operator-=(const complex<_Tp>&);
00763     template<class _Tp>
00764       complex<float>& operator*=(const complex<_Tp>&);
00765     template<class _Tp>
00766       complex<float>&operator/=(const complex<_Tp>&);
00767 
00768   private:
00769     typedef __complex__ float _ComplexT;
00770     _ComplexT _M_value;
00771 
00772     complex(_ComplexT __z) : _M_value(__z) { }
00773         
00774     friend class complex<double>;
00775     friend class complex<long double>;
00776   };
00777 
00778   inline float&
00779   complex<float>::real()
00780   { return __real__ _M_value; }
00781 
00782   inline const float&
00783   complex<float>::real() const
00784   { return __real__ _M_value; }
00785 
00786   inline float&
00787   complex<float>::imag()
00788   { return __imag__ _M_value; }
00789 
00790   inline const float&
00791   complex<float>::imag() const
00792   { return __imag__ _M_value; }
00793 
00794   inline
00795   complex<float>::complex(float r, float i)
00796   {
00797     __real__ _M_value = r;
00798     __imag__ _M_value = i;
00799   }
00800 
00801   inline complex<float>&
00802   complex<float>::operator=(float __f)
00803   {
00804     __real__ _M_value = __f;
00805     __imag__ _M_value = 0.0f;
00806     return *this;
00807   }
00808 
00809   inline complex<float>&
00810   complex<float>::operator+=(float __f)
00811   {
00812     __real__ _M_value += __f;
00813     return *this;
00814   }
00815 
00816   inline complex<float>&
00817   complex<float>::operator-=(float __f)
00818   {
00819     __real__ _M_value -= __f;
00820     return *this;
00821   }
00822 
00823   inline complex<float>&
00824   complex<float>::operator*=(float __f)
00825   {
00826     _M_value *= __f;
00827     return *this;
00828   }
00829 
00830   inline complex<float>&
00831   complex<float>::operator/=(float __f)
00832   {
00833     _M_value /= __f;
00834     return *this;
00835   }
00836 
00837   template<typename _Tp>
00838   inline complex<float>&
00839   complex<float>::operator=(const complex<_Tp>& __z)
00840   {
00841     __real__ _M_value = __z.real();
00842     __imag__ _M_value = __z.imag();
00843     return *this;
00844   }
00845 
00846   template<typename _Tp>
00847   inline complex<float>&
00848   complex<float>::operator+=(const complex<_Tp>& __z)
00849   {
00850     __real__ _M_value += __z.real();
00851     __imag__ _M_value += __z.imag();
00852     return *this;
00853   }
00854     
00855   template<typename _Tp>
00856     inline complex<float>&
00857     complex<float>::operator-=(const complex<_Tp>& __z)
00858     {
00859      __real__ _M_value -= __z.real();
00860      __imag__ _M_value -= __z.imag();
00861      return *this;
00862     } 
00863 
00864   template<typename _Tp>
00865     inline complex<float>&
00866     complex<float>::operator*=(const complex<_Tp>& __z)
00867     {
00868       _ComplexT __t;
00869       __real__ __t = __z.real();
00870       __imag__ __t = __z.imag();
00871       _M_value *= __t;
00872       return *this;
00873     }
00874 
00875   template<typename _Tp>
00876     inline complex<float>&
00877     complex<float>::operator/=(const complex<_Tp>& __z)
00878     {
00879       _ComplexT __t;
00880       __real__ __t = __z.real();
00881       __imag__ __t = __z.imag();
00882       _M_value /= __t;
00883       return *this;
00884     }
00885 
00886   // 26.2.3  complex specializations
00887   // complex<double> specialization
00888   template<> class complex<double>
00889   {
00890   public:
00891     typedef double value_type;
00892 
00893     complex(double = 0.0, double = 0.0);
00894 
00895     complex(const complex<float>&);
00896     explicit complex(const complex<long double>&);
00897 
00898     double& real();
00899     const double& real() const;
00900     double& imag();
00901     const double& imag() const;
00902         
00903     complex<double>& operator=(double);
00904     complex<double>& operator+=(double);
00905     complex<double>& operator-=(double);
00906     complex<double>& operator*=(double);
00907     complex<double>& operator/=(double);
00908 
00909     // The compiler will synthetize this, efficiently.
00910     // complex& operator= (const complex&);
00911     template<typename _Tp>
00912       complex<double>& operator=(const complex<_Tp>&);
00913     template<typename _Tp>
00914       complex<double>& operator+=(const complex<_Tp>&);
00915     template<typename _Tp>
00916       complex<double>& operator-=(const complex<_Tp>&);
00917     template<typename _Tp>
00918       complex<double>& operator*=(const complex<_Tp>&);
00919     template<typename _Tp>
00920       complex<double>& operator/=(const complex<_Tp>&);
00921 
00922   private:
00923     typedef __complex__ double _ComplexT;
00924     _ComplexT _M_value;
00925 
00926     complex(_ComplexT __z) : _M_value(__z) { }
00927         
00928     friend class complex<float>;
00929     friend class complex<long double>;
00930   };
00931 
00932   inline double&
00933   complex<double>::real()
00934   { return __real__ _M_value; }
00935 
00936   inline const double&
00937   complex<double>::real() const
00938   { return __real__ _M_value; }
00939 
00940   inline double&
00941   complex<double>::imag()
00942   { return __imag__ _M_value; }
00943 
00944   inline const double&
00945   complex<double>::imag() const
00946   { return __imag__ _M_value; }
00947 
00948   inline
00949   complex<double>::complex(double __r, double __i)
00950   {
00951     __real__ _M_value = __r;
00952     __imag__ _M_value = __i;
00953   }
00954 
00955   inline complex<double>&
00956   complex<double>::operator=(double __d)
00957   {
00958     __real__ _M_value = __d;
00959     __imag__ _M_value = 0.0;
00960     return *this;
00961   }
00962 
00963   inline complex<double>&
00964   complex<double>::operator+=(double __d)
00965   {
00966     __real__ _M_value += __d;
00967     return *this;
00968   }
00969 
00970   inline complex<double>&
00971   complex<double>::operator-=(double __d)
00972   {
00973     __real__ _M_value -= __d;
00974     return *this;
00975   }
00976 
00977   inline complex<double>&
00978   complex<double>::operator*=(double __d)
00979   {
00980     _M_value *= __d;
00981     return *this;
00982   }
00983 
00984   inline complex<double>&
00985   complex<double>::operator/=(double __d)
00986   {
00987     _M_value /= __d;
00988     return *this;
00989   }
00990 
00991   template<typename _Tp>
00992     inline complex<double>&
00993     complex<double>::operator=(const complex<_Tp>& __z)
00994     {
00995       __real__ _M_value = __z.real();
00996       __imag__ _M_value = __z.imag();
00997       return *this;
00998     }
00999     
01000   template<typename _Tp>
01001     inline complex<double>&
01002     complex<double>::operator+=(const complex<_Tp>& __z)
01003     {
01004       __real__ _M_value += __z.real();
01005       __imag__ _M_value += __z.imag();
01006       return *this;
01007     }
01008 
01009   template<typename _Tp>
01010     inline complex<double>&
01011     complex<double>::operator-=(const complex<_Tp>& __z)
01012     {
01013       __real__ _M_value -= __z.real();
01014       __imag__ _M_value -= __z.imag();
01015       return *this;
01016     }
01017 
01018   template<typename _Tp>
01019     inline complex<double>&
01020     complex<double>::operator*=(const complex<_Tp>& __z)
01021     {
01022       _ComplexT __t;
01023       __real__ __t = __z.real();
01024       __imag__ __t = __z.imag();
01025       _M_value *= __t;
01026       return *this;
01027     }
01028 
01029   template<typename _Tp>
01030     inline complex<double>&
01031     complex<double>::operator/=(const complex<_Tp>& __z)
01032     {
01033       _ComplexT __t;
01034       __real__ __t = __z.real();
01035       __imag__ __t = __z.imag();
01036       _M_value /= __t;
01037       return *this;
01038     }
01039 
01040   // 26.2.3  complex specializations
01041   // complex<long double> specialization
01042   template<> class complex<long double>
01043   {
01044   public:
01045     typedef long double value_type;
01046 
01047     complex(long double = 0.0L, long double = 0.0L);
01048 
01049     complex(const complex<float>&);
01050     complex(const complex<double>&);
01051 
01052     long double& real();
01053     const long double& real() const;
01054     long double& imag();
01055     const long double& imag() const;
01056 
01057     complex<long double>& operator= (long double);
01058     complex<long double>& operator+= (long double);
01059     complex<long double>& operator-= (long double);
01060     complex<long double>& operator*= (long double);
01061     complex<long double>& operator/= (long double);
01062 
01063     // The compiler knows how to do this efficiently
01064     // complex& operator= (const complex&);
01065     template<typename _Tp>
01066       complex<long double>& operator=(const complex<_Tp>&);
01067     template<typename _Tp>
01068       complex<long double>& operator+=(const complex<_Tp>&);
01069     template<typename _Tp>
01070       complex<long double>& operator-=(const complex<_Tp>&);
01071     template<typename _Tp>
01072       complex<long double>& operator*=(const complex<_Tp>&);
01073     template<typename _Tp>
01074       complex<long double>& operator/=(const complex<_Tp>&);
01075 
01076   private:
01077     typedef __complex__ long double _ComplexT;
01078     _ComplexT _M_value;
01079 
01080     complex(_ComplexT __z) : _M_value(__z) { }
01081 
01082     friend class complex<float>;
01083     friend class complex<double>;
01084   };
01085 
01086   inline
01087   complex<long double>::complex(long double __r, long double __i)
01088   {
01089     __real__ _M_value = __r;
01090     __imag__ _M_value = __i;
01091   }
01092 
01093   inline long double&
01094   complex<long double>::real()
01095   { return __real__ _M_value; }
01096 
01097   inline const long double&
01098   complex<long double>::real() const
01099   { return __real__ _M_value; }
01100 
01101   inline long double&
01102   complex<long double>::imag()
01103   { return __imag__ _M_value; }
01104 
01105   inline const long double&
01106   complex<long double>::imag() const
01107   { return __imag__ _M_value; }
01108 
01109   inline complex<long double>&   
01110   complex<long double>::operator=(long double __r)
01111   {
01112     __real__ _M_value = __r;
01113     __imag__ _M_value = 0.0L;
01114     return *this;
01115   }
01116 
01117   inline complex<long double>&
01118   complex<long double>::operator+=(long double __r)
01119   {
01120     __real__ _M_value += __r;
01121     return *this;
01122   }
01123 
01124   inline complex<long double>&
01125   complex<long double>::operator-=(long double __r)
01126   {
01127     __real__ _M_value -= __r;
01128     return *this;
01129   }
01130 
01131   inline complex<long double>&
01132   complex<long double>::operator*=(long double __r)
01133   {
01134     _M_value *= __r;
01135     return *this;
01136   }
01137 
01138   inline complex<long double>&
01139   complex<long double>::operator/=(long double __r)
01140   {
01141     _M_value /= __r;
01142     return *this;
01143   }
01144 
01145   template<typename _Tp>
01146     inline complex<long double>&
01147     complex<long double>::operator=(const complex<_Tp>& __z)
01148     {
01149       __real__ _M_value = __z.real();
01150       __imag__ _M_value = __z.imag();
01151       return *this;
01152     }
01153 
01154   template<typename _Tp>
01155     inline complex<long double>&
01156     complex<long double>::operator+=(const complex<_Tp>& __z)
01157     {
01158       __real__ _M_value += __z.real();
01159       __imag__ _M_value += __z.imag();
01160       return *this;
01161     }
01162 
01163   template<typename _Tp>
01164     inline complex<long double>&
01165     complex<long double>::operator-=(const complex<_Tp>& __z)
01166     {
01167       __real__ _M_value -= __z.real();
01168       __imag__ _M_value -= __z.imag();
01169       return *this;
01170     }
01171     
01172   template<typename _Tp>
01173     inline complex<long double>&
01174     complex<long double>::operator*=(const complex<_Tp>& __z)
01175     {
01176       _ComplexT __t;
01177       __real__ __t = __z.real();
01178       __imag__ __t = __z.imag();
01179       _M_value *= __t;
01180       return *this;
01181     }
01182 
01183   template<typename _Tp>
01184     inline complex<long double>&
01185     complex<long double>::operator/=(const complex<_Tp>& __z)
01186     {
01187       _ComplexT __t;
01188       __real__ __t = __z.real();
01189       __imag__ __t = __z.imag();
01190       _M_value /= __t;
01191       return *this;
01192     }
01193 
01194   // These bits have to be at the end of this file, so that the
01195   // specializations have all been defined.
01196   // ??? No, they have to be there because of compiler limitation at
01197   // inlining.  It suffices that class specializations be defined.
01198   inline
01199   complex<float>::complex(const complex<double>& __z)
01200   : _M_value(_ComplexT(__z._M_value)) { }
01201 
01202   inline
01203   complex<float>::complex(const complex<long double>& __z)
01204   : _M_value(_ComplexT(__z._M_value)) { }
01205 
01206   inline
01207   complex<double>::complex(const complex<float>& __z) 
01208   : _M_value(_ComplexT(__z._M_value)) { }
01209 
01210   inline
01211   complex<double>::complex(const complex<long double>& __z)
01212   {
01213     __real__ _M_value = __z.real();
01214     __imag__ _M_value = __z.imag();
01215   }
01216 
01217   inline
01218   complex<long double>::complex(const complex<float>& __z)
01219   : _M_value(_ComplexT(__z._M_value)) { }
01220 
01221   inline
01222   complex<long double>::complex(const complex<double>& __z)
01223   : _M_value(_ComplexT(__z._M_value)) { }
01224 } // namespace std
01225 
01226 #endif  /* _GLIBCXX_COMPLEX */

Generated on Tue Jan 30 17:31:48 2007 for GNU C++ STL by doxygen 1.3.6