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
53namespace 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 && !_GLIBCPP_FAST_MATH>::_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    complex<_Tp>
569    pow(const complex<_Tp>& __x, const _Tp& __y)
570    {
571      if (__x.imag() == _Tp())
572        return pow(__x.real(), __y);
573
574      complex<_Tp> __t = log(__x);
575      return polar(exp(__y * __t.real()), __y * __t.imag());
576    }
577
578  template<typename _Tp>
579    inline complex<_Tp>
580    pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
581    {
582      return __x == _Tp() ? _Tp() : exp(__y * log(__x));
583    }
584
585  template<typename _Tp>
586    inline complex<_Tp>
587    pow(const _Tp& __x, const complex<_Tp>& __y)
588    {
589      return __x == _Tp()
590        ? _Tp()
591        : polar(pow(__x, __y.real()), __y.imag() * log(__x));
592    }
593
594  // 26.2.3  complex specializations
595  // complex<float> specialization
596  template<> class complex<float>
597  {
598  public:
599    typedef float value_type;
600
601    complex(float = 0.0f, float = 0.0f);
602#ifdef _GLIBCPP_BUGGY_COMPLEX
603    complex(const complex& __z) : _M_value(__z._M_value) { }
604#endif
605    explicit complex(const complex<double>&);
606    explicit complex(const complex<long double>&);
607
608    float real() const;
609    float imag() const;
610
611    complex<float>& operator=(float);
612    complex<float>& operator+=(float);
613    complex<float>& operator-=(float);
614    complex<float>& operator*=(float);
615    complex<float>& operator/=(float);
616
617    // Let's the compiler synthetize the copy and assignment
618    // operator.  It always does a pretty good job.
619    // complex& operator= (const complex&);
620    template<typename _Tp>
621      complex<float>&operator=(const complex<_Tp>&);
622    template<typename _Tp>
623      complex<float>& operator+=(const complex<_Tp>&);
624    template<class _Tp>
625      complex<float>& operator-=(const complex<_Tp>&);
626    template<class _Tp>
627      complex<float>& operator*=(const complex<_Tp>&);
628    template<class _Tp>
629      complex<float>&operator/=(const complex<_Tp>&);
630
631  private:
632    typedef __complex__ float _ComplexT;
633    _ComplexT _M_value;
634
635    complex(_ComplexT __z) : _M_value(__z) { }
636
637    friend class complex<double>;
638    friend class complex<long double>;
639  };
640
641  inline float
642  complex<float>::real() const
643  { return __real__ _M_value; }
644
645  inline float
646  complex<float>::imag() const
647  { return __imag__ _M_value; }
648
649  inline
650  complex<float>::complex(float r, float i)
651  {
652    __real__ _M_value = r;
653    __imag__ _M_value = i;
654  }
655
656  inline complex<float>&
657  complex<float>::operator=(float __f)
658  {
659    __real__ _M_value = __f;
660    __imag__ _M_value = 0.0f;
661    return *this;
662  }
663
664  inline complex<float>&
665  complex<float>::operator+=(float __f)
666  {
667    __real__ _M_value += __f;
668    return *this;
669  }
670
671  inline complex<float>&
672  complex<float>::operator-=(float __f)
673  {
674    __real__ _M_value -= __f;
675    return *this;
676  }
677
678  inline complex<float>&
679  complex<float>::operator*=(float __f)
680  {
681    _M_value *= __f;
682    return *this;
683  }
684
685  inline complex<float>&
686  complex<float>::operator/=(float __f)
687  {
688    _M_value /= __f;
689    return *this;
690  }
691
692  template<typename _Tp>
693  inline complex<float>&
694  complex<float>::operator=(const complex<_Tp>& __z)
695  {
696    __real__ _M_value = __z.real();
697    __imag__ _M_value = __z.imag();
698    return *this;
699  }
700
701  template<typename _Tp>
702  inline complex<float>&
703  complex<float>::operator+=(const complex<_Tp>& __z)
704  {
705    __real__ _M_value += __z.real();
706    __imag__ _M_value += __z.imag();
707    return *this;
708  }
709
710  template<typename _Tp>
711    inline complex<float>&
712    complex<float>::operator-=(const complex<_Tp>& __z)
713    {
714     __real__ _M_value -= __z.real();
715     __imag__ _M_value -= __z.imag();
716     return *this;
717    }
718
719  template<typename _Tp>
720    inline complex<float>&
721    complex<float>::operator*=(const complex<_Tp>& __z)
722    {
723      _ComplexT __t;
724      __real__ __t = __z.real();
725      __imag__ __t = __z.imag();
726      _M_value *= __t;
727      return *this;
728    }
729
730  template<typename _Tp>
731    inline complex<float>&
732    complex<float>::operator/=(const complex<_Tp>& __z)
733    {
734      _ComplexT __t;
735      __real__ __t = __z.real();
736      __imag__ __t = __z.imag();
737      _M_value /= __t;
738      return *this;
739    }
740
741  // 26.2.3  complex specializations
742  // complex<double> specialization
743  template<> class complex<double>
744  {
745  public:
746    typedef double value_type;
747
748    complex(double  =0.0, double =0.0);
749#ifdef _GLIBCPP_BUGGY_COMPLEX
750    complex(const complex& __z) : _M_value(__z._M_value) { }
751#endif
752    complex(const complex<float>&);
753    explicit complex(const complex<long double>&);
754
755    double real() const;
756    double imag() const;
757
758    complex<double>& operator=(double);
759    complex<double>& operator+=(double);
760    complex<double>& operator-=(double);
761    complex<double>& operator*=(double);
762    complex<double>& operator/=(double);
763
764    // The compiler will synthetize this, efficiently.
765    // complex& operator= (const complex&);
766    template<typename _Tp>
767      complex<double>& operator=(const complex<_Tp>&);
768    template<typename _Tp>
769      complex<double>& operator+=(const complex<_Tp>&);
770    template<typename _Tp>
771      complex<double>& operator-=(const complex<_Tp>&);
772    template<typename _Tp>
773      complex<double>& operator*=(const complex<_Tp>&);
774    template<typename _Tp>
775      complex<double>& operator/=(const complex<_Tp>&);
776
777  private:
778    typedef __complex__ double _ComplexT;
779    _ComplexT _M_value;
780
781    complex(_ComplexT __z) : _M_value(__z) { }
782
783    friend class complex<float>;
784    friend class complex<long double>;
785  };
786
787  inline double
788  complex<double>::real() const
789  { return __real__ _M_value; }
790
791  inline double
792  complex<double>::imag() const
793  { return __imag__ _M_value; }
794
795  inline
796  complex<double>::complex(double __r, double __i)
797  {
798    __real__ _M_value = __r;
799    __imag__ _M_value = __i;
800  }
801
802  inline complex<double>&
803  complex<double>::operator=(double __d)
804  {
805    __real__ _M_value = __d;
806    __imag__ _M_value = 0.0;
807    return *this;
808  }
809
810  inline complex<double>&
811  complex<double>::operator+=(double __d)
812  {
813    __real__ _M_value += __d;
814    return *this;
815  }
816
817  inline complex<double>&
818  complex<double>::operator-=(double __d)
819  {
820    __real__ _M_value -= __d;
821    return *this;
822  }
823
824  inline complex<double>&
825  complex<double>::operator*=(double __d)
826  {
827    _M_value *= __d;
828    return *this;
829  }
830
831  inline complex<double>&
832  complex<double>::operator/=(double __d)
833  {
834    _M_value /= __d;
835    return *this;
836  }
837
838  template<typename _Tp>
839    inline complex<double>&
840    complex<double>::operator=(const complex<_Tp>& __z)
841    {
842      __real__ _M_value = __z.real();
843      __imag__ _M_value = __z.imag();
844      return *this;
845    }
846
847  template<typename _Tp>
848    inline complex<double>&
849    complex<double>::operator+=(const complex<_Tp>& __z)
850    {
851      __real__ _M_value += __z.real();
852      __imag__ _M_value += __z.imag();
853      return *this;
854    }
855
856  template<typename _Tp>
857    inline complex<double>&
858    complex<double>::operator-=(const complex<_Tp>& __z)
859    {
860      __real__ _M_value -= __z.real();
861      __imag__ _M_value -= __z.imag();
862      return *this;
863    }
864
865  template<typename _Tp>
866    inline complex<double>&
867    complex<double>::operator*=(const complex<_Tp>& __z)
868    {
869      _ComplexT __t;
870      __real__ __t = __z.real();
871      __imag__ __t = __z.imag();
872      _M_value *= __t;
873      return *this;
874    }
875
876  template<typename _Tp>
877    inline complex<double>&
878    complex<double>::operator/=(const complex<_Tp>& __z)
879    {
880      _ComplexT __t;
881      __real__ __t = __z.real();
882      __imag__ __t = __z.imag();
883      _M_value /= __t;
884      return *this;
885    }
886
887  // 26.2.3  complex specializations
888  // complex<long double> specialization
889  template<> class complex<long double>
890  {
891  public:
892    typedef long double value_type;
893
894    complex(long double = 0.0L, long double = 0.0L);
895#ifdef _GLIBCPP_BUGGY_COMPLEX
896    complex(const complex& __z) : _M_value(__z._M_value) { }
897#endif
898    complex(const complex<float>&);
899    complex(const complex<double>&);
900
901    long double real() const;
902    long double imag() const;
903
904    complex<long double>& operator= (long double);
905    complex<long double>& operator+= (long double);
906    complex<long double>& operator-= (long double);
907    complex<long double>& operator*= (long double);
908    complex<long double>& operator/= (long double);
909
910    // The compiler knows how to do this efficiently
911    // complex& operator= (const complex&);
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    template<typename _Tp>
917      complex<long double>& operator-=(const complex<_Tp>&);
918    template<typename _Tp>
919      complex<long double>& operator*=(const complex<_Tp>&);
920    template<typename _Tp>
921      complex<long double>& operator/=(const complex<_Tp>&);
922
923  private:
924    typedef __complex__ long double _ComplexT;
925    _ComplexT _M_value;
926
927    complex(_ComplexT __z) : _M_value(__z) { }
928
929    friend class complex<float>;
930    friend class complex<double>;
931  };
932
933  inline
934  complex<long double>::complex(long double __r, long double __i)
935  {
936    __real__ _M_value = __r;
937    __imag__ _M_value = __i;
938  }
939
940  inline long double
941  complex<long double>::real() const
942  { return __real__ _M_value; }
943
944  inline long double
945  complex<long double>::imag() const
946  { return __imag__ _M_value; }
947
948  inline complex<long double>&
949  complex<long double>::operator=(long double __r)
950  {
951    __real__ _M_value = __r;
952    __imag__ _M_value = 0.0L;
953    return *this;
954  }
955
956  inline complex<long double>&
957  complex<long double>::operator+=(long double __r)
958  {
959    __real__ _M_value += __r;
960    return *this;
961  }
962
963  inline complex<long double>&
964  complex<long double>::operator-=(long double __r)
965  {
966    __real__ _M_value -= __r;
967    return *this;
968  }
969
970  inline complex<long double>&
971  complex<long double>::operator*=(long double __r)
972  {
973    _M_value *= __r;
974    return *this;
975  }
976
977  inline complex<long double>&
978  complex<long double>::operator/=(long double __r)
979  {
980    _M_value /= __r;
981    return *this;
982  }
983
984  template<typename _Tp>
985    inline complex<long double>&
986    complex<long double>::operator=(const complex<_Tp>& __z)
987    {
988      __real__ _M_value = __z.real();
989      __imag__ _M_value = __z.imag();
990      return *this;
991    }
992
993  template<typename _Tp>
994    inline complex<long double>&
995    complex<long double>::operator+=(const complex<_Tp>& __z)
996    {
997      __real__ _M_value += __z.real();
998      __imag__ _M_value += __z.imag();
999      return *this;
1000    }
1001
1002  template<typename _Tp>
1003    inline complex<long double>&
1004    complex<long double>::operator-=(const complex<_Tp>& __z)
1005    {
1006      __real__ _M_value -= __z.real();
1007      __imag__ _M_value -= __z.imag();
1008      return *this;
1009    }
1010
1011  template<typename _Tp>
1012    inline complex<long double>&
1013    complex<long double>::operator*=(const complex<_Tp>& __z)
1014    {
1015      _ComplexT __t;
1016      __real__ __t = __z.real();
1017      __imag__ __t = __z.imag();
1018      _M_value *= __t;
1019      return *this;
1020    }
1021
1022  template<typename _Tp>
1023    inline complex<long double>&
1024    complex<long double>::operator/=(const complex<_Tp>& __z)
1025    {
1026      _ComplexT __t;
1027      __real__ __t = __z.real();
1028      __imag__ __t = __z.imag();
1029      _M_value /= __t;
1030      return *this;
1031    }
1032
1033  // These bits have to be at the end of this file, so that the
1034  // specializations have all been defined.
1035  // ??? No, they have to be there because of compiler limitation at
1036  // inlining.  It suffices that class specializations be defined.
1037  inline
1038  complex<float>::complex(const complex<double>& __z)
1039  : _M_value(_ComplexT(__z._M_value)) { }
1040
1041  inline
1042  complex<float>::complex(const complex<long double>& __z)
1043  : _M_value(_ComplexT(__z._M_value)) { }
1044
1045  inline
1046  complex<double>::complex(const complex<float>& __z)
1047  : _M_value(_ComplexT(__z._M_value)) { }
1048
1049  inline
1050  complex<double>::complex(const complex<long double>& __z)
1051  {
1052    __real__ _M_value = __z.real();
1053    __imag__ _M_value = __z.imag();
1054  }
1055
1056  inline
1057  complex<long double>::complex(const complex<float>& __z)
1058  : _M_value(_ComplexT(__z._M_value)) { }
1059
1060  inline
1061  complex<long double>::complex(const complex<double>& __z)
1062  : _M_value(_ComplexT(__z._M_value)) { }
1063} // namespace std
1064
1065#endif	/* _CPP_COMPLEX */
1066