williamr@2: /* williamr@2: * Copyright (c) 1999 williamr@2: * Silicon Graphics Computer Systems, Inc. williamr@2: * williamr@4: * Copyright (c) 1999 williamr@2: * Boris Fomitchev williamr@2: * williamr@2: * This material is provided "as is", with absolutely no warranty expressed williamr@2: * or implied. Any use is at your own risk. williamr@2: * williamr@4: * Permission to use or copy this software for any purpose is hereby granted williamr@2: * without fee, provided the above notices are retained on all copies. williamr@2: * Permission to modify the code and to distribute modified code is granted, williamr@2: * provided the above notices are retained, and a notice that the code was williamr@2: * modified is included with the above copyright notice. williamr@2: * williamr@4: */ williamr@2: #ifndef _STLP_COMPLEX_C williamr@2: #define _STLP_COMPLEX_C williamr@2: williamr@4: #ifndef _STLP_INTERNAL_COMPLEX williamr@2: # include williamr@4: #endif williamr@2: williamr@4: #if !defined (_STLP_USE_NO_IOSTREAMS) williamr@4: # ifndef _STLP_INTERNAL_ISTREAM williamr@4: # include williamr@4: # endif williamr@2: williamr@4: # ifndef _STLP_INTERNAL_SSTREAM williamr@4: # include williamr@4: # endif williamr@4: williamr@4: # ifndef _STLP_STRING_IO_H williamr@4: # include williamr@4: # endif williamr@2: #endif williamr@2: williamr@2: _STLP_BEGIN_NAMESPACE williamr@2: williamr@2: // Non-inline member functions. williamr@2: williamr@2: template williamr@2: void complex<_Tp>::_div(const _Tp& __z1_r, const _Tp& __z1_i, williamr@2: const _Tp& __z2_r, const _Tp& __z2_i, williamr@2: _Tp& __res_r, _Tp& __res_i) { williamr@2: _Tp __ar = __z2_r >= 0 ? __z2_r : -__z2_r; williamr@2: _Tp __ai = __z2_i >= 0 ? __z2_i : -__z2_i; williamr@2: williamr@2: if (__ar <= __ai) { williamr@2: _Tp __ratio = __z2_r / __z2_i; williamr@2: _Tp __denom = __z2_i * (1 + __ratio * __ratio); williamr@2: __res_r = (__z1_r * __ratio + __z1_i) / __denom; williamr@2: __res_i = (__z1_i * __ratio - __z1_r) / __denom; williamr@2: } williamr@2: else { williamr@2: _Tp __ratio = __z2_i / __z2_r; williamr@2: _Tp __denom = __z2_r * (1 + __ratio * __ratio); williamr@2: __res_r = (__z1_r + __z1_i * __ratio) / __denom; williamr@2: __res_i = (__z1_i - __z1_r * __ratio) / __denom; williamr@2: } williamr@2: } williamr@2: williamr@2: template williamr@2: void complex<_Tp>::_div(const _Tp& __z1_r, williamr@2: const _Tp& __z2_r, const _Tp& __z2_i, williamr@2: _Tp& __res_r, _Tp& __res_i) { williamr@2: _Tp __ar = __z2_r >= 0 ? __z2_r : -__z2_r; williamr@2: _Tp __ai = __z2_i >= 0 ? __z2_i : -__z2_i; williamr@2: williamr@2: if (__ar <= __ai) { williamr@2: _Tp __ratio = __z2_r / __z2_i; williamr@2: _Tp __denom = __z2_i * (1 + __ratio * __ratio); williamr@2: __res_r = (__z1_r * __ratio) / __denom; williamr@2: __res_i = - __z1_r / __denom; williamr@2: } williamr@2: else { williamr@2: _Tp __ratio = __z2_i / __z2_r; williamr@2: _Tp __denom = __z2_r * (1 + __ratio * __ratio); williamr@2: __res_r = __z1_r / __denom; williamr@2: __res_i = - (__z1_r * __ratio) / __denom; williamr@2: } williamr@2: } williamr@2: williamr@2: // I/O. williamr@4: #if !defined (_STLP_USE_NO_IOSTREAMS) williamr@2: williamr@4: // Complex output, in the form (re,im). We use a two-step process williamr@4: // involving stringstream so that we get the padding right. williamr@2: template williamr@2: basic_ostream<_CharT, _Traits>& _STLP_CALL williamr@4: operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __z) { williamr@2: basic_ostringstream<_CharT, _Traits, allocator<_CharT> > __tmp; williamr@2: __tmp.flags(__os.flags()); williamr@2: __tmp.imbue(__os.getloc()); williamr@2: __tmp.precision(__os.precision()); williamr@2: __tmp << '(' << __z.real() << ',' << __z.imag() << ')'; williamr@2: return __os << __tmp.str(); williamr@2: } williamr@2: williamr@2: // Complex input from arbitrary streams. Note that results in some williamr@2: // locales may be confusing, since the decimal character varies with williamr@2: // locale and the separator between real and imaginary parts does not. williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& _STLP_CALL williamr@4: operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __z) { williamr@2: _Tp __re = 0; williamr@2: _Tp __im = 0; williamr@2: williamr@2: // typedef ctype<_CharT> _Ctype; williamr@2: // locale __loc = __is.getloc(); williamr@2: //const _Ctype& __c_type = use_facet<_Ctype>(__loc); williamr@4: const ctype<_CharT>& __c_type = *__STATIC_CAST(const ctype<_CharT>*, __is._M_ctype_facet()); williamr@2: williamr@4: const char __punct[4] = "(,)"; williamr@2: _CharT __wpunct[3]; williamr@2: __c_type.widen(__punct, __punct + 3, __wpunct); williamr@2: williamr@2: _CharT __c; williamr@2: williamr@2: __is >> __c; williamr@2: if (_Traits::eq(__c, __wpunct[0])) { // Left paren williamr@2: __is >> __re >> __c; williamr@2: if (_Traits::eq(__c, __wpunct[1])) // Comma williamr@2: __is >> __im >> __c; williamr@2: if (!_Traits::eq(__c, __wpunct[2])) // Right paren williamr@2: __is.setstate(ios_base::failbit); williamr@2: } williamr@2: else { williamr@2: __is.putback(__c); williamr@2: __is >> __re; williamr@2: } williamr@2: williamr@2: if (__is) williamr@2: __z = complex<_Tp>(__re, __im); williamr@2: return __is; williamr@2: } williamr@2: williamr@4: #endif /* _STLP_USE_NO_IOSTREAMS */ williamr@2: williamr@2: _STLP_END_NAMESPACE williamr@2: williamr@2: #endif /* _STLP_COMPLEX_C */ williamr@4: williamr@4: // Local Variables: williamr@4: // mode:C++ williamr@4: // End: