Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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