# 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
    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 _CPP_COMPLEX
    00044 #define _CPP_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
    00061   template<typename _Tp> _Tp abs(const complex<_Tp>&);
    00062   template<typename _Tp> _Tp arg(const complex<_Tp>&);
    00063   template<typename _Tp> _Tp norm(const complex<_Tp>&);
    00064
    00065   template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&);
    00066   template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
    00067
    00068   // Transcendentals:
    00069   template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&);
    00070   template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&);
    00071   template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&);
    00072   template<typename _Tp> complex<_Tp> log(const complex<_Tp>&);
    00073   template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&);
    00074   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int);
    00075   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&);
    00076   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&,
    00077                        const complex<_Tp>&);
    00078   template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&);
    00079   template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&);
    00080   template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&);
    00081   template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&);
    00082   template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&);
    00083   template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&);
    00084
    00085
    00086   // 26.2.2  Primary template class complex
    00087   template<typename _Tp>
    00088     class complex
    00089     {
    00090     public:
    00091       typedef _Tp value_type;
    00092
    00093       complex(const _Tp& = _Tp(), const _Tp & = _Tp());
    00094
    00095       // Let's the compiler synthetize the copy constructor
    00096       // complex (const complex<_Tp>&);
    00097       template<typename _Up>
    00098         complex(const complex<_Up>&);
    00099
    00100       _Tp real() const;
    00101       _Tp imag() const;
    00102
    00103       complex<_Tp>& operator=(const _Tp&);
    00104       complex<_Tp>& operator+=(const _Tp&);
    00105       complex<_Tp>& operator-=(const _Tp&);
    00106       complex<_Tp>& operator*=(const _Tp&);
    00107       complex<_Tp>& operator/=(const _Tp&);
    00108
    00109       // Let's the compiler synthetize the
    00110       // copy and assignment operator
    00111       // complex<_Tp>& operator= (const complex<_Tp>&);
    00112       template<typename _Up>
    00113         complex<_Tp>& operator=(const complex<_Up>&);
    00114       template<typename _Up>
    00115         complex<_Tp>& operator+=(const complex<_Up>&);
    00116       template<typename _Up>
    00117         complex<_Tp>& operator-=(const complex<_Up>&);
    00118       template<typename _Up>
    00119         complex<_Tp>& operator*=(const complex<_Up>&);
    00120       template<typename _Up>
    00121         complex<_Tp>& operator/=(const complex<_Up>&);
    00122
    00123     private:
    00124       _Tp _M_real, _M_imag;
    00125     };
    00126
    00127   template<typename _Tp>
    00128     inline _Tp
    00129     complex<_Tp>::real() const { return _M_real; }
    00130
    00131   template<typename _Tp>
    00132     inline _Tp
    00133     complex<_Tp>::imag() const { return _M_imag; }
    00134
    00135   template<typename _Tp>
    00136     inline
    00137     complex<_Tp>::complex(const _Tp& __r, const _Tp& __i)
    00138     : _M_real(__r), _M_imag(__i) { }
    00139
    00140   template<typename _Tp>
    00141     template<typename _Up>
    00142     inline
    00143     complex<_Tp>::complex(const complex<_Up>& __z)
    00144     : _M_real(__z.real()), _M_imag(__z.imag()) { }
    00145
    00146   template<typename _Tp>
    00147     complex<_Tp>&
    00148     complex<_Tp>::operator=(const _Tp& __t)
    00149     {
    00150      _M_real = __t;
    00151      _M_imag = _Tp();
    00152      return *this;
    00153     }
    00154
    00155   // 26.2.5/1
    00156   template<typename _Tp>
    00157     inline complex<_Tp>&
    00158     complex<_Tp>::operator+=(const _Tp& __t)
    00159     {
    00160       _M_real += __t;
    00161       return *this;
    00162     }
    00163
    00164   // 26.2.5/3
    00165   template<typename _Tp>
    00166     inline complex<_Tp>&
    00167     complex<_Tp>::operator-=(const _Tp& __t)
    00168     {
    00169       _M_real -= __t;
    00170       return *this;
    00171     }
    00172
    00173   // 26.2.5/5
    00174   template<typename _Tp>
    00175     complex<_Tp>&
    00176     complex<_Tp>::operator*=(const _Tp& __t)
    00177     {
    00178       _M_real *= __t;
    00179       _M_imag *= __t;
    00180       return *this;
    00181     }
    00182
    00183   // 26.2.5/7
    00184   template<typename _Tp>
    00185     complex<_Tp>&
    00186     complex<_Tp>::operator/=(const _Tp& __t)
    00187     {
    00188       _M_real /= __t;
    00189       _M_imag /= __t;
    00190       return *this;
    00191     }
    00192
    00193   template<typename _Tp>
    00194     template<typename _Up>
    00195     complex<_Tp>&
    00196     complex<_Tp>::operator=(const complex<_Up>& __z)
    00197     {
    00198       _M_real = __z.real();
    00199       _M_imag = __z.imag();
    00200       return *this;
    00201     }
    00202
    00203   // 26.2.5/9
    00204   template<typename _Tp>
    00205     template<typename _Up>
    00206     complex<_Tp>&
    00207     complex<_Tp>::operator+=(const complex<_Up>& __z)
    00208     {
    00209       _M_real += __z.real();
    00210       _M_imag += __z.imag();
    00211       return *this;
    00212     }
    00213
    00214   // 26.2.5/11
    00215   template<typename _Tp>
    00216     template<typename _Up>
    00217     complex<_Tp>&
    00218     complex<_Tp>::operator-=(const complex<_Up>& __z)
    00219     {
    00220       _M_real -= __z.real();
    00221       _M_imag -= __z.imag();
    00222       return *this;
    00223     }
    00224
    00225   // 26.2.5/13
    00226   // XXX: This is a grammar school implementation.
    00227   template<typename _Tp>
    00228     template<typename _Up>
    00229     complex<_Tp>&
    00230     complex<_Tp>::operator*=(const complex<_Up>& __z)
    00231     {
    00232       const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
    00233       _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
    00234       _M_real = __r;
    00235       return *this;
    00236     }
    00237
    00238   // 26.2.5/15
    00239   // XXX: This is a grammar school implementation.
    00240   template<typename _Tp>
    00241     template<typename _Up>
    00242     complex<_Tp>&
    00243     complex<_Tp>::operator/=(const complex<_Up>& __z)
    00244     {
    00245       const _Tp __r =  _M_real * __z.real() + _M_imag * __z.imag();
    00246       const _Tp __n = norm(__z);
    00247       _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n;
    00248       _M_real = __r / __n;
    00249       return *this;
    00250     }
    00251
    00252   // Operators:
    00253   template<typename _Tp>
    00254     inline complex<_Tp>
    00255     operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
    00256     { return complex<_Tp> (__x) += __y; }
    00257
    00258   template<typename _Tp>
    00259     inline complex<_Tp>
    00260     operator+(const complex<_Tp>& __x, const _Tp& __y)
    00261     { return complex<_Tp> (__x) += __y; }
    00262
    00263   template<typename _Tp>
    00264     inline complex<_Tp>
    00265     operator+(const _Tp& __x, const complex<_Tp>& __y)
    00266     { return complex<_Tp> (__y) += __x; }
    00267
    00268   template<typename _Tp>
    00269     inline complex<_Tp>
    00270     operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
    00271     { return complex<_Tp> (__x) -= __y; }
    00272
    00273   template<typename _Tp>
    00274     inline complex<_Tp>
    00275     operator-(const complex<_Tp>& __x, const _Tp& __y)
    00276     { return complex<_Tp> (__x) -= __y; }
    00277
    00278   template<typename _Tp>
    00279     inline complex<_Tp>
    00280     operator-(const _Tp& __x, const complex<_Tp>& __y)
    00281     { return complex<_Tp> (__x) -= __y; }
    00282
    00283   template<typename _Tp>
    00284     inline complex<_Tp>
    00285     operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
    00286     { return complex<_Tp> (__x) *= __y; }
    00287
    00288   template<typename _Tp>
    00289     inline complex<_Tp>
    00290     operator*(const complex<_Tp>& __x, const _Tp& __y)
    00291     { return complex<_Tp> (__x) *= __y; }
    00292
    00293   template<typename _Tp>
    00294     inline complex<_Tp>
    00295     operator*(const _Tp& __x, const complex<_Tp>& __y)
    00296     { return complex<_Tp> (__y) *= __x; }
    00297
    00298   template<typename _Tp>
    00299     inline complex<_Tp>
    00300     operator/(const complex<_Tp>& __x, const complex<_Tp>& __y)
    00301     { return complex<_Tp> (__x) /= __y; }
    00302
    00303   template<typename _Tp>
    00304     inline complex<_Tp>
    00305     operator/(const complex<_Tp>& __x, const _Tp& __y)
    00306     { return complex<_Tp> (__x) /= __y; }
    00307
    00308   template<typename _Tp>
    00309     inline complex<_Tp>
    00310     operator/(const _Tp& __x, const complex<_Tp>& __y)
    00311     { return complex<_Tp> (__x) /= __y; }
    00312
    00313   template<typename _Tp>
    00314     inline complex<_Tp>
    00315     operator+(const complex<_Tp>& __x)
    00316     { return __x; }
    00317
    00318   template<typename _Tp>
    00319     inline complex<_Tp>
    00320     operator-(const complex<_Tp>& __x)
    00321     {  return complex<_Tp>(-__x.real(), -__x.imag()); }
    00322
    00323   template<typename _Tp>
    00324     inline bool
    00325     operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
    00326     { return __x.real() == __y.real() && __x.imag() == __y.imag(); }
    00327
    00328   template<typename _Tp>
    00329     inline bool
    00330     operator==(const complex<_Tp>& __x, const _Tp& __y)
    00331     { return __x.real() == __y && __x.imag() == _Tp(); }
    00332
    00333   template<typename _Tp>
    00334     inline bool
    00335     operator==(const _Tp& __x, const complex<_Tp>& __y)
    00336     { return __x == __y.real() && _Tp() == __y.imag(); }
    00337
    00338   template<typename _Tp>
    00339     inline bool
    00340     operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
    00341     { return __x.real() != __y.real() || __x.imag() != __y.imag(); }
    00342
    00343   template<typename _Tp>
    00344     inline bool
    00345     operator!=(const complex<_Tp>& __x, const _Tp& __y)
    00346     { return __x.real() != __y || __x.imag() != _Tp(); }
    00347
    00348   template<typename _Tp>
    00349     inline bool
    00350     operator!=(const _Tp& __x, const complex<_Tp>& __y)
    00351     { return __x != __y.real() || _Tp() != __y.imag(); }
    00352
    00353   template<typename _Tp, typename _CharT, class _Traits>
    00354     basic_istream<_CharT, _Traits>&
    00355     operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
    00356     {
    00357       _Tp __re_x, __im_x;
    00358       _CharT __ch;
    00359       __is >> __ch;
    00360       if (__ch == '(')
    00361     {
    00362       __is >> __re_x >> __ch;
    00363       if (__ch == ',')
    00364         {
    00365           __is >> __im_x >> __ch;
    00366           if (__ch == ')')
    00367         __x = complex<_Tp>(__re_x, __im_x);
    00368           else
    00369         __is.setstate(ios_base::failbit);
    00370         }
    00371       else if (__ch == ')')
    00372         __x = complex<_Tp>(__re_x, _Tp(0));
    00373       else
    00374         __is.setstate(ios_base::failbit);
    00375     }
    00376       else
    00377     {
    00378       __is.putback(__ch);
    00379       __is >> __re_x;
    00380       __x = complex<_Tp>(__re_x, _Tp(0));
    00381     }
    00382       return __is;
    00383     }
    00384
    00385   template<typename _Tp, typename _CharT, class _Traits>
    00386     basic_ostream<_CharT, _Traits>&
    00387     operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
    00388     {
    00389       basic_ostringstream<_CharT, _Traits> __s;
    00390       __s.flags(__os.flags());
    00391       __s.imbue(__os.getloc());
    00392       __s.precision(__os.precision());
    00393       __s << '(' << __x.real() << ',' << __x.imag() << ')';
    00394       return __os << __s.str();
    00395     }
    00396
    00397   // Values
    00398   template<typename _Tp>
    00399     inline _Tp
    00400     real(const complex<_Tp>& __z)
    00401     { return __z.real(); }
    00402
    00403   template<typename _Tp>
    00404     inline _Tp
    00405     imag(const complex<_Tp>& __z)
    00406     { return __z.imag(); }
    00407
    00408   template<typename _Tp>
    00409     inline _Tp
    00410     abs(const complex<_Tp>& __z)
    00411     {
    00412       _Tp __x = __z.real();
    00413       _Tp __y = __z.imag();
    00414       const _Tp __s = max(abs(__x), abs(__y));
    00415       if (__s == _Tp())  // well ...
    00416         return __s;
    00417       __x /= __s;
    00418       __y /= __s;
    00419       return __s * sqrt(__x * __x + __y * __y);
    00420     }
    00421
    00422   template<typename _Tp>
    00423     inline _Tp
    00424     arg(const complex<_Tp>& __z)
    00425     { return atan2(__z.imag(), __z.real()); }
    00426
    00427   // 26.2.7/5: norm(__z) returns the squared magintude of __z.
    00428   //     As defined, norm() is -not- a norm is the common mathematical
    00429   //     sens used in numerics.  The helper class _Norm_helper<> tries to
    00430   //     distinguish between builtin floating point and the rest, so as
    00431   //     to deliver an answer as close as possible to the real value.
    00432   template<bool>
    00433     struct _Norm_helper
    00434     {
    00435       template<typename _Tp>
    00436         static inline _Tp _S_do_it(const complex<_Tp>& __z)
    00437         {
    00438           const _Tp __x = __z.real();
    00439           const _Tp __y = __z.imag();
    00440           return __x * __x + __y * __y;
    00441         }
    00442     };
    00443
    00444   template<>
    00445     struct _Norm_helper<true>
    00446     {
    00447       template<typename _Tp>
    00448         static inline _Tp _S_do_it(const complex<_Tp>& __z)
    00449         {
    00450           _Tp __res = abs(__z);
    00451           return __res * __res;
    00452         }
    00453     };
    00454
    00455   template<typename _Tp>
    00456     inline _Tp
    00457     norm(const complex<_Tp>& __z)
    00458     {
    00459       return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCPP_FAST_MATH>::_S_do_it(__z);
    00460     }
    00461
    00462   template<typename _Tp>
    00463     inline complex<_Tp>
    00464     polar(const _Tp& __rho, const _Tp& __theta)
    00465     { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); }
    00466
    00467   template<typename _Tp>
    00468     inline complex<_Tp>
    00469     conj(const complex<_Tp>& __z)
    00470     { return complex<_Tp>(__z.real(), -__z.imag()); }
    00471
    00472   // Transcendentals
    00473   template<typename _Tp>
    00474     inline complex<_Tp>
    00475     cos(const complex<_Tp>& __z)
    00476     {
    00477       const _Tp __x = __z.real();
    00478       const _Tp __y = __z.imag();
    00479       return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y));
    00480     }
    00481
    00482   template<typename _Tp>
    00483     inline complex<_Tp>
    00484     cosh(const complex<_Tp>& __z)
    00485     {
    00486       const _Tp __x = __z.real();
    00487       const _Tp __y = __z.imag();
    00488       return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y));
    00489     }
    00490
    00491   template<typename _Tp>
    00492     inline complex<_Tp>
    00493     exp(const complex<_Tp>& __z)
    00494     { return polar(exp(__z.real()), __z.imag()); }
    00495
    00496   template<typename _Tp>
    00497     inline complex<_Tp>
    00498     log(const complex<_Tp>& __z)
    00499     { return complex<_Tp>(log(abs(__z)), arg(__z)); }
    00500
    00501   template<typename _Tp>
    00502     inline complex<_Tp>
    00503     log10(const complex<_Tp>& __z)
    00504     { return log(__z) / log(_Tp(10.0)); }
    00505
    00506   template<typename _Tp>
    00507     inline complex<_Tp>
    00508     sin(const complex<_Tp>& __z)
    00509     {
    00510       const _Tp __x = __z.real();
    00511       const _Tp __y = __z.imag();
    00512       return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y));
    00513     }
    00514
    00515   template<typename _Tp>
    00516     inline complex<_Tp>
    00517     sinh(const complex<_Tp>& __z)
    00518     {
    00519       const _Tp __x = __z.real();
    00520       const _Tp  __y = __z.imag();
    00521       return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y));
    00522     }
    00523
    00524   template<typename _Tp>
    00525     complex<_Tp>
    00526     sqrt(const complex<_Tp>& __z)
    00527     {
    00528       _Tp __x = __z.real();
    00529       _Tp __y = __z.imag();
    00530
    00531       if (__x == _Tp())
    00532         {
    00533           _Tp __t = sqrt(abs(__y) / 2);
    00534           return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
    00535         }
    00536       else
    00537         {
    00538           _Tp __t = sqrt(2 * (abs(__z) + abs(__x)));
    00539           _Tp __u = __t / 2;
    00540           return __x > _Tp()
    00541             ? complex<_Tp>(__u, __y / __t)
    00542             : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
    00543         }
    00544     }
    00545
    00546   template<typename _Tp>
    00547     inline complex<_Tp>
    00548     tan(const complex<_Tp>& __z)
    00549     {
    00550       return sin(__z) / cos(__z);
    00551     }
    00552
    00553   template<typename _Tp>
    00554     inline complex<_Tp>
    00555     tanh(const complex<_Tp>& __z)
    00556     {
    00557       return sinh(__z) / cosh(__z);
    00558     }
    00559
    00560   template<typename _Tp>
    00561     inline complex<_Tp>
    00562     pow(const complex<_Tp>& __z, int __n)
    00563     {
    00564       return __pow_helper(__z, __n);
    00565     }
    00566
    00567   template<typename _Tp>
    00568     inline complex<_Tp>
    00569     pow(const complex<_Tp>& __x, const _Tp& __y)
    00570     {
    00571       return exp(__y * log(__x));
    00572     }
    00573
    00574   template<typename _Tp>
    00575     inline complex<_Tp>
    00576     pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
    00577     {
    00578       return exp(__y * log(__x));
    00579     }
    00580
    00581   template<typename _Tp>
    00582     inline complex<_Tp>
    00583     pow(const _Tp& __x, const complex<_Tp>& __y)
    00584     {
    00585       return exp(__y * log(__x));
    00586     }
    00587
    00588   // 26.2.3  complex specializations
    00589   // complex<float> specialization
    00590   template<> class complex<float>
    00591   {
    00592   public:
    00593     typedef float value_type;
    00594
    00595     complex(float = 0.0f, float = 0.0f);
    00596 #ifdef _GLIBCPP_BUGGY_COMPLEX
    00597     complex(const complex& __z) : _M_value(__z._M_value) { }
    00598 #endif
    00599     explicit complex(const complex<double>&);
    00600     explicit complex(const complex<long double>&);
    00601
    00602     float real() const;
    00603     float imag() const;
    00604
    00605     complex<float>& operator=(float);
    00606     complex<float>& operator+=(float);
    00607     complex<float>& operator-=(float);
    00608     complex<float>& operator*=(float);
    00609     complex<float>& operator/=(float);
    00610
    00611     // Let's the compiler synthetize the copy and assignment
    00612     // operator.  It always does a pretty good job.
    00613     // complex& operator= (const complex&);
    00614     template<typename _Tp>
    00615       complex<float>&operator=(const complex<_Tp>&);
    00616     template<typename _Tp>
    00617       complex<float>& operator+=(const complex<_Tp>&);
    00618     template<class _Tp>
    00619       complex<float>& operator-=(const complex<_Tp>&);
    00620     template<class _Tp>
    00621       complex<float>& operator*=(const complex<_Tp>&);
    00622     template<class _Tp>
    00623       complex<float>&operator/=(const complex<_Tp>&);
    00624
    00625   private:
    00626     typedef __complex__ float _ComplexT;
    00627     _ComplexT _M_value;
    00628
    00629     complex(_ComplexT __z) : _M_value(__z) { }
    00630
    00631     friend class complex<double>;
    00632     friend class complex<long double>;
    00633   };
    00634
    00635   inline float
    00636   complex<float>::real() const
    00637   { return __real__ _M_value; }
    00638
    00639   inline float
    00640   complex<float>::imag() const
    00641   { return __imag__ _M_value; }
    00642
    00643   inline
    00644   complex<float>::complex(float r, float i)
    00645   {
    00646     __real__ _M_value = r;
    00647     __imag__ _M_value = i;
    00648   }
    00649
    00650   inline complex<float>&
    00651   complex<float>::operator=(float __f)
    00652   {
    00653     __real__ _M_value = __f;
    00654     __imag__ _M_value = 0.0f;
    00655     return *this;
    00656   }
    00657
    00658   inline complex<float>&
    00659   complex<float>::operator+=(float __f)
    00660   {
    00661     __real__ _M_value += __f;
    00662     return *this;
    00663   }
    00664
    00665   inline complex<float>&
    00666   complex<float>::operator-=(float __f)
    00667   {
    00668     __real__ _M_value -= __f;
    00669     return *this;
    00670   }
    00671
    00672   inline complex<float>&
    00673   complex<float>::operator*=(float __f)
    00674   {
    00675     _M_value *= __f;
    00676     return *this;
    00677   }
    00678
    00679   inline complex<float>&
    00680   complex<float>::operator/=(float __f)
    00681   {
    00682     _M_value /= __f;
    00683     return *this;
    00684   }
    00685
    00686   template<typename _Tp>
    00687   inline complex<float>&
    00688   complex<float>::operator=(const complex<_Tp>& __z)
    00689   {
    00690     __real__ _M_value = __z.real();
    00691     __imag__ _M_value = __z.imag();
    00692     return *this;
    00693   }
    00694
    00695   template<typename _Tp>
    00696   inline complex<float>&
    00697   complex<float>::operator+=(const complex<_Tp>& __z)
    00698   {
    00699     __real__ _M_value += __z.real();
    00700     __imag__ _M_value += __z.imag();
    00701     return *this;
    00702   }
    00703
    00704   template<typename _Tp>
    00705     inline complex<float>&
    00706     complex<float>::operator-=(const complex<_Tp>& __z)
    00707     {
    00708      __real__ _M_value -= __z.real();
    00709      __imag__ _M_value -= __z.imag();
    00710      return *this;
    00711     }
    00712
    00713   template<typename _Tp>
    00714     inline complex<float>&
    00715     complex<float>::operator*=(const complex<_Tp>& __z)
    00716     {
    00717       _ComplexT __t;
    00718       __real__ __t = __z.real();
    00719       __imag__ __t = __z.imag();
    00720       _M_value *= __t;
    00721       return *this;
    00722     }
    00723
    00724   template<typename _Tp>
    00725     inline complex<float>&
    00726     complex<float>::operator/=(const complex<_Tp>& __z)
    00727     {
    00728       _ComplexT __t;
    00729       __real__ __t = __z.real();
    00730       __imag__ __t = __z.imag();
    00731       _M_value /= __t;
    00732       return *this;
    00733     }
    00734
    00735   // 26.2.3  complex specializations
    00736   // complex<double> specialization
    00737   template<> class complex<double>
    00738   {
    00739   public:
    00740     typedef double value_type;
    00741
    00742     complex(double  =0.0, double =0.0);
    00743 #ifdef _GLIBCPP_BUGGY_COMPLEX
    00744     complex(const complex& __z) : _M_value(__z._M_value) { }
    00745 #endif
    00746     complex(const complex<float>&);
    00747     explicit complex(const complex<long double>&);
    00748
    00749     double real() const;
    00750     double imag() const;
    00751
    00752     complex<double>& operator=(double);
    00753     complex<double>& operator+=(double);
    00754     complex<double>& operator-=(double);
    00755     complex<double>& operator*=(double);
    00756     complex<double>& operator/=(double);
    00757
    00758     // The compiler will synthetize this, efficiently.
    00759     // complex& operator= (const complex&);
    00760     template<typename _Tp>
    00761       complex<double>& operator=(const complex<_Tp>&);
    00762     template<typename _Tp>
    00763       complex<double>& operator+=(const complex<_Tp>&);
    00764     template<typename _Tp>
    00765       complex<double>& operator-=(const complex<_Tp>&);
    00766     template<typename _Tp>
    00767       complex<double>& operator*=(const complex<_Tp>&);
    00768     template<typename _Tp>
    00769       complex<double>& operator/=(const complex<_Tp>&);
    00770
    00771   private:
    00772     typedef __complex__ double _ComplexT;
    00773     _ComplexT _M_value;
    00774
    00775     complex(_ComplexT __z) : _M_value(__z) { }
    00776
    00777     friend class complex<float>;
    00778     friend class complex<long double>;
    00779   };
    00780
    00781   inline double
    00782   complex<double>::real() const
    00783   { return __real__ _M_value; }
    00784
    00785   inline double
    00786   complex<double>::imag() const
    00787   { return __imag__ _M_value; }
    00788
    00789   inline
    00790   complex<double>::complex(double __r, double __i)
    00791   {
    00792     __real__ _M_value = __r;
    00793     __imag__ _M_value = __i;
    00794   }
    00795
    00796   inline complex<double>&
    00797   complex<double>::operator=(double __d)
    00798   {
    00799     __real__ _M_value = __d;
    00800     __imag__ _M_value = 0.0;
    00801     return *this;
    00802   }
    00803
    00804   inline complex<double>&
    00805   complex<double>::operator+=(double __d)
    00806   {
    00807     __real__ _M_value += __d;
    00808     return *this;
    00809   }
    00810
    00811   inline complex<double>&
    00812   complex<double>::operator-=(double __d)
    00813   {
    00814     __real__ _M_value -= __d;
    00815     return *this;
    00816   }
    00817
    00818   inline complex<double>&
    00819   complex<double>::operator*=(double __d)
    00820   {
    00821     _M_value *= __d;
    00822     return *this;
    00823   }
    00824
    00825   inline complex<double>&
    00826   complex<double>::operator/=(double __d)
    00827   {
    00828     _M_value /= __d;
    00829     return *this;
    00830   }
    00831
    00832   template<typename _Tp>
    00833     inline complex<double>&
    00834     complex<double>::operator=(const complex<_Tp>& __z)
    00835     {
    00836       __real__ _M_value = __z.real();
    00837       __imag__ _M_value = __z.imag();
    00838       return *this;
    00839     }
    00840
    00841   template<typename _Tp>
    00842     inline complex<double>&
    00843     complex<double>::operator+=(const complex<_Tp>& __z)
    00844     {
    00845       __real__ _M_value += __z.real();
    00846       __imag__ _M_value += __z.imag();
    00847       return *this;
    00848     }
    00849
    00850   template<typename _Tp>
    00851     inline complex<double>&
    00852     complex<double>::operator-=(const complex<_Tp>& __z)
    00853     {
    00854       __real__ _M_value -= __z.real();
    00855       __imag__ _M_value -= __z.imag();
    00856       return *this;
    00857     }
    00858
    00859   template<typename _Tp>
    00860     inline complex<double>&
    00861     complex<double>::operator*=(const complex<_Tp>& __z)
    00862     {
    00863       _ComplexT __t;
    00864       __real__ __t = __z.real();
    00865       __imag__ __t = __z.imag();
    00866       _M_value *= __t;
    00867       return *this;
    00868     }
    00869
    00870   template<typename _Tp>
    00871     inline complex<double>&
    00872     complex<double>::operator/=(const complex<_Tp>& __z)
    00873     {
    00874       _ComplexT __t;
    00875       __real__ __t = __z.real();
    00876       __imag__ __t = __z.imag();
    00877       _M_value /= __t;
    00878       return *this;
    00879     }
    00880
    00881   // 26.2.3  complex specializations
    00882   // complex<long double> specialization
    00883   template<> class complex<long double>
    00884   {
    00885   public:
    00886     typedef long double value_type;
    00887
    00888     complex(long double = 0.0L, long double = 0.0L);
    00889 #ifdef _GLIBCPP_BUGGY_COMPLEX
    00890     complex(const complex& __z) : _M_value(__z._M_value) { }
    00891 #endif
    00892     complex(const complex<float>&);
    00893     complex(const complex<double>&);
    00894
    00895     long double real() const;
    00896     long double imag() const;
    00897
    00898     complex<long double>& operator= (long double);
    00899     complex<long double>& operator+= (long double);
    00900     complex<long double>& operator-= (long double);
    00901     complex<long double>& operator*= (long double);
    00902     complex<long double>& operator/= (long double);
    00903
    00904     // The compiler knows how to do this efficiently
    00905     // complex& operator= (const complex&);
    00906     template<typename _Tp>
    00907       complex<long double>& operator=(const complex<_Tp>&);
    00908     template<typename _Tp>
    00909       complex<long double>& operator+=(const complex<_Tp>&);
    00910     template<typename _Tp>
    00911       complex<long double>& operator-=(const complex<_Tp>&);
    00912     template<typename _Tp>
    00913       complex<long double>& operator*=(const complex<_Tp>&);
    00914     template<typename _Tp>
    00915       complex<long double>& operator/=(const complex<_Tp>&);
    00916
    00917   private:
    00918     typedef __complex__ long double _ComplexT;
    00919     _ComplexT _M_value;
    00920
    00921     complex(_ComplexT __z) : _M_value(__z) { }
    00922
    00923     friend class complex<float>;
    00924     friend class complex<double>;
    00925   };
    00926
    00927   inline
    00928   complex<long double>::complex(long double __r, long double __i)
    00929   {
    00930     __real__ _M_value = __r;
    00931     __imag__ _M_value = __i;
    00932   }
    00933
    00934   inline long double
    00935   complex<long double>::real() const
    00936   { return __real__ _M_value; }
    00937
    00938   inline long double
    00939   complex<long double>::imag() const
    00940   { return __imag__ _M_value; }
    00941
    00942   inline complex<long double>&
    00943   complex<long double>::operator=(long double __r)
    00944   {
    00945     __real__ _M_value = __r;
    00946     __imag__ _M_value = 0.0L;
    00947     return *this;
    00948   }
    00949
    00950   inline complex<long double>&
    00951   complex<long double>::operator+=(long double __r)
    00952   {
    00953     __real__ _M_value += __r;
    00954     return *this;
    00955   }
    00956
    00957   inline complex<long double>&
    00958   complex<long double>::operator-=(long double __r)
    00959   {
    00960     __real__ _M_value -= __r;
    00961     return *this;
    00962   }
    00963
    00964   inline complex<long double>&
    00965   complex<long double>::operator*=(long double __r)
    00966   {
    00967     _M_value *= __r;
    00968     return *this;
    00969   }
    00970
    00971   inline complex<long double>&
    00972   complex<long double>::operator/=(long double __r)
    00973   {
    00974     _M_value /= __r;
    00975     return *this;
    00976   }
    00977
    00978   template<typename _Tp>
    00979     inline complex<long double>&
    00980     complex<long double>::operator=(const complex<_Tp>& __z)
    00981     {
    00982       __real__ _M_value = __z.real();
    00983       __imag__ _M_value = __z.imag();
    00984       return *this;
    00985     }
    00986
    00987   template<typename _Tp>
    00988     inline complex<long double>&
    00989     complex<long double>::operator+=(const complex<_Tp>& __z)
    00990     {
    00991       __real__ _M_value += __z.real();
    00992       __imag__ _M_value += __z.imag();
    00993       return *this;
    00994     }
    00995
    00996   template<typename _Tp>
    00997     inline complex<long double>&
    00998     complex<long double>::operator-=(const complex<_Tp>& __z)
    00999     {
    01000       __real__ _M_value -= __z.real();
    01001       __imag__ _M_value -= __z.imag();
    01002       return *this;
    01003     }
    01004
    01005   template<typename _Tp>
    01006     inline complex<long double>&
    01007     complex<long double>::operator*=(const complex<_Tp>& __z)
    01008     {
    01009       _ComplexT __t;
    01010       __real__ __t = __z.real();
    01011       __imag__ __t = __z.imag();
    01012       _M_value *= __t;
    01013       return *this;
    01014     }
    01015
    01016   template<typename _Tp>
    01017     inline complex<long double>&
    01018     complex<long double>::operator/=(const complex<_Tp>& __z)
    01019     {
    01020       _ComplexT __t;
    01021       __real__ __t = __z.real();
    01022       __imag__ __t = __z.imag();
    01023       _M_value /= __t;
    01024       return *this;
    01025     }
    01026
    01027   // These bits have to be at the end of this file, so that the
    01028   // specializations have all been defined.
    01029   // ??? No, they have to be there because of compiler limitation at
    01030   // inlining.  It suffices that class specializations be defined.
    01031   inline
    01032   complex<float>::complex(const complex<double>& __z)
    01033   : _M_value(_ComplexT(__z._M_value)) { }
    01034
    01035   inline
    01036   complex<float>::complex(const complex<long double>& __z)
    01037   : _M_value(_ComplexT(__z._M_value)) { }
    01038
    01039   inline
    01040   complex<double>::complex(const complex<float>& __z)
    01041   : _M_value(_ComplexT(__z._M_value)) { }
    01042
    01043   inline
    01044   complex<double>::complex(const complex<long double>& __z)
    01045   {
    01046     __real__ _M_value = __z.real();
    01047     __imag__ _M_value = __z.imag();
    01048   }
    01049
    01050   inline
    01051   complex<long double>::complex(const complex<float>& __z)
    01052   : _M_value(_ComplexT(__z._M_value)) { }
    01053
    01054   inline
    01055   complex<long double>::complex(const complex<double>& __z)
    01056   : _M_value(_ComplexT(__z._M_value)) { }
    01057 } // namespace std
    01058
    01059 #endif  /* _CPP_COMPLEX */