Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

std_complex.h

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 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 //
00031 // ISO C++ 14882: 26.2  Complex Numbers
00032 // Note: this is not a conforming implementation.
00033 // Initially implemented by Ulrich Drepper <drepper@cygnus.com>
00034 // Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
00035 //
00036 
00037 #ifndef _CPP_COMPLEX
00038 #define _CPP_COMPLEX    1
00039 
00040 #pragma GCC system_header
00041 
00042 #include <bits/c++config.h>
00043 #include <bits/std_cmath.h>
00044 #include <bits/std_iosfwd.h>
00045 
00046 namespace std
00047 {
00048 
00049   // Forward declarations
00050   template<typename _Tp> class complex;
00051   template<> class complex<float>;
00052   template<> class complex<double>;
00053   template<> class complex<long double>;
00054 
00055   template<typename _Tp> _Tp abs(const complex<_Tp>&);
00056   template<typename _Tp> _Tp arg(const complex<_Tp>&);
00057   template<typename _Tp> _Tp norm(const complex<_Tp>&);
00058 
00059   template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&);
00060   template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp&);
00061 
00062   // Transcendentals:
00063   template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&);
00064   template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&);
00065   template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&);
00066   template<typename _Tp> complex<_Tp> log(const complex<_Tp>&);
00067   template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&);
00068   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int);
00069   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&);
00070   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 
00071                        const complex<_Tp>&);
00072   template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&);
00073   template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&);
00074   template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&);
00075   template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&);
00076   template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&);
00077   template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&);
00078     
00079     
00080   // 26.2.2  Primary template class complex
00081   template<typename _Tp>
00082     class complex
00083     {
00084     public:
00085       typedef _Tp value_type;
00086       
00087       complex(const _Tp& = _Tp(), const _Tp & = _Tp());
00088 
00089       // Let's the compiler synthetize the copy constructor   
00090       // complex (const complex<_Tp>&);
00091       template<typename _Up>
00092         complex(const complex<_Up>&);
00093         
00094       _Tp real() const;
00095       _Tp imag() const;
00096 
00097       complex<_Tp>& operator=(const _Tp&);
00098       complex<_Tp>& operator+=(const _Tp&);
00099       complex<_Tp>& operator-=(const _Tp&);
00100       complex<_Tp>& operator*=(const _Tp&);
00101       complex<_Tp>& operator/=(const _Tp&);
00102 
00103       // Let's the compiler synthetize the
00104       // copy and assignment operator
00105       // complex<_Tp>& operator= (const complex<_Tp>&);
00106       template<typename _Up>
00107         complex<_Tp>& operator=(const complex<_Up>&);
00108       template<typename _Up>
00109         complex<_Tp>& operator+=(const complex<_Up>&);
00110       template<typename _Up>
00111         complex<_Tp>& operator-=(const complex<_Up>&);
00112       template<typename _Up>
00113         complex<_Tp>& operator*=(const complex<_Up>&);
00114       template<typename _Up>
00115         complex<_Tp>& operator/=(const complex<_Up>&);
00116 
00117     private:
00118       _Tp _M_real, _M_imag;
00119     };
00120 
00121   template<typename _Tp>
00122     inline _Tp
00123     complex<_Tp>::real() const { return _M_real; }
00124 
00125   template<typename _Tp>
00126     inline _Tp
00127     complex<_Tp>::imag() const { return _M_imag; }
00128 
00129   template<typename _Tp>
00130     inline 
00131     complex<_Tp>::complex(const _Tp& __r, const _Tp& __i)
00132     : _M_real(__r), _M_imag(__i) { }
00133 
00134   template<typename _Tp>
00135     template<typename _Up>
00136     inline 
00137     complex<_Tp>::complex(const complex<_Up>& __z)
00138     : _M_real(__z.real()), _M_imag(__z.imag()) { }
00139         
00140   template<typename _Tp>
00141     complex<_Tp>&
00142     complex<_Tp>::operator=(const _Tp& __t)
00143     {
00144      _M_real = __t;
00145      _M_imag = _Tp();
00146      return *this;
00147     } 
00148 
00149   // 26.2.5/1
00150   template<typename _Tp>
00151     inline complex<_Tp>&
00152     complex<_Tp>::operator+=(const _Tp& __t)
00153     {
00154       _M_real += __t;
00155       return *this;
00156     }
00157 
00158   // 26.2.5/3
00159   template<typename _Tp>
00160     inline complex<_Tp>&
00161     complex<_Tp>::operator-=(const _Tp& __t)
00162     {
00163       _M_real -= __t;
00164       return *this;
00165     }
00166 
00167   // 26.2.5/5
00168   template<typename _Tp>
00169     complex<_Tp>&
00170     complex<_Tp>::operator*=(const _Tp& __t)
00171     {
00172       _M_real *= __t;
00173       _M_imag *= __t;
00174       return *this;
00175     }
00176 
00177   // 26.2.5/7
00178   template<typename _Tp>
00179     complex<_Tp>&
00180     complex<_Tp>::operator/=(const _Tp& __t)
00181     {
00182       _M_real /= __t;
00183       _M_imag /= __t;
00184       return *this;
00185     }
00186 
00187   template<typename _Tp>
00188     template<typename _Up>
00189     complex<_Tp>&
00190     complex<_Tp>::operator=(const complex<_Up>& __z)
00191     {
00192       _M_real = __z.real();
00193       _M_imag = __z.imag();
00194       return *this;
00195     }
00196 
00197   // 26.2.5/9
00198   template<typename _Tp>
00199     template<typename _Up>
00200     complex<_Tp>&
00201     complex<_Tp>::operator+=(const complex<_Up>& __z)
00202     {
00203       _M_real += __z.real();
00204       _M_imag += __z.imag();
00205       return *this;
00206     }
00207 
00208   // 26.2.5/11
00209   template<typename _Tp>
00210     template<typename _Up>
00211     complex<_Tp>&
00212     complex<_Tp>::operator-=(const complex<_Up>& __z)
00213     {
00214       _M_real -= __z.real();
00215       _M_imag -= __z.imag();
00216       return *this;
00217     }
00218 
00219   // 26.2.5/13
00220   // XXX: This is a grammar school implementation.
00221   template<typename _Tp>
00222     template<typename _Up>
00223     complex<_Tp>&
00224     complex<_Tp>::operator*=(const complex<_Up>& __z)
00225     {
00226       const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
00227       _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
00228       _M_real = __r;
00229       return *this;
00230     }
00231 
00232   // 26.2.5/15
00233   // XXX: This is a grammar school implementation.
00234   template<typename _Tp>
00235     template<typename _Up>
00236     complex<_Tp>&
00237     complex<_Tp>::operator/=(const complex<_Up>& __z)
00238     {
00239       const _Tp __r =  _M_real * __z.real() + _M_imag * __z.imag();
00240       const _Tp __n = norm(__z);
00241       _M_imag = (_M_real * __z.imag() - _M_imag * __z.real()) / __n;
00242       _M_real = __r / __n;
00243       return *this;
00244     }
00245     
00246   // Operators:
00247   template<typename _Tp>
00248     inline complex<_Tp>
00249     operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
00250     { return complex<_Tp> (__x) += __y; }
00251 
00252   template<typename _Tp>
00253     inline complex<_Tp>
00254     operator+(const complex<_Tp>& __x, const _Tp& __y)
00255     { return complex<_Tp> (__x) += __y; }
00256 
00257   template<typename _Tp>
00258     inline complex<_Tp>
00259     operator+(const _Tp& __x, const complex<_Tp>& __y)
00260     { return complex<_Tp> (__y) += __x; }
00261 
00262   template<typename _Tp>
00263     inline complex<_Tp>
00264     operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
00265     { return complex<_Tp> (__x) -= __y; }
00266     
00267   template<typename _Tp>
00268     inline complex<_Tp>
00269     operator-(const complex<_Tp>& __x, const _Tp& __y)
00270     { return complex<_Tp> (__x) -= __y; }
00271 
00272   template<typename _Tp>
00273     inline complex<_Tp>
00274     operator-(const _Tp& __x, const complex<_Tp>& __y)
00275     { return complex<_Tp> (__x) -= __y; }
00276 
00277   template<typename _Tp>
00278     inline complex<_Tp>
00279     operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
00280     { return complex<_Tp> (__x) *= __y; }
00281 
00282   template<typename _Tp>
00283     inline complex<_Tp>
00284     operator*(const complex<_Tp>& __x, const _Tp& __y)
00285     { return complex<_Tp> (__x) *= __y; }
00286 
00287   template<typename _Tp>
00288     inline complex<_Tp>
00289     operator*(const _Tp& __x, const complex<_Tp>& __y)
00290     { return complex<_Tp> (__y) *= __x; }
00291 
00292   template<typename _Tp>
00293     inline complex<_Tp>
00294     operator/(const complex<_Tp>& __x, const complex<_Tp>& __y)
00295     { return complex<_Tp> (__x) /= __y; }
00296     
00297   template<typename _Tp>
00298     inline complex<_Tp>
00299     operator/(const complex<_Tp>& __x, const _Tp& __y)
00300     { return complex<_Tp> (__x) /= __y; }
00301 
00302   template<typename _Tp>
00303     inline complex<_Tp>
00304     operator/(const _Tp& __x, const complex<_Tp>& __y)
00305     { return complex<_Tp> (__x) /= __y; }
00306 
00307   template<typename _Tp>
00308     inline complex<_Tp>
00309     operator+(const complex<_Tp>& __x)
00310     { return __x; }
00311 
00312   template<typename _Tp>
00313     inline complex<_Tp>
00314     operator-(const complex<_Tp>& __x)
00315     {  return complex<_Tp>(-__x.real(), -__x.imag()); }
00316 
00317   template<typename _Tp>
00318     inline bool
00319     operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
00320     { return __x.real() == __y.real() && __x.imag() == __y.imag(); }
00321 
00322   template<typename _Tp>
00323     inline bool
00324     operator==(const complex<_Tp>& __x, const _Tp& __y)
00325     { return __x.real() == __y && __x.imag() == _Tp(); }
00326 
00327   template<typename _Tp>
00328     inline bool
00329     operator==(const _Tp& __x, const complex<_Tp>& __y)
00330     { return __x == __y.real() && _Tp() == __y.imag(); }
00331 
00332   template<typename _Tp>
00333     inline bool
00334     operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
00335     { return __x.real() != __y.real() || __x.imag() != __y.imag(); }
00336 
00337   template<typename _Tp>
00338     inline bool
00339     operator!=(const complex<_Tp>& __x, const _Tp& __y)
00340     { return __x.real() != __y || __x.imag() != _Tp(); }
00341 
00342   template<typename _Tp>
00343     inline bool
00344     operator!=(const _Tp& __x, const complex<_Tp>& __y)
00345     { return __x != __y.real() || _Tp() != __y.imag(); }
00346 
00347   template<typename _Tp, typename _CharT, class _Traits>
00348     basic_istream<_CharT, _Traits>&
00349     operator>>(basic_istream<_CharT, _Traits>&, complex<_Tp>&);
00350 
00351   template<typename _Tp, typename _CharT, class _Traits>
00352     basic_ostream<_CharT, _Traits>&
00353     operator<<(basic_ostream<_CharT, _Traits>&, const complex<_Tp>&);
00354 
00355   // Values
00356   template<typename _Tp>
00357     inline _Tp
00358     real(const complex<_Tp>& __z)
00359     { return __z.real(); }
00360     
00361   template<typename _Tp>
00362     inline _Tp
00363     imag(const complex<_Tp>& __z)
00364     { return __z.imag(); }
00365 
00366   template<typename _Tp>
00367     inline _Tp
00368     abs(const complex<_Tp>& __z)
00369     {
00370       _Tp __x = __z.real();
00371       _Tp __y = __z.imag();
00372       const _Tp __s = abs(__x) + abs(__y);
00373       if (__s == _Tp())  // well ...
00374         return __s;
00375       __x /= __s; 
00376       __y /= __s;
00377       return __s * sqrt(__x * __x + __y * __y);
00378     }
00379 
00380   template<typename _Tp>
00381     inline _Tp
00382     arg(const complex<_Tp>& __z)
00383     { return atan2(__z.imag(), __z.real()); }
00384 
00385   template<typename _Tp>
00386     inline _Tp
00387     norm(const complex<_Tp>& __z)
00388     {
00389       _Tp __res = abs(__z);
00390       return __res * __res;
00391     }
00392 
00393   template<typename _Tp>
00394     inline complex<_Tp>
00395     polar(const _Tp& __rho, const _Tp& __theta)
00396     { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); }
00397 
00398   template<typename _Tp>
00399     inline complex<_Tp>
00400     conj(const complex<_Tp>& __z)
00401     { return complex<_Tp>(__z.real(), -__z.imag()); }
00402   
00403   // Transcendentals
00404   template<typename _Tp>
00405     inline complex<_Tp>
00406     cos(const complex<_Tp>& __z)
00407     {
00408       const _Tp __x = __z.real();
00409       const _Tp __y = __z.imag();
00410       return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y));
00411     }
00412 
00413   template<typename _Tp>
00414     inline complex<_Tp>
00415     cosh(const complex<_Tp>& __z)
00416     {
00417       const _Tp __x = __z.real();
00418       const _Tp __y = __z.imag();
00419       return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y));
00420     }
00421 
00422   template<typename _Tp>
00423     inline complex<_Tp>
00424     exp(const complex<_Tp>& __z)
00425     { return polar(exp(__z.real()), __z.imag()); }
00426 
00427   template<typename _Tp>
00428     inline complex<_Tp>
00429     log(const complex<_Tp>& __z)
00430     { return complex<_Tp>(log(abs(__z)), arg(__z)); }
00431 
00432   template<typename _Tp>
00433     inline complex<_Tp>
00434     log10(const complex<_Tp>& __z)
00435     { return log(__z) / log(_Tp(10.0)); }
00436 
00437   template<typename _Tp>
00438     inline complex<_Tp>
00439     sin(const complex<_Tp>& __z)
00440     {
00441       const _Tp __x = __z.real();
00442       const _Tp __y = __z.imag();
00443       return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 
00444     }
00445 
00446   template<typename _Tp>
00447     inline complex<_Tp>
00448     sinh(const complex<_Tp>& __z)
00449     {
00450       const _Tp __x = __z.real();
00451       const _Tp  __y = __z.imag();
00452       return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y));
00453     }
00454 
00455   template<typename _Tp>
00456     complex<_Tp>
00457     sqrt(const complex<_Tp>& __z)
00458     {
00459       _Tp __x = __z.real();
00460       _Tp __y = __z.imag();
00461 
00462       if (__x == _Tp())
00463         {
00464           _Tp __t = sqrt(abs(__y) / 2);
00465           return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
00466         }
00467       else
00468         {
00469           _Tp __t = sqrt(2 * (abs(__z) + abs(__x)));
00470           _Tp __u = __t / 2;
00471           return __x > _Tp()
00472             ? complex<_Tp>(__u, __y / __t)
00473             : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
00474         }
00475     }
00476 
00477   template<typename _Tp>
00478     inline complex<_Tp>
00479     tan(const complex<_Tp>& __z)
00480     {
00481       return sin(__z) / cos(__z);
00482     }
00483 
00484   template<typename _Tp>
00485     inline complex<_Tp>
00486     tanh(const complex<_Tp>& __z)
00487     {
00488       return sinh(__z) / cosh(__z);
00489     }
00490 
00491   template<typename _Tp>
00492     inline complex<_Tp>
00493     pow(const complex<_Tp>& __z, int __n)
00494     {
00495       return __pow_helper(__z, __n);
00496     }
00497 
00498   template<typename _Tp>
00499     inline complex<_Tp>
00500     pow(const complex<_Tp>& __x, const _Tp& __y)
00501     {
00502       return exp(__y * log(__x));
00503     }
00504 
00505   template<typename _Tp>
00506     inline complex<_Tp>
00507     pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
00508     {
00509       return exp(__y * log(__x));
00510     }
00511 
00512   template<typename _Tp>
00513     inline complex<_Tp>
00514     pow(const _Tp& __x, const complex<_Tp>& __y)
00515     {
00516       return exp(__y * log(__x));
00517     }
00518 
00519   // 26.2.3  complex specializations
00520   // complex<float> specialization
00521   template<> class complex<float>
00522   {
00523   public:
00524     typedef float value_type;
00525     
00526     complex(float = 0.0f, float = 0.0f);
00527 #ifdef _GLIBCPP_BUGGY_COMPLEX
00528     complex(const complex& __z) : _M_value(__z._M_value) { }
00529 #endif
00530     explicit complex(const complex<double>&);
00531     explicit complex(const complex<long double>&);
00532 
00533     float real() const;
00534     float imag() const;
00535 
00536     complex<float>& operator=(float);
00537     complex<float>& operator+=(float);
00538     complex<float>& operator-=(float);
00539     complex<float>& operator*=(float);
00540     complex<float>& operator/=(float);
00541         
00542     // Let's the compiler synthetize the copy and assignment
00543     // operator.  It always does a pretty good job.
00544     // complex& operator= (const complex&);
00545     template<typename _Tp>
00546       complex<float>&operator=(const complex<_Tp>&);
00547     template<typename _Tp>
00548       complex<float>& operator+=(const complex<_Tp>&);
00549     template<class _Tp>
00550       complex<float>& operator-=(const complex<_Tp>&);
00551     template<class _Tp>
00552       complex<float>& operator*=(const complex<_Tp>&);
00553     template<class _Tp>
00554       complex<float>&operator/=(const complex<_Tp>&);
00555 
00556   private:
00557     typedef __complex__ float _ComplexT;
00558     _ComplexT _M_value;
00559 
00560     complex(_ComplexT __z) : _M_value(__z) { }
00561         
00562     friend class complex<double>;
00563     friend class complex<long double>;
00564   };
00565 
00566   inline float
00567   complex<float>::real() const
00568   { return __real__ _M_value; }
00569 
00570   inline float
00571   complex<float>::imag() const
00572   { return __imag__ _M_value; }
00573 
00574   inline
00575   complex<float>::complex(float r, float i)
00576   {
00577     __real__ _M_value = r;
00578     __imag__ _M_value = i;
00579   }
00580 
00581   inline complex<float>&
00582   complex<float>::operator=(float __f)
00583   {
00584     __real__ _M_value = __f;
00585     __imag__ _M_value = 0.0f;
00586     return *this;
00587   }
00588 
00589   inline complex<float>&
00590   complex<float>::operator+=(float __f)
00591   {
00592     __real__ _M_value += __f;
00593     return *this;
00594   }
00595 
00596   inline complex<float>&
00597   complex<float>::operator-=(float __f)
00598   {
00599     __real__ _M_value -= __f;
00600     return *this;
00601   }
00602 
00603   inline complex<float>&
00604   complex<float>::operator*=(float __f)
00605   {
00606     _M_value *= __f;
00607     return *this;
00608   }
00609 
00610   inline complex<float>&
00611   complex<float>::operator/=(float __f)
00612   {
00613     _M_value /= __f;
00614     return *this;
00615   }
00616 
00617   template<typename _Tp>
00618   inline complex<float>&
00619   complex<float>::operator=(const complex<_Tp>& __z)
00620   {
00621     __real__ _M_value = __z.real();
00622     __imag__ _M_value = __z.imag();
00623     return *this;
00624   }
00625 
00626   template<typename _Tp>
00627   inline complex<float>&
00628   complex<float>::operator+=(const complex<_Tp>& __z)
00629   {
00630     __real__ _M_value += __z.real();
00631     __imag__ _M_value += __z.imag();
00632     return *this;
00633   }
00634     
00635   template<typename _Tp>
00636     inline complex<float>&
00637     complex<float>::operator-=(const complex<_Tp>& __z)
00638     {
00639      __real__ _M_value -= __z.real();
00640      __imag__ _M_value -= __z.imag();
00641      return *this;
00642     } 
00643 
00644   template<typename _Tp>
00645     inline complex<float>&
00646     complex<float>::operator*=(const complex<_Tp>& __z)
00647     {
00648       _ComplexT __t;
00649       __real__ __t = __z.real();
00650       __imag__ __t = __z.imag();
00651       _M_value *= __t;
00652       return *this;
00653     }
00654 
00655   template<typename _Tp>
00656     inline complex<float>&
00657     complex<float>::operator/=(const complex<_Tp>& __z)
00658     {
00659       _ComplexT __t;
00660       __real__ __t = __z.real();
00661       __imag__ __t = __z.imag();
00662       _M_value /= __t;
00663       return *this;
00664     }
00665 
00666   // 26.2.3  complex specializations
00667   // complex<double> specialization
00668   template<> class complex<double>
00669   {
00670   public:
00671     typedef double value_type;
00672 
00673     complex(double  =0.0, double =0.0);
00674 #ifdef _GLIBCPP_BUGGY_COMPLEX
00675     complex(const complex& __z) : _M_value(__z._M_value) { }
00676 #endif
00677     complex(const complex<float>&);
00678     explicit complex(const complex<long double>&);
00679         
00680     double real() const;
00681     double imag() const;
00682         
00683     complex<double>& operator=(double);
00684     complex<double>& operator+=(double);
00685     complex<double>& operator-=(double);
00686     complex<double>& operator*=(double);
00687     complex<double>& operator/=(double);
00688 
00689     // The compiler will synthetize this, efficiently.
00690     // complex& operator= (const complex&);
00691     template<typename _Tp>
00692       complex<double>& operator=(const complex<_Tp>&);
00693     template<typename _Tp>
00694       complex<double>& operator+=(const complex<_Tp>&);
00695     template<typename _Tp>
00696       complex<double>& operator-=(const complex<_Tp>&);
00697     template<typename _Tp>
00698       complex<double>& operator*=(const complex<_Tp>&);
00699     template<typename _Tp>
00700       complex<double>& operator/=(const complex<_Tp>&);
00701 
00702   private:
00703     typedef __complex__ double _ComplexT;
00704     _ComplexT _M_value;
00705 
00706     complex(_ComplexT __z) : _M_value(__z) { }
00707         
00708     friend class complex<float>;
00709     friend class complex<long double>;
00710   };
00711 
00712   inline double
00713   complex<double>::real() const
00714   { return __real__ _M_value; }
00715 
00716   inline double
00717   complex<double>::imag() const
00718   { return __imag__ _M_value; }
00719 
00720   inline
00721   complex<double>::complex(double __r, double __i)
00722   {
00723     __real__ _M_value = __r;
00724     __imag__ _M_value = __i;
00725   }
00726 
00727   inline complex<double>&
00728   complex<double>::operator=(double __d)
00729   {
00730     __real__ _M_value = __d;
00731     __imag__ _M_value = 0.0;
00732     return *this;
00733   }
00734 
00735   inline complex<double>&
00736   complex<double>::operator+=(double __d)
00737   {
00738     __real__ _M_value += __d;
00739     return *this;
00740   }
00741 
00742   inline complex<double>&
00743   complex<double>::operator-=(double __d)
00744   {
00745     __real__ _M_value -= __d;
00746     return *this;
00747   }
00748 
00749   inline complex<double>&
00750   complex<double>::operator*=(double __d)
00751   {
00752     _M_value *= __d;
00753     return *this;
00754   }
00755 
00756   inline complex<double>&
00757   complex<double>::operator/=(double __d)
00758   {
00759     _M_value /= __d;
00760     return *this;
00761   }
00762 
00763   template<typename _Tp>
00764     inline complex<double>&
00765     complex<double>::operator=(const complex<_Tp>& __z)
00766     {
00767       __real__ _M_value = __z.real();
00768       __imag__ _M_value = __z.imag();
00769       return *this;
00770     }
00771     
00772   template<typename _Tp>
00773     inline complex<double>&
00774     complex<double>::operator+=(const complex<_Tp>& __z)
00775     {
00776       __real__ _M_value += __z.real();
00777       __imag__ _M_value += __z.imag();
00778       return *this;
00779     }
00780 
00781   template<typename _Tp>
00782     inline complex<double>&
00783     complex<double>::operator-=(const complex<_Tp>& __z)
00784     {
00785       __real__ _M_value -= __z.real();
00786       __imag__ _M_value -= __z.imag();
00787       return *this;
00788     }
00789 
00790   template<typename _Tp>
00791     inline complex<double>&
00792     complex<double>::operator*=(const complex<_Tp>& __z)
00793     {
00794       _ComplexT __t;
00795       __real__ __t = __z.real();
00796       __imag__ __t = __z.imag();
00797       _M_value *= __t;
00798       return *this;
00799     }
00800 
00801   template<typename _Tp>
00802     inline complex<double>&
00803     complex<double>::operator/=(const complex<_Tp>& __z)
00804     {
00805       _ComplexT __t;
00806       __real__ __t = __z.real();
00807       __imag__ __t = __z.imag();
00808       _M_value /= __t;
00809       return *this;
00810     }
00811 
00812   // 26.2.3  complex specializations
00813   // complex<long double> specialization
00814   template<> class complex<long double>
00815   {
00816   public:
00817     typedef long double value_type;
00818 
00819     complex(long double = 0.0L, long double = 0.0L);
00820 #ifdef _GLIBCPP_BUGGY_COMPLEX
00821     complex(const complex& __z) : _M_value(__z._M_value) { }
00822 #endif
00823     complex(const complex<float>&);
00824     complex(const complex<double>&);
00825 
00826     long double real() const;
00827     long double imag() const;
00828 
00829     complex<long double>& operator= (long double);
00830     complex<long double>& operator+= (long double);
00831     complex<long double>& operator-= (long double);
00832     complex<long double>& operator*= (long double);
00833     complex<long double>& operator/= (long double);
00834 
00835     // The compiler knows how to do this efficiently
00836     // complex& operator= (const complex&);
00837     template<typename _Tp>
00838       complex<long double>& operator=(const complex<_Tp>&);
00839     template<typename _Tp>
00840       complex<long double>& operator+=(const complex<_Tp>&);
00841     template<typename _Tp>
00842       complex<long double>& operator-=(const complex<_Tp>&);
00843     template<typename _Tp>
00844       complex<long double>& operator*=(const complex<_Tp>&);
00845     template<typename _Tp>
00846       complex<long double>& operator/=(const complex<_Tp>&);
00847 
00848   private:
00849     typedef __complex__ long double _ComplexT;
00850     _ComplexT _M_value;
00851 
00852     complex(_ComplexT __z) : _M_value(__z) { }
00853 
00854     friend class complex<float>;
00855     friend class complex<double>;
00856   };
00857 
00858   inline
00859   complex<long double>::complex(long double __r, long double __i)
00860   {
00861     __real__ _M_value = __r;
00862     __imag__ _M_value = __i;
00863   }
00864 
00865   inline long double
00866   complex<long double>::real() const
00867   { return __real__ _M_value; }
00868 
00869   inline long double
00870   complex<long double>::imag() const
00871   { return __imag__ _M_value; }
00872 
00873   inline complex<long double>&   
00874   complex<long double>::operator=(long double __r)
00875   {
00876     __real__ _M_value = __r;
00877     __imag__ _M_value = 0.0L;
00878     return *this;
00879   }
00880 
00881   inline complex<long double>&
00882   complex<long double>::operator+=(long double __r)
00883   {
00884     __real__ _M_value += __r;
00885     return *this;
00886   }
00887 
00888   inline complex<long double>&
00889   complex<long double>::operator-=(long double __r)
00890   {
00891     __real__ _M_value -= __r;
00892     return *this;
00893   }
00894 
00895   inline complex<long double>&
00896   complex<long double>::operator*=(long double __r)
00897   {
00898     __real__ _M_value *= __r;
00899     return *this;
00900   }
00901 
00902   inline complex<long double>&
00903   complex<long double>::operator/=(long double __r)
00904   {
00905     __real__ _M_value /= __r;
00906     return *this;
00907   }
00908 
00909   template<typename _Tp>
00910     inline complex<long double>&
00911     complex<long double>::operator=(const complex<_Tp>& __z)
00912     {
00913       __real__ _M_value = __z.real();
00914       __imag__ _M_value = __z.imag();
00915       return *this;
00916     }
00917 
00918   template<typename _Tp>
00919     inline complex<long double>&
00920     complex<long double>::operator+=(const complex<_Tp>& __z)
00921     {
00922       __real__ _M_value += __z.real();
00923       __imag__ _M_value += __z.imag();
00924       return *this;
00925     }
00926 
00927   template<typename _Tp>
00928     inline complex<long double>&
00929     complex<long double>::operator-=(const complex<_Tp>& __z)
00930     {
00931       __real__ _M_value -= __z.real();
00932       __imag__ _M_value -= __z.imag();
00933       return *this;
00934     }
00935     
00936   template<typename _Tp>
00937     inline complex<long double>&
00938     complex<long double>::operator*=(const complex<_Tp>& __z)
00939     {
00940       _ComplexT __t;
00941       __real__ __t = __z.real();
00942       __imag__ __t = __z.imag();
00943       _M_value *= __t;
00944       return *this;
00945     }
00946 
00947   template<typename _Tp>
00948     inline complex<long double>&
00949     complex<long double>::operator/=(const complex<_Tp>& __z)
00950     {
00951       _ComplexT __t;
00952       __real__ __t = __z.real();
00953       __imag__ __t = __z.imag();
00954       _M_value /= __t;
00955       return *this;
00956     }
00957 
00958   // These bits have to be at the end of this file, so that the
00959   // specializations have all been defined.
00960   // ??? No, they have to be there because of compiler limitation at
00961   // inlining.  It suffices that class specializations be defined.
00962   inline
00963   complex<float>::complex(const complex<double>& __z)
00964   : _M_value(_ComplexT(__z._M_value)) { }
00965 
00966   inline
00967   complex<float>::complex(const complex<long double>& __z)
00968   : _M_value(_ComplexT(__z._M_value)) { }
00969 
00970   inline
00971   complex<double>::complex(const complex<float>& __z) 
00972   : _M_value(_ComplexT(__z._M_value)) { }
00973 
00974   inline
00975   complex<double>::complex(const complex<long double>& __z)
00976   {
00977     __real__ _M_value = __z.real();
00978     __imag__ _M_value = __z.imag();
00979   }
00980 
00981   inline
00982   complex<long double>::complex(const complex<float>& __z)
00983   : _M_value(_ComplexT(__z._M_value)) { }
00984 
00985   inline
00986   complex<long double>::complex(const complex<double>& __z)
00987   : _M_value(_ComplexT(__z._M_value)) { }
00988 } // namespace std
00989 
00990 #endif  /* _CPP_COMPLEX */

Generated at Tue May 1 16:28:38 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001