OSDN Git Service

2003-09-10 Petur Runolfsson <peturr02@ru.is>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / std_complex.h
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 _GLIBCXX_COMPLEX
44 #define _GLIBCXX_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 = std::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 = std::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 = std::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 && !_GLIBCXX_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 std::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(std::abs(__z)), std::arg(__z)); }
500
501   template<typename _Tp>
502     inline complex<_Tp>
503     log10(const complex<_Tp>& __z)
504     { return std::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 * (std::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 std::sin(__z) / std::cos(__z);
551     }
552
553   template<typename _Tp>
554     inline complex<_Tp>
555     tanh(const complex<_Tp>& __z)
556     {
557       return std::sinh(__z) / std::cosh(__z);
558     }
559
560   template<typename _Tp>
561     inline complex<_Tp>
562     pow(const complex<_Tp>& __z, int __n)
563     {
564       return std::__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 std::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         : std::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 _GLIBCXX_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 _GLIBCXX_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 _GLIBCXX_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  /* _GLIBCXX_COMPLEX */