home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 14 / hacker14.iso / programacao / cwin / c.exe / $INSTDIR / include / c++ / complex < prev    next >
Encoding:
Text File  |  2003-12-15  |  27.5 KB  |  1,060 lines

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