home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / include / complex < prev    next >
Text File  |  1998-06-16  |  11KB  |  368 lines

  1. // complex standard header
  2.  
  3. #if     _MSC_VER > 1000
  4. #pragma once
  5. #endif
  6.  
  7. #ifndef _COMPLEX_
  8. #define _COMPLEX_
  9. #include <ymath.h>
  10. #include <cmath>
  11. #include <sstream>
  12. #include <xutility>
  13.  
  14. #ifdef  _MSC_VER
  15. #pragma pack(push,8)
  16. #endif  /* _MSC_VER */
  17. _STD_BEGIN
  18. #define __STD_COMPLEX
  19.         // TEMPLATE CLASS _Ctr
  20. template<class _Ty> class _Ctr {
  21. public:
  22.     static _Ty _Cosh(_Ty _X, _Ty _Y)
  23.         {return (::_Cosh((double)_X, (double)_Y)); }
  24.     static short _Exp(_Ty *_P, _Ty _Y, short _E)
  25.         {double _W = (double)*_P;
  26.         short _Ans = ::_Exp(&_W, (double)_Y, _E);
  27.         *_P = (_Ty)_W;
  28.         return (_Ans); }
  29.     static _Ty _Infv(_Ty)
  30.         {return (_Inf._D); }
  31.     static bool _Isinf(_Ty _X)
  32.         {double _W = (double)_X;
  33.         return (_Dtest(&_W) == _INFCODE); }
  34.     static bool _Isnan(_Ty _X)
  35.         {double _W = (double)_X;
  36.         return (_Dtest(&_W) == _NANCODE); }
  37.     static _Ty _Nanv(_Ty)
  38.         {return (_Nan._D); }
  39.     static _Ty _Sinh(_Ty _X, _Ty _Y)
  40.         {return (::_Sinh((double)_X, (double)_Y)); }
  41.     static _Ty atan2(_Ty _Y, _Ty _X)
  42.         {return (::atan2((double)_Y, (double)_X)); }
  43.     static _Ty cos(_Ty _X)
  44.         {return (::cos((double)_X)); }
  45.     static _Ty exp(_Ty _X)
  46.         {return (::exp((double)_X)); }
  47.     static _Ty ldexp(_Ty _R, int _E)
  48.         {return (::ldexp((double)_R, _E)); }
  49.     static _Ty log(_Ty _X)
  50.         {return (::log((double)_X)); }
  51.     static _Ty pow(_Ty _X, _Ty _Y)
  52.         {return (::pow((double)_X, (double)_Y)); }
  53.     static _Ty sin(_Ty _X)
  54.         {return (::sin((double)_X)); }
  55.     static _Ty sqrt(_Ty _X)
  56.         {return (::sqrt((double)_X)); }
  57.     };
  58.         // CLASS _Ctr<long double>
  59. class _CRTIMP _Ctr<long double> {
  60. public:
  61.     typedef long double _Ty;
  62.     static _Ty _Cosh(_Ty _X, _Ty _Y)
  63.         {return (_LCosh(_X, _Y)); }
  64.     static short _Exp(_Ty *_P, _Ty _Y, short _E)
  65.         {return (_LExp(_P, _Y, _E)); }
  66.     static _Ty _Infv(_Ty)
  67.         {return (_LInf._L); }
  68.     static bool _Isinf(_Ty _X)
  69.         {return (_LDtest(&_X) == _INFCODE); }
  70.     static bool _Isnan(_Ty _X)
  71.         {return (_LDtest(&_X) == _NANCODE); }
  72.     static _Ty _Nanv(_Ty)
  73.         {return (_LNan._L); }
  74.     static _Ty _Sinh(_Ty _X, _Ty _Y)
  75.         {return (_LSinh(_X, _Y)); }
  76.     static _Ty atan2(_Ty _Y, _Ty _X)
  77.         {return (atan2l(_Y, _X)); }
  78.     static _Ty cos(_Ty _X)
  79.         {return (cosl(_X)); }
  80.     static _Ty exp(_Ty _X)
  81.         {return (expl(_X)); }
  82.     static _Ty ldexp(_Ty _R, int _E)
  83.         {return (ldexpl(_R, _E)); }
  84.     static _Ty log(_Ty _X)
  85.         {return (logl(_X)); }
  86.     static _Ty pow(_Ty _X, _Ty _Y)
  87.         {return (powl(_X, _Y)); }
  88.     static _Ty sin(_Ty _X)
  89.         {return (sinl(_X)); }
  90.     static _Ty sqrt(_Ty _X)
  91.         {return (sqrtl(_X)); }
  92.     };
  93.         // CLASS _Ctr<double>
  94. class _CRTIMP _Ctr<double> {
  95. public:
  96.     typedef double _Ty;
  97.     static _Ty _Cosh(_Ty _X, _Ty _Y)
  98.         {return (::_Cosh(_X, _Y)); }
  99.     static short _Exp(_Ty *_P, _Ty _Y, short _E)
  100.         {return (::_Exp(_P, _Y, _E)); }
  101.     static _Ty _Infv(_Ty)
  102.         {return (_Inf._D); }
  103.     static bool _Isinf(_Ty _X)
  104.         {return (_Dtest(&_X) == _INFCODE); }
  105.     static bool _Isnan(_Ty _X)
  106.         {return (_Dtest(&_X) == _NANCODE); }
  107.     static _Ty _Nanv(_Ty)
  108.         {return (_Nan._D); }
  109.     static _Ty _Sinh(_Ty _X, _Ty _Y)
  110.         {return (::_Sinh(_X, _Y)); }
  111.     static _Ty atan2(_Ty _Y, _Ty _X)
  112.         {return (::atan2(_Y, _X)); }
  113.     static _Ty cos(_Ty _X)
  114.         {return (::cos(_X)); }
  115.     static _Ty exp(_Ty _X)
  116.         {return (::exp(_X)); }
  117.     static _Ty ldexp(_Ty _R, int _E)
  118.         {return (::ldexp(_R, _E)); }
  119.     static _Ty log(_Ty _X)
  120.         {return (::log(_X)); }
  121.     static _Ty pow(_Ty _X, _Ty _Y)
  122.         {return (::pow(_X, _Y)); }
  123.     static _Ty sin(_Ty _X)
  124.         {return (::sin(_X)); }
  125.     static _Ty sqrt(_Ty _X)
  126.         {return (::sqrt(_X)); }
  127.     };
  128. class _CRTIMP _Ctr<float> {
  129. public:
  130.     typedef float _Ty;
  131.     static _Ty _Cosh(_Ty _X, _Ty _Y)
  132.         {return (_FCosh(_X, _Y)); }
  133.     static short _Exp(_Ty *_P, _Ty _Y, short _E)
  134.         {return (_FExp(_P, _Y, _E)); }
  135.     static _Ty _Infv(_Ty)
  136.         {return (_FInf._F); }
  137.     static bool _Isinf(_Ty _X)
  138.         {return (_FDtest(&_X) == _INFCODE); }
  139.     static bool _Isnan(_Ty _X)
  140.         {return (_FDtest(&_X) == _NANCODE); }
  141.     static _Ty _Nanv(_Ty)
  142.         {return (_FNan._F); }
  143.     static _Ty _Sinh(_Ty _X, _Ty _Y)
  144.         {return (_FSinh(_X, _Y)); }
  145.     static _Ty atan2(_Ty _Y, _Ty _X)
  146.         {return (atan2f(_Y, _X)); }
  147.     static _Ty cos(_Ty _X)
  148.         {return (cosf(_X)); }
  149.     static _Ty exp(_Ty _X)
  150.         {return (expf(_X)); }
  151.     static _Ty ldexp(_Ty _R, int _E)
  152.         {return (ldexpf(_R, _E)); }
  153.     static _Ty log(_Ty _X)
  154.         {return (logf(_X)); }
  155.     static _Ty pow(_Ty _X, _Ty _Y)
  156.         {return (powf(_X, _Y)); }
  157.     static _Ty sin(_Ty _X)
  158.         {return (sinf(_X)); }
  159.     static _Ty sqrt(_Ty _X)
  160.         {return (sqrtf(_X)); }
  161.     };
  162.         // TEMPLATE CLASS _Complex_base
  163. template<class _Ty> class complex;
  164. class _CRTIMP complex<float>;
  165. class _CRTIMP complex<double>;
  166. class _CRTIMP complex<long double>;
  167. template<class _Ty>
  168.     class _Complex_base {
  169. public:
  170.     typedef _Complex_base<_Ty> _Myt;
  171.     typedef _Ctr<_Ty> _Myctr;
  172.     typedef _Ty value_type;
  173.     _Complex_base(const _Ty& _R, const _Ty& _I)
  174.         : _Re(_R), _Im(_I) {}
  175.     _Myt& operator+=(const _Ty& _X)
  176.         {_Re = _Re + _X;
  177.         return (*this); }
  178.     _Myt& operator-=(const _Ty& _X)
  179.         {_Re = _Re - _X;
  180.         return (*this); }
  181.     _Myt& operator*=(const _Ty& _X)
  182.         {_Re = _Re * _X;
  183.         _Im = _Im * _X;
  184.         return (*this); }
  185.     _Myt& operator/=(const _Ty& _X)
  186.         {_Re = _Re / _X;
  187.         _Im = _Im / _X;
  188.         return (*this); }
  189.     _Ty real(const _Ty& _X)
  190.         {return (_Re = _X); }
  191.     _Ty imag(const _Ty& _X)
  192.         {return (_Im = _X); }
  193.     _Ty real() const
  194.         {return (_Re); }
  195.     _Ty imag() const
  196.         {return (_Im); }
  197. protected:
  198.     _Ty _Re, _Im;
  199.     };
  200.  
  201.  
  202.         // CLASS complex<float>
  203. class _CRTIMP complex<float> : public _Complex_base<float> {
  204. public:
  205.     typedef float _Ty;
  206.     explicit complex(const complex<double>&);
  207.     explicit complex(const complex<long double>&);
  208.     complex(const _Ty& _R = 0, const _Ty& _I = 0)
  209.         : _Complex_base<_Ty>(_R, _I) {}
  210.     complex<_Ty>& operator=(const _Ty& _X)
  211.         {_Re = _X;
  212.         _Im = 0;
  213.         return (*this); }
  214.     };
  215.         // CLASS complex<double>
  216. class _CRTIMP complex<double> : public _Complex_base<double> {
  217. public:
  218.     typedef double _Ty;
  219.     complex(const complex<float>&);
  220.     explicit complex(const complex<long double>&);
  221.     complex(const _Ty& _R = 0, const _Ty& _I = 0)
  222.         : _Complex_base<_Ty>(_R, _I) {}
  223.     complex<_Ty>& operator=(const _Ty& _X)
  224.         {_Re = _X;
  225.         _Im = 0;
  226.         return (*this); }
  227.     };
  228.         // CLASS complex<long double>
  229. class _CRTIMP complex<long double> : public _Complex_base<long double> {
  230. public:
  231.     typedef long double _Ty;
  232.     complex(const complex<float>&);
  233.     complex(const complex<double>&);
  234.     complex(const _Ty& _R = 0, const _Ty& _I = 0)
  235.         : _Complex_base<_Ty>(_R, _I) {}
  236.     complex<_Ty>& operator=(const _Ty& _X)
  237.         {_Re = _X;
  238.         _Im = 0;
  239.         return (*this); }
  240.     };
  241.         // CONSTRUCTORS FOR complex SPECIALIZATIONS
  242. inline complex<float>::complex(const complex<double>& _X)
  243.     : _Complex_base<float>((_Ty)_X.real(), (_Ty)_X.imag()) {}
  244. inline complex<float>::complex(const complex<long double>& _X)
  245.     : _Complex_base<float>((_Ty)_X.real(), (_Ty)_X.imag()) {}
  246. inline complex<double>::complex(const complex<float>& _X)
  247.     : _Complex_base<double>((_Ty)_X.real(), (_Ty)_X.imag()) {}
  248. inline complex<double>::complex(const complex<long double>& _X)
  249.     : _Complex_base<double>((_Ty)_X.real(), (_Ty)_X.imag()) {}
  250. inline complex<long double>::complex(const complex<float>& _X)
  251.     : _Complex_base<long double>((_Ty)_X.real(), (_Ty)_X.imag()) {}
  252. inline complex<long double>::complex(const complex<double>& _X)
  253.     : _Complex_base<long double>((_Ty)_X.real(), (_Ty)_X.imag()) {}
  254.         // TEMPLATE CLASS complex
  255. template<class _Ty>
  256.     class complex : public _Complex_base<_Ty> {
  257. public:
  258.     complex(const _Ty& _R = 0, const _Ty& _I = 0)
  259.         : _Complex_base<_Ty>(_R, _I) {}
  260.     typedef _Ty _U;
  261.     complex(const complex<_U>& _X)
  262.         : _Complex_base<_Ty>((_Ty)_X.real(), (_Ty)_X.imag()) {}
  263.     complex<_Ty>& operator=(const complex<_U>& _X)
  264.         {_Re = (_Ty)_X.real();
  265.         _Im = (_Ty)_X.imag();
  266.         return (*this); }
  267.     };
  268.         // TEMPLATE complex OPERATORS
  269. template<class _Ty, class _U> inline
  270.     complex<_Ty>& __cdecl operator+=(
  271.     complex<_Ty>& _X,
  272.     const complex<_U>& _Y)
  273.     {_X.real(_X.real() + (_Ty)_Y.real());
  274.     _X.imag(_X.imag() + (_Ty)_Y.imag());
  275.     return (_X); }
  276. template<class _Ty, class _U> inline
  277.      complex<_Ty>& __cdecl operator-=(
  278.     complex<_Ty>& _X,
  279.     const complex<_U>& _Y)
  280.     {_X.real(_X.real() - (_Ty)_Y.real());
  281.     _X.imag(_X.imag() - (_Ty)_Y.imag());
  282.     return (_X); }
  283. template<class _Ty, class _U> inline
  284.      complex<_Ty>& __cdecl operator*=(
  285.     complex<_Ty>& _X,
  286.     const complex<_U>& _Y)
  287.     {_Ty _Yre = (_Ty)_Y.real();
  288.     _Ty _Yim = (_Ty)_Y.imag();
  289.     _Ty _W = _X.real() * _Yre - _X.imag() * _Yim;
  290.     _X.imag(_X.real() * _Yim + _X.imag() * _Yre);
  291.     _X.real(_W);
  292.     return (_X); }
  293. template<class _Ty, class _U> inline
  294.      complex<_Ty>& __cdecl operator/=(
  295.     complex<_Ty>& _X,
  296.     const complex<_U>& _Y)
  297.     {typedef _Ctr<_Ty> _Myctr;
  298.     _Ty _Yre = (_Ty)_Y.real();
  299.     _Ty _Yim = (_Ty)_Y.imag();
  300.     if (_Myctr::_Isnan(_Yre) || _Myctr::_Isnan(_Yim))
  301.         _X.real(_Myctr::_Nanv(_Yre)), _X.imag(_X.real());
  302.     else if ((_Yim < 0 ? -_Yim : +_Yim)
  303.         < (_Yre < 0 ? -_Yre : +_Yre))
  304.         {_Ty _Wr = _Yim / _Yre;
  305.         _Ty _Wd = _Yre + _Wr * _Yim;
  306.         if (_Myctr::_Isnan(_Wd) || _Wd == 0)
  307.             _X.real(_Myctr::_Nanv(_Yre)), _X.imag(_X.real());
  308.         else
  309.             {_Ty _W = (_X.real() + _X.imag() * _Wr) / _Wd;
  310.             _X.imag((_X.imag() - _X.real() * _Wr) / _Wd);
  311.             _X.real(_W); }}
  312.     else if (_Yim == 0)
  313.         _X.real(_Myctr::_Nanv(_Yre)), _X.imag(_X.real());
  314.     else
  315.         {_Ty _Wr = _Yre / _Yim;
  316.         _Ty _Wd = _Yim + _Wr * _Yre;
  317.         if (_Myctr::_Isnan(_Wd) || _Wd == 0)
  318.             _X.real(_Myctr::_Nanv(_Yre)), _X.imag(_X.real());
  319.         else
  320.             {_Ty _W = (_X.real() * _Wr + _X.imag()) / _Wd;
  321.             _X.imag((_X.imag() * _Wr - _X.real()) / _Wd);
  322.             _X.real(_W); }}
  323.     return (_X); }
  324.         // TEMPLATE FUNCTION operator>>
  325. template<class _E, class _Tr, class _U> inline
  326.     basic_istream<_E, _Tr>& __cdecl operator>>(
  327.         basic_istream<_E, _Tr>& _I, complex<_U>& _X)
  328.     {typedef complex<_U> _Myt;
  329.     _E _Ch;
  330.     long double _Re, _Im;
  331.     if (_I >> _Ch && _Ch != '(')
  332.         _I.putback(_Ch), _I >> _Re, _Im = 0;
  333.     else if (_I >> _Re >> _Ch && _Ch != ',')
  334.         if (_Ch == ')')
  335.             _Im = 0;
  336.         else
  337.             _I.putback(_Ch), _I.setstate(ios_base::failbit);
  338.     else if (_I >> _Im >> _Ch && _Ch != ')')
  339.             _I.putback(_Ch), _I.setstate(ios_base::failbit);
  340.     if (!_I.fail())
  341.         _X = _Myt((_U)_Re, (_U)_Im);
  342.     return (_I); }
  343.         // TEMPLATE FUNCTION operator<<
  344. template<class _E, class _Tr, class _U> inline
  345.     basic_ostream<_E, _Tr>& __cdecl operator<<(
  346.         basic_ostream<_E, _Tr>& _O, const complex<_U>& _X)
  347.     {basic_ostringstream<_E, _Tr, allocator<_E> > _S;
  348.     _S.flags(_O.flags());
  349.     _S.imbue(_O.getloc());
  350.     _S.precision(_O.precision());
  351.     _S << '(' << real(_X) << ',' << imag(_X) << ')';
  352.     return (_O << _S.str().c_str()); }
  353.  #define _CMPLX(T)    complex<T >
  354.  #define _CTR(T)    _Ctr<T >
  355.  #define _TMPLT(T)    template<class T >
  356.  #include <xcomplex>
  357. _STD_END
  358. #ifdef  _MSC_VER
  359. #pragma pack(pop)
  360. #endif  /* _MSC_VER */
  361.  
  362. #endif /* _COMPLEX_ */
  363.  
  364. /*
  365.  * Copyright (c) 1994 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  366.  * Consult your license regarding permissions and restrictions.
  367.  */
  368.