source: svn/trunk/newcon3bcm2_21bu/toolchain/include/c++/3.4.2/complex @ 37

Last change on this file since 37 was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 31.8 KB
Line 
1// The template and inlines for the -*- C++ -*- complex number classes.
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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
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  ///  Return magnitude of @a z.
62  template<typename _Tp> _Tp abs(const complex<_Tp>&);
63  ///  Return phase angle of @a z.
64  template<typename _Tp> _Tp arg(const complex<_Tp>&);
65  ///  Return @a z magnitude squared.
66  template<typename _Tp> _Tp norm(const complex<_Tp>&);
67
68  ///  Return complex conjugate of @a z.
69  template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&);
70  ///  Return complex with magnitude @a rho and angle @a theta.
71  template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
72
73  // Transcendentals:
74  /// Return complex cosine of @a z.
75  template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&);
76  /// Return complex hyperbolic cosine of @a z.
77  template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&);
78  /// Return complex base e exponential of @a z.
79  template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&);
80  /// Return complex natural logarithm of @a z.
81  template<typename _Tp> complex<_Tp> log(const complex<_Tp>&);
82  /// Return complex base 10 logarithm of @a z.
83  template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&);
84  /// Return complex cosine of @a z.
85  template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int);
86  /// Return @a x to the @a y'th power.
87  template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&);
88  /// Return @a x to the @a y'th power.
89  template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 
90                                           const complex<_Tp>&);
91  /// Return @a x to the @a y'th power.
92  template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&);
93  /// Return complex sine of @a z.
94  template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&);
95  /// Return complex hyperbolic sine of @a z.
96  template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&);
97  /// Return complex square root of @a z.
98  template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&);
99  /// Return complex tangent of @a z.
100  template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&);
101  /// Return complex hyperbolic tangent of @a z.
102  template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&);
103  //@}
104   
105   
106  // 26.2.2  Primary template class complex
107  /**
108   *  Template to represent complex numbers.
109   *
110   *  Specializations for float, double, and long double are part of the
111   *  library.  Results with any other type are not guaranteed.
112   *
113   *  @param  Tp  Type of real and imaginary values.
114  */
115  template<typename _Tp>
116    class complex
117    {
118    public:
119      /// Value typedef.
120      typedef _Tp value_type;
121     
122      ///  Default constructor.  First parameter is x, second parameter is y.
123      ///  Unspecified parameters default to 0.
124      complex(const _Tp& = _Tp(), const _Tp & = _Tp());
125
126      // Lets the compiler synthesize the copy constructor   
127      // complex (const complex<_Tp>&);
128      ///  Copy constructor.
129      template<typename _Up>
130        complex(const complex<_Up>&);
131
132      ///  Return real part of complex number.
133      _Tp& real(); 
134      ///  Return real part of complex number.
135      const _Tp& real() const;
136      ///  Return imaginary part of complex number.
137      _Tp& imag();
138      ///  Return imaginary part of complex number.
139      const _Tp& imag() const;
140
141      /// Assign this complex number to scalar @a t.
142      complex<_Tp>& operator=(const _Tp&);
143      /// Add @a t to this complex number.
144      complex<_Tp>& operator+=(const _Tp&);
145      /// Subtract @a t from this complex number.
146      complex<_Tp>& operator-=(const _Tp&);
147      /// Multiply this complex number by @a t.
148      complex<_Tp>& operator*=(const _Tp&);
149      /// Divide this complex number by @a t.
150      complex<_Tp>& operator/=(const _Tp&);
151
152      // Lets the compiler synthesize the
153      // copy and assignment operator
154      // complex<_Tp>& operator= (const complex<_Tp>&);
155      /// Assign this complex number to complex @a z.
156      template<typename _Up>
157        complex<_Tp>& operator=(const complex<_Up>&);
158      /// Add @a z to this complex number.
159      template<typename _Up>
160        complex<_Tp>& operator+=(const complex<_Up>&);
161      /// Subtract @a z from this complex number.
162      template<typename _Up>
163        complex<_Tp>& operator-=(const complex<_Up>&);
164      /// Multiply this complex number by @a z.
165      template<typename _Up>
166        complex<_Tp>& operator*=(const complex<_Up>&);
167      /// Divide this complex number by @a z.
168      template<typename _Up>
169        complex<_Tp>& operator/=(const complex<_Up>&);
170
171    private:
172      _Tp _M_real;
173      _Tp _M_imag;
174    };
175
176  template<typename _Tp>
177    inline _Tp&
178    complex<_Tp>::real() { return _M_real; }
179
180  template<typename _Tp>
181    inline const _Tp&
182    complex<_Tp>::real() const { return _M_real; }
183
184  template<typename _Tp>
185    inline _Tp&
186    complex<_Tp>::imag() { return _M_imag; }
187
188  template<typename _Tp>
189    inline const _Tp&
190    complex<_Tp>::imag() const { return _M_imag; }
191
192  template<typename _Tp>
193    inline 
194    complex<_Tp>::complex(const _Tp& __r, const _Tp& __i)
195    : _M_real(__r), _M_imag(__i) { }
196
197  template<typename _Tp>
198    template<typename _Up>
199    inline 
200    complex<_Tp>::complex(const complex<_Up>& __z)
201    : _M_real(__z.real()), _M_imag(__z.imag()) { }
202       
203  template<typename _Tp>
204    complex<_Tp>&
205    complex<_Tp>::operator=(const _Tp& __t)
206    {
207     _M_real = __t;
208     _M_imag = _Tp();
209     return *this;
210    } 
211
212  // 26.2.5/1
213  template<typename _Tp>
214    inline complex<_Tp>&
215    complex<_Tp>::operator+=(const _Tp& __t)
216    {
217      _M_real += __t;
218      return *this;
219    }
220
221  // 26.2.5/3
222  template<typename _Tp>
223    inline complex<_Tp>&
224    complex<_Tp>::operator-=(const _Tp& __t)
225    {
226      _M_real -= __t;
227      return *this;
228    }
229
230  // 26.2.5/5
231  template<typename _Tp>
232    complex<_Tp>&
233    complex<_Tp>::operator*=(const _Tp& __t)
234    {
235      _M_real *= __t;
236      _M_imag *= __t;
237      return *this;
238    }
239
240  // 26.2.5/7
241  template<typename _Tp>
242    complex<_Tp>&
243    complex<_Tp>::operator/=(const _Tp& __t)
244    {
245      _M_real /= __t;
246      _M_imag /= __t;
247      return *this;
248    }
249
250  template<typename _Tp>
251    template<typename _Up>
252    complex<_Tp>&
253    complex<_Tp>::operator=(const complex<_Up>& __z)
254    {
255      _M_real = __z.real();
256      _M_imag = __z.imag();
257      return *this;
258    }
259
260  // 26.2.5/9
261  template<typename _Tp>
262    template<typename _Up>
263    complex<_Tp>&
264    complex<_Tp>::operator+=(const complex<_Up>& __z)
265    {
266      _M_real += __z.real();
267      _M_imag += __z.imag();
268      return *this;
269    }
270
271  // 26.2.5/11
272  template<typename _Tp>
273    template<typename _Up>
274    complex<_Tp>&
275    complex<_Tp>::operator-=(const complex<_Up>& __z)
276    {
277      _M_real -= __z.real();
278      _M_imag -= __z.imag();
279      return *this;
280    }
281
282  // 26.2.5/13
283  // XXX: This is a grammar school implementation.
284  template<typename _Tp>
285    template<typename _Up>
286    complex<_Tp>&
287    complex<_Tp>::operator*=(const complex<_Up>& __z)
288    {
289      const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
290      _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
291      _M_real = __r;
292      return *this;
293    }
294
295  // 26.2.5/15
296  // XXX: This is a grammar school implementation.
297  template<typename _Tp>
298    template<typename _Up>
299    complex<_Tp>&
300    complex<_Tp>::operator/=(const complex<_Up>& __z)
301    {
302      const _Tp __r =  _M_real * __z.real() + _M_imag * __z.imag();
303      const _Tp __n = std::norm(__z);
304      _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n;
305      _M_real = __r / __n;
306      return *this;
307    }
308   
309  // Operators:
310  //@{
311  ///  Return new complex value @a x plus @a y.
312  template<typename _Tp>
313    inline complex<_Tp>
314    operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
315    {
316      complex<_Tp> __r = __x;
317      __r += __y;
318      return __r;
319    }
320
321  template<typename _Tp>
322    inline complex<_Tp>
323    operator+(const complex<_Tp>& __x, const _Tp& __y)
324    {
325      complex<_Tp> __r = __x;
326      __r.real() += __y;
327      return __r;
328    }
329
330  template<typename _Tp>
331    inline complex<_Tp>
332    operator+(const _Tp& __x, const complex<_Tp>& __y)
333    {
334      complex<_Tp> __r = __y;
335      __r.real() += __x;
336      return __r;
337    }
338  //@}
339
340  //@{
341  ///  Return new complex value @a x minus @a y.
342  template<typename _Tp>
343    inline complex<_Tp>
344    operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
345    {
346      complex<_Tp> __r = __x;
347      __r -= __y;
348      return __r;
349    }
350   
351  template<typename _Tp>
352    inline complex<_Tp>
353    operator-(const complex<_Tp>& __x, const _Tp& __y)
354    {
355      complex<_Tp> __r = __x;
356      __r.real() -= __y;
357      return __r;
358    }
359
360  template<typename _Tp>
361    inline complex<_Tp>
362    operator-(const _Tp& __x, const complex<_Tp>& __y)
363    {
364      complex<_Tp> __r(__x, -__y.imag());
365      __r.real() -= __y.real();
366      return __r;
367    }
368  //@}
369
370  //@{
371  ///  Return new complex value @a x times @a y.
372  template<typename _Tp>
373    inline complex<_Tp>
374    operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
375    {
376      complex<_Tp> __r = __x;
377      __r *= __y;
378      return __r;
379    }
380
381  template<typename _Tp>
382    inline complex<_Tp>
383    operator*(const complex<_Tp>& __x, const _Tp& __y)
384    {
385      complex<_Tp> __r = __x;
386      __r *= __y;
387      return __r;
388    }
389
390  template<typename _Tp>
391    inline complex<_Tp>
392    operator*(const _Tp& __x, const complex<_Tp>& __y)
393    {
394      complex<_Tp> __r = __y;
395      __r *= __x;
396      return __r;
397    }
398  //@}
399
400  //@{
401  ///  Return new complex value @a x divided by @a y.
402  template<typename _Tp>
403    inline complex<_Tp>
404    operator/(const complex<_Tp>& __x, const complex<_Tp>& __y)
405    {
406      complex<_Tp> __r = __x;
407      __r /= __y;
408      return __r;
409    }
410   
411  template<typename _Tp>
412    inline complex<_Tp>
413    operator/(const complex<_Tp>& __x, const _Tp& __y)
414    {
415      complex<_Tp> __r = __x;
416      __r /= __y;
417      return __r;
418    }
419
420  template<typename _Tp>
421    inline complex<_Tp>
422    operator/(const _Tp& __x, const complex<_Tp>& __y)
423    {
424      complex<_Tp> __r = __x;
425      __r /= __y;
426      return __r;
427    }
428  //@}
429
430  ///  Return @a x.
431  template<typename _Tp>
432    inline complex<_Tp>
433    operator+(const complex<_Tp>& __x)
434    { return __x; }
435
436  ///  Return complex negation of @a x.
437  template<typename _Tp>
438    inline complex<_Tp>
439    operator-(const complex<_Tp>& __x)
440    {  return complex<_Tp>(-__x.real(), -__x.imag()); }
441
442  //@{
443  ///  Return true if @a x is equal to @a y.
444  template<typename _Tp>
445    inline bool
446    operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
447    { return __x.real() == __y.real() && __x.imag() == __y.imag(); }
448
449  template<typename _Tp>
450    inline bool
451    operator==(const complex<_Tp>& __x, const _Tp& __y)
452    { return __x.real() == __y && __x.imag() == _Tp(); }
453
454  template<typename _Tp>
455    inline bool
456    operator==(const _Tp& __x, const complex<_Tp>& __y)
457    { return __x == __y.real() && _Tp() == __y.imag(); }
458  //@}
459
460  //@{
461  ///  Return false if @a x is equal to @a y.
462  template<typename _Tp>
463    inline bool
464    operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
465    { return __x.real() != __y.real() || __x.imag() != __y.imag(); }
466
467  template<typename _Tp>
468    inline bool
469    operator!=(const complex<_Tp>& __x, const _Tp& __y)
470    { return __x.real() != __y || __x.imag() != _Tp(); }
471
472  template<typename _Tp>
473    inline bool
474    operator!=(const _Tp& __x, const complex<_Tp>& __y)
475    { return __x != __y.real() || _Tp() != __y.imag(); }
476  //@}
477
478  ///  Extraction operator for complex values.
479  template<typename _Tp, typename _CharT, class _Traits>
480    basic_istream<_CharT, _Traits>&
481    operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
482    {
483      _Tp __re_x, __im_x;
484      _CharT __ch;
485      __is >> __ch;
486      if (__ch == '(') 
487        {
488          __is >> __re_x >> __ch;
489          if (__ch == ',') 
490            {
491              __is >> __im_x >> __ch;
492              if (__ch == ')') 
493                __x = complex<_Tp>(__re_x, __im_x);
494              else
495                __is.setstate(ios_base::failbit);
496            }
497          else if (__ch == ')') 
498            __x = __re_x;
499          else
500            __is.setstate(ios_base::failbit);
501        }
502      else 
503        {
504          __is.putback(__ch);
505          __is >> __re_x;
506          __x = __re_x;
507        }
508      return __is;
509    }
510
511  ///  Insertion operator for complex values.
512  template<typename _Tp, typename _CharT, class _Traits>
513    basic_ostream<_CharT, _Traits>&
514    operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
515    {
516      basic_ostringstream<_CharT, _Traits> __s;
517      __s.flags(__os.flags());
518      __s.imbue(__os.getloc());
519      __s.precision(__os.precision());
520      __s << '(' << __x.real() << ',' << __x.imag() << ')';
521      return __os << __s.str();
522    }
523
524  // Values
525  template<typename _Tp>
526    inline _Tp&
527    real(complex<_Tp>& __z)
528    { return __z.real(); }
529   
530  template<typename _Tp>
531    inline const _Tp&
532    real(const complex<_Tp>& __z)
533    { return __z.real(); }
534   
535  template<typename _Tp>
536    inline _Tp&
537    imag(complex<_Tp>& __z)
538    { return __z.imag(); }
539   
540  template<typename _Tp>
541    inline const _Tp&
542    imag(const complex<_Tp>& __z)
543    { return __z.imag(); }
544
545  template<typename _Tp>
546    inline _Tp
547    abs(const complex<_Tp>& __z)
548    {
549      _Tp __x = __z.real();
550      _Tp __y = __z.imag();
551      const _Tp __s = std::max(abs(__x), abs(__y));
552      if (__s == _Tp())  // well ...
553        return __s;
554      __x /= __s; 
555      __y /= __s;
556      return __s * sqrt(__x * __x + __y * __y);
557    }
558
559  template<typename _Tp>
560    inline _Tp
561    arg(const complex<_Tp>& __z)
562    { return atan2(__z.imag(), __z.real()); }
563
564  // 26.2.7/5: norm(__z) returns the squared magintude of __z.
565  //     As defined, norm() is -not- a norm is the common mathematical
566  //     sens used in numerics.  The helper class _Norm_helper<> tries to
567  //     distinguish between builtin floating point and the rest, so as
568  //     to deliver an answer as close as possible to the real value.
569  template<bool>
570    struct _Norm_helper
571    {
572      template<typename _Tp>
573        static inline _Tp _S_do_it(const complex<_Tp>& __z)
574        {
575          const _Tp __x = __z.real();
576          const _Tp __y = __z.imag();
577          return __x * __x + __y * __y;
578        }
579    };
580
581  template<>
582    struct _Norm_helper<true>
583    {
584      template<typename _Tp>
585        static inline _Tp _S_do_it(const complex<_Tp>& __z)
586        {
587          _Tp __res = std::abs(__z);
588          return __res * __res;
589        }
590    };
591 
592  template<typename _Tp>
593    inline _Tp
594    norm(const complex<_Tp>& __z)
595    {
596      return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCXX_FAST_MATH>::_S_do_it(__z);
597    }
598
599  template<typename _Tp>
600    inline complex<_Tp>
601    polar(const _Tp& __rho, const _Tp& __theta)
602    { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); }
603
604  template<typename _Tp>
605    inline complex<_Tp>
606    conj(const complex<_Tp>& __z)
607    { return complex<_Tp>(__z.real(), -__z.imag()); }
608 
609  // Transcendentals
610  template<typename _Tp>
611    inline complex<_Tp>
612    cos(const complex<_Tp>& __z)
613    {
614      const _Tp __x = __z.real();
615      const _Tp __y = __z.imag();
616      return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y));
617    }
618
619  template<typename _Tp>
620    inline complex<_Tp>
621    cosh(const complex<_Tp>& __z)
622    {
623      const _Tp __x = __z.real();
624      const _Tp __y = __z.imag();
625      return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y));
626    }
627
628  template<typename _Tp>
629    inline complex<_Tp>
630    exp(const complex<_Tp>& __z)
631    { return std::polar(exp(__z.real()), __z.imag()); }
632
633  template<typename _Tp>
634    inline complex<_Tp>
635    log(const complex<_Tp>& __z)
636    { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); }
637
638  template<typename _Tp>
639    inline complex<_Tp>
640    log10(const complex<_Tp>& __z)
641    { return std::log(__z) / log(_Tp(10.0)); }
642
643  template<typename _Tp>
644    inline complex<_Tp>
645    sin(const complex<_Tp>& __z)
646    {
647      const _Tp __x = __z.real();
648      const _Tp __y = __z.imag();
649      return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 
650    }
651
652  template<typename _Tp>
653    inline complex<_Tp>
654    sinh(const complex<_Tp>& __z)
655    {
656      const _Tp __x = __z.real();
657      const _Tp  __y = __z.imag();
658      return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y));
659    }
660
661  template<typename _Tp>
662    complex<_Tp>
663    sqrt(const complex<_Tp>& __z)
664    {
665      _Tp __x = __z.real();
666      _Tp __y = __z.imag();
667
668      if (__x == _Tp())
669        {
670          _Tp __t = sqrt(abs(__y) / 2);
671          return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
672        }
673      else
674        {
675          _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x)));
676          _Tp __u = __t / 2;
677          return __x > _Tp()
678            ? complex<_Tp>(__u, __y / __t)
679            : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
680        }
681    }
682
683  template<typename _Tp>
684    inline complex<_Tp>
685    tan(const complex<_Tp>& __z)
686    {
687      return std::sin(__z) / std::cos(__z);
688    }
689
690  template<typename _Tp>
691    inline complex<_Tp>
692    tanh(const complex<_Tp>& __z)
693    {
694      return std::sinh(__z) / std::cosh(__z);
695    }
696
697  template<typename _Tp>
698    inline complex<_Tp>
699    pow(const complex<_Tp>& __z, int __n)
700    {
701      return std::__pow_helper(__z, __n);
702    }
703
704  template<typename _Tp>
705    complex<_Tp>
706    pow(const complex<_Tp>& __x, const _Tp& __y)
707    {
708      if (__x.imag() == _Tp() && __x.real() > _Tp())
709        return pow(__x.real(), __y);
710
711      complex<_Tp> __t = std::log(__x);
712      return std::polar(exp(__y * __t.real()), __y * __t.imag());
713    }
714
715  template<typename _Tp>
716    inline complex<_Tp>
717    pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
718    {
719      return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x));
720    }
721
722  template<typename _Tp>
723    inline complex<_Tp>
724    pow(const _Tp& __x, const complex<_Tp>& __y)
725    {
726      return __x > _Tp() ? std::polar(pow(__x, __y.real()),
727                                      __y.imag() * log(__x))
728                         : std::pow(complex<_Tp>(__x, _Tp()), __y);
729    }
730
731  // 26.2.3  complex specializations
732  // complex<float> specialization
733  template<> class complex<float>
734  {
735  public:
736    typedef float value_type;
737   
738    complex(float = 0.0f, float = 0.0f);
739#ifdef _GLIBCXX_BUGGY_COMPLEX
740    complex(const complex& __z) : _M_value(__z._M_value) { }
741#endif
742    explicit complex(const complex<double>&);
743    explicit complex(const complex<long double>&);
744
745    float& real();
746    const float& real() const;
747    float& imag();
748    const float& imag() const;
749
750    complex<float>& operator=(float);
751    complex<float>& operator+=(float);
752    complex<float>& operator-=(float);
753    complex<float>& operator*=(float);
754    complex<float>& operator/=(float);
755       
756    // Let's the compiler synthetize the copy and assignment
757    // operator.  It always does a pretty good job.
758    // complex& operator= (const complex&);
759    template<typename _Tp>
760      complex<float>&operator=(const complex<_Tp>&);
761    template<typename _Tp>
762      complex<float>& operator+=(const complex<_Tp>&);
763    template<class _Tp>
764      complex<float>& operator-=(const complex<_Tp>&);
765    template<class _Tp>
766      complex<float>& operator*=(const complex<_Tp>&);
767    template<class _Tp>
768      complex<float>&operator/=(const complex<_Tp>&);
769
770  private:
771    typedef __complex__ float _ComplexT;
772    _ComplexT _M_value;
773
774    complex(_ComplexT __z) : _M_value(__z) { }
775       
776    friend class complex<double>;
777    friend class complex<long double>;
778  };
779
780  inline float&
781  complex<float>::real()
782  { return __real__ _M_value; }
783
784  inline const float&
785  complex<float>::real() const
786  { return __real__ _M_value; }
787
788  inline float&
789  complex<float>::imag()
790  { return __imag__ _M_value; }
791
792  inline const float&
793  complex<float>::imag() const
794  { return __imag__ _M_value; }
795
796  inline
797  complex<float>::complex(float r, float i)
798  {
799    __real__ _M_value = r;
800    __imag__ _M_value = i;
801  }
802
803  inline complex<float>&
804  complex<float>::operator=(float __f)
805  {
806    __real__ _M_value = __f;
807    __imag__ _M_value = 0.0f;
808    return *this;
809  }
810
811  inline complex<float>&
812  complex<float>::operator+=(float __f)
813  {
814    __real__ _M_value += __f;
815    return *this;
816  }
817
818  inline complex<float>&
819  complex<float>::operator-=(float __f)
820  {
821    __real__ _M_value -= __f;
822    return *this;
823  }
824
825  inline complex<float>&
826  complex<float>::operator*=(float __f)
827  {
828    _M_value *= __f;
829    return *this;
830  }
831
832  inline complex<float>&
833  complex<float>::operator/=(float __f)
834  {
835    _M_value /= __f;
836    return *this;
837  }
838
839  template<typename _Tp>
840  inline complex<float>&
841  complex<float>::operator=(const complex<_Tp>& __z)
842  {
843    __real__ _M_value = __z.real();
844    __imag__ _M_value = __z.imag();
845    return *this;
846  }
847
848  template<typename _Tp>
849  inline complex<float>&
850  complex<float>::operator+=(const complex<_Tp>& __z)
851  {
852    __real__ _M_value += __z.real();
853    __imag__ _M_value += __z.imag();
854    return *this;
855  }
856   
857  template<typename _Tp>
858    inline complex<float>&
859    complex<float>::operator-=(const complex<_Tp>& __z)
860    {
861     __real__ _M_value -= __z.real();
862     __imag__ _M_value -= __z.imag();
863     return *this;
864    } 
865
866  template<typename _Tp>
867    inline complex<float>&
868    complex<float>::operator*=(const complex<_Tp>& __z)
869    {
870      _ComplexT __t;
871      __real__ __t = __z.real();
872      __imag__ __t = __z.imag();
873      _M_value *= __t;
874      return *this;
875    }
876
877  template<typename _Tp>
878    inline complex<float>&
879    complex<float>::operator/=(const complex<_Tp>& __z)
880    {
881      _ComplexT __t;
882      __real__ __t = __z.real();
883      __imag__ __t = __z.imag();
884      _M_value /= __t;
885      return *this;
886    }
887
888  // 26.2.3  complex specializations
889  // complex<double> specialization
890  template<> class complex<double>
891  {
892  public:
893    typedef double value_type;
894
895    complex(double  =0.0, double =0.0);
896#ifdef _GLIBCXX_BUGGY_COMPLEX
897    complex(const complex& __z) : _M_value(__z._M_value) { }
898#endif
899    complex(const complex<float>&);
900    explicit complex(const complex<long double>&);
901
902    double& real();
903    const double& real() const;
904    double& imag();
905    const double& imag() const;
906       
907    complex<double>& operator=(double);
908    complex<double>& operator+=(double);
909    complex<double>& operator-=(double);
910    complex<double>& operator*=(double);
911    complex<double>& operator/=(double);
912
913    // The compiler will synthetize this, efficiently.
914    // complex& operator= (const complex&);
915    template<typename _Tp>
916      complex<double>& operator=(const complex<_Tp>&);
917    template<typename _Tp>
918      complex<double>& operator+=(const complex<_Tp>&);
919    template<typename _Tp>
920      complex<double>& operator-=(const complex<_Tp>&);
921    template<typename _Tp>
922      complex<double>& operator*=(const complex<_Tp>&);
923    template<typename _Tp>
924      complex<double>& operator/=(const complex<_Tp>&);
925
926  private:
927    typedef __complex__ double _ComplexT;
928    _ComplexT _M_value;
929
930    complex(_ComplexT __z) : _M_value(__z) { }
931       
932    friend class complex<float>;
933    friend class complex<long double>;
934  };
935
936  inline double&
937  complex<double>::real()
938  { return __real__ _M_value; }
939
940  inline const double&
941  complex<double>::real() const
942  { return __real__ _M_value; }
943
944  inline double&
945  complex<double>::imag()
946  { return __imag__ _M_value; }
947
948  inline const double&
949  complex<double>::imag() const
950  { return __imag__ _M_value; }
951
952  inline
953  complex<double>::complex(double __r, double __i)
954  {
955    __real__ _M_value = __r;
956    __imag__ _M_value = __i;
957  }
958
959  inline complex<double>&
960  complex<double>::operator=(double __d)
961  {
962    __real__ _M_value = __d;
963    __imag__ _M_value = 0.0;
964    return *this;
965  }
966
967  inline complex<double>&
968  complex<double>::operator+=(double __d)
969  {
970    __real__ _M_value += __d;
971    return *this;
972  }
973
974  inline complex<double>&
975  complex<double>::operator-=(double __d)
976  {
977    __real__ _M_value -= __d;
978    return *this;
979  }
980
981  inline complex<double>&
982  complex<double>::operator*=(double __d)
983  {
984    _M_value *= __d;
985    return *this;
986  }
987
988  inline complex<double>&
989  complex<double>::operator/=(double __d)
990  {
991    _M_value /= __d;
992    return *this;
993  }
994
995  template<typename _Tp>
996    inline complex<double>&
997    complex<double>::operator=(const complex<_Tp>& __z)
998    {
999      __real__ _M_value = __z.real();
1000      __imag__ _M_value = __z.imag();
1001      return *this;
1002    }
1003   
1004  template<typename _Tp>
1005    inline complex<double>&
1006    complex<double>::operator+=(const complex<_Tp>& __z)
1007    {
1008      __real__ _M_value += __z.real();
1009      __imag__ _M_value += __z.imag();
1010      return *this;
1011    }
1012
1013  template<typename _Tp>
1014    inline complex<double>&
1015    complex<double>::operator-=(const complex<_Tp>& __z)
1016    {
1017      __real__ _M_value -= __z.real();
1018      __imag__ _M_value -= __z.imag();
1019      return *this;
1020    }
1021
1022  template<typename _Tp>
1023    inline complex<double>&
1024    complex<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  template<typename _Tp>
1034    inline complex<double>&
1035    complex<double>::operator/=(const complex<_Tp>& __z)
1036    {
1037      _ComplexT __t;
1038      __real__ __t = __z.real();
1039      __imag__ __t = __z.imag();
1040      _M_value /= __t;
1041      return *this;
1042    }
1043
1044  // 26.2.3  complex specializations
1045  // complex<long double> specialization
1046  template<> class complex<long double>
1047  {
1048  public:
1049    typedef long double value_type;
1050
1051    complex(long double = 0.0L, long double = 0.0L);
1052#ifdef _GLIBCXX_BUGGY_COMPLEX
1053    complex(const complex& __z) : _M_value(__z._M_value) { }
1054#endif
1055    complex(const complex<float>&);
1056    complex(const complex<double>&);
1057
1058    long double& real();
1059    const long double& real() const;
1060    long double& imag();
1061    const long double& imag() const;
1062
1063    complex<long double>& operator= (long double);
1064    complex<long double>& operator+= (long double);
1065    complex<long double>& operator-= (long double);
1066    complex<long double>& operator*= (long double);
1067    complex<long double>& operator/= (long double);
1068
1069    // The compiler knows how to do this efficiently
1070    // complex& operator= (const complex&);
1071    template<typename _Tp>
1072      complex<long double>& operator=(const complex<_Tp>&);
1073    template<typename _Tp>
1074      complex<long double>& operator+=(const complex<_Tp>&);
1075    template<typename _Tp>
1076      complex<long double>& operator-=(const complex<_Tp>&);
1077    template<typename _Tp>
1078      complex<long double>& operator*=(const complex<_Tp>&);
1079    template<typename _Tp>
1080      complex<long double>& operator/=(const complex<_Tp>&);
1081
1082  private:
1083    typedef __complex__ long double _ComplexT;
1084    _ComplexT _M_value;
1085
1086    complex(_ComplexT __z) : _M_value(__z) { }
1087
1088    friend class complex<float>;
1089    friend class complex<double>;
1090  };
1091
1092  inline
1093  complex<long double>::complex(long double __r, long double __i)
1094  {
1095    __real__ _M_value = __r;
1096    __imag__ _M_value = __i;
1097  }
1098
1099  inline long double&
1100  complex<long double>::real()
1101  { return __real__ _M_value; }
1102
1103  inline const long double&
1104  complex<long double>::real() const
1105  { return __real__ _M_value; }
1106
1107  inline long double&
1108  complex<long double>::imag()
1109  { return __imag__ _M_value; }
1110
1111  inline const long double&
1112  complex<long double>::imag() const
1113  { return __imag__ _M_value; }
1114
1115  inline complex<long double>&   
1116  complex<long double>::operator=(long double __r)
1117  {
1118    __real__ _M_value = __r;
1119    __imag__ _M_value = 0.0L;
1120    return *this;
1121  }
1122
1123  inline complex<long double>&
1124  complex<long double>::operator+=(long double __r)
1125  {
1126    __real__ _M_value += __r;
1127    return *this;
1128  }
1129
1130  inline complex<long double>&
1131  complex<long double>::operator-=(long double __r)
1132  {
1133    __real__ _M_value -= __r;
1134    return *this;
1135  }
1136
1137  inline complex<long double>&
1138  complex<long double>::operator*=(long double __r)
1139  {
1140    _M_value *= __r;
1141    return *this;
1142  }
1143
1144  inline complex<long double>&
1145  complex<long double>::operator/=(long double __r)
1146  {
1147    _M_value /= __r;
1148    return *this;
1149  }
1150
1151  template<typename _Tp>
1152    inline complex<long double>&
1153    complex<long double>::operator=(const complex<_Tp>& __z)
1154    {
1155      __real__ _M_value = __z.real();
1156      __imag__ _M_value = __z.imag();
1157      return *this;
1158    }
1159
1160  template<typename _Tp>
1161    inline complex<long double>&
1162    complex<long double>::operator+=(const complex<_Tp>& __z)
1163    {
1164      __real__ _M_value += __z.real();
1165      __imag__ _M_value += __z.imag();
1166      return *this;
1167    }
1168
1169  template<typename _Tp>
1170    inline complex<long double>&
1171    complex<long double>::operator-=(const complex<_Tp>& __z)
1172    {
1173      __real__ _M_value -= __z.real();
1174      __imag__ _M_value -= __z.imag();
1175      return *this;
1176    }
1177   
1178  template<typename _Tp>
1179    inline complex<long double>&
1180    complex<long double>::operator*=(const complex<_Tp>& __z)
1181    {
1182      _ComplexT __t;
1183      __real__ __t = __z.real();
1184      __imag__ __t = __z.imag();
1185      _M_value *= __t;
1186      return *this;
1187    }
1188
1189  template<typename _Tp>
1190    inline complex<long double>&
1191    complex<long double>::operator/=(const complex<_Tp>& __z)
1192    {
1193      _ComplexT __t;
1194      __real__ __t = __z.real();
1195      __imag__ __t = __z.imag();
1196      _M_value /= __t;
1197      return *this;
1198    }
1199
1200  // These bits have to be at the end of this file, so that the
1201  // specializations have all been defined.
1202  // ??? No, they have to be there because of compiler limitation at
1203  // inlining.  It suffices that class specializations be defined.
1204  inline
1205  complex<float>::complex(const complex<double>& __z)
1206  : _M_value(_ComplexT(__z._M_value)) { }
1207
1208  inline
1209  complex<float>::complex(const complex<long double>& __z)
1210  : _M_value(_ComplexT(__z._M_value)) { }
1211
1212  inline
1213  complex<double>::complex(const complex<float>& __z) 
1214  : _M_value(_ComplexT(__z._M_value)) { }
1215
1216  inline
1217  complex<double>::complex(const complex<long double>& __z)
1218  {
1219    __real__ _M_value = __z.real();
1220    __imag__ _M_value = __z.imag();
1221  }
1222
1223  inline
1224  complex<long double>::complex(const complex<float>& __z)
1225  : _M_value(_ComplexT(__z._M_value)) { }
1226
1227  inline
1228  complex<long double>::complex(const complex<double>& __z)
1229  : _M_value(_ComplexT(__z._M_value)) { }
1230} // namespace std
1231
1232#endif  /* _GLIBCXX_COMPLEX */
Note: See TracBrowser for help on using the repository browser.