OSDN Git Service

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