diff options
Diffstat (limited to 'libstdc++-v3/include/tr1')
62 files changed, 23104 insertions, 0 deletions
diff --git a/libstdc++-v3/include/tr1/array b/libstdc++-v3/include/tr1/array new file mode 100644 index 000000000..058fcfad6 --- /dev/null +++ b/libstdc++-v3/include/tr1/array @@ -0,0 +1,252 @@ +// class template array -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/array + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_ARRAY +#define _GLIBCXX_TR1_ARRAY 1 + +#pragma GCC system_header + +#include <bits/stl_algobase.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief A standard container for storing a fixed size sequence of elements. + * + * @ingroup sequences + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and a + * <a href="tables.html#67">sequence</a>. + * + * Sets support random access iterators. + * + * @param Tp Type of element. Required to be a complete type. + * @param N Number of elements. + */ + template<typename _Tp, std::size_t _Nm> + struct array + { + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // Support for zero-sized arrays mandatory. + value_type _M_instance[_Nm ? _Nm : 1]; + + // No explicit construct/copy/destroy for aggregate type. + + void + assign(const value_type& __u) + { std::fill_n(begin(), size(), __u); } + + void + swap(array& __other) + { std::swap_ranges(begin(), end(), __other.begin()); } + + // Iterators. + iterator + begin() + { return iterator(std::__addressof(_M_instance[0])); } + + const_iterator + begin() const + { return const_iterator(std::__addressof(_M_instance[0])); } + + iterator + end() + { return iterator(std::__addressof(_M_instance[_Nm])); } + + const_iterator + end() const + { return const_iterator(std::__addressof(_M_instance[_Nm])); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // Capacity. + size_type + size() const { return _Nm; } + + size_type + max_size() const { return _Nm; } + + bool + empty() const { return size() == 0; } + + // Element access. + reference + operator[](size_type __n) + { return _M_instance[__n]; } + + const_reference + operator[](size_type __n) const + { return _M_instance[__n]; } + + reference + at(size_type __n) + { + if (__n >= _Nm) + std::__throw_out_of_range(__N("array::at")); + return _M_instance[__n]; + } + + const_reference + at(size_type __n) const + { + if (__n >= _Nm) + std::__throw_out_of_range(__N("array::at")); + return _M_instance[__n]; + } + + reference + front() + { return *begin(); } + + const_reference + front() const + { return *begin(); } + + reference + back() + { return _Nm ? *(end() - 1) : *end(); } + + const_reference + back() const + { return _Nm ? *(end() - 1) : *end(); } + + _Tp* + data() + { return std::__addressof(_M_instance[0]); } + + const _Tp* + data() const + { return std::__addressof(_M_instance[0]); } + }; + + // Array comparisons. + template<typename _Tp, std::size_t _Nm> + inline bool + operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return std::equal(__one.begin(), __one.end(), __two.begin()); } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return !(__one == __two); } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) + { + return std::lexicographical_compare(__a.begin(), __a.end(), + __b.begin(), __b.end()); + } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return __two < __one; } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return !(__one > __two); } + + template<typename _Tp, std::size_t _Nm> + inline bool + operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) + { return !(__one < __two); } + + // Specialized algorithms [6.2.2.2]. + template<typename _Tp, std::size_t _Nm> + inline void + swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) + { __one.swap(__two); } + + // Tuple interface to class template array [6.2.2.5]. + + /// tuple_size + template<typename _Tp> + class tuple_size; + + /// tuple_element + template<int _Int, typename _Tp> + class tuple_element; + + template<typename _Tp, std::size_t _Nm> + struct tuple_size<array<_Tp, _Nm> > + { static const int value = _Nm; }; + + template<typename _Tp, std::size_t _Nm> + const int + tuple_size<array<_Tp, _Nm> >::value; + + template<int _Int, typename _Tp, std::size_t _Nm> + struct tuple_element<_Int, array<_Tp, _Nm> > + { typedef _Tp type; }; + + template<int _Int, typename _Tp, std::size_t _Nm> + inline _Tp& + get(array<_Tp, _Nm>& __arr) + { return __arr[_Int]; } + + template<int _Int, typename _Tp, std::size_t _Nm> + inline const _Tp& + get(const array<_Tp, _Nm>& __arr) + { return __arr[_Int]; } + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_ARRAY diff --git a/libstdc++-v3/include/tr1/bessel_function.tcc b/libstdc++-v3/include/tr1/bessel_function.tcc new file mode 100644 index 000000000..b525ebc10 --- /dev/null +++ b/libstdc++-v3/include/tr1/bessel_function.tcc @@ -0,0 +1,628 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/bessel_function.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland. +// +// References: +// (1) Handbook of Mathematical Functions, +// ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, +// Section 9, pp. 355-434, Section 10 pp. 435-478 +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky, +// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992), +// 2nd ed, pp. 240-245 + +#ifndef _GLIBCXX_TR1_BESSEL_FUNCTION_TCC +#define _GLIBCXX_TR1_BESSEL_FUNCTION_TCC 1 + +#include "special_function_util.h" + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Compute the gamma functions required by the Temme series + * expansions of @f$ N_\nu(x) @f$ and @f$ K_\nu(x) @f$. + * @f[ + * \Gamma_1 = \frac{1}{2\mu} + * [\frac{1}{\Gamma(1 - \mu)} - \frac{1}{\Gamma(1 + \mu)}] + * @f] + * and + * @f[ + * \Gamma_2 = \frac{1}{2} + * [\frac{1}{\Gamma(1 - \mu)} + \frac{1}{\Gamma(1 + \mu)}] + * @f] + * where @f$ -1/2 <= \mu <= 1/2 @f$ is @f$ \mu = \nu - N @f$ and @f$ N @f$. + * is the nearest integer to @f$ \nu @f$. + * The values of \f$ \Gamma(1 + \mu) \f$ and \f$ \Gamma(1 - \mu) \f$ + * are returned as well. + * + * The accuracy requirements on this are exquisite. + * + * @param __mu The input parameter of the gamma functions. + * @param __gam1 The output function \f$ \Gamma_1(\mu) \f$ + * @param __gam2 The output function \f$ \Gamma_2(\mu) \f$ + * @param __gampl The output function \f$ \Gamma(1 + \mu) \f$ + * @param __gammi The output function \f$ \Gamma(1 - \mu) \f$ + */ + template <typename _Tp> + void + __gamma_temme(const _Tp __mu, + _Tp & __gam1, _Tp & __gam2, _Tp & __gampl, _Tp & __gammi) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + __gampl = _Tp(1) / std::tr1::tgamma(_Tp(1) + __mu); + __gammi = _Tp(1) / std::tr1::tgamma(_Tp(1) - __mu); +#else + __gampl = _Tp(1) / __gamma(_Tp(1) + __mu); + __gammi = _Tp(1) / __gamma(_Tp(1) - __mu); +#endif + + if (std::abs(__mu) < std::numeric_limits<_Tp>::epsilon()) + __gam1 = -_Tp(__numeric_constants<_Tp>::__gamma_e()); + else + __gam1 = (__gammi - __gampl) / (_Tp(2) * __mu); + + __gam2 = (__gammi + __gampl) / (_Tp(2)); + + return; + } + + + /** + * @brief Compute the Bessel @f$ J_\nu(x) @f$ and Neumann + * @f$ N_\nu(x) @f$ functions and their first derivatives + * @f$ J'_\nu(x) @f$ and @f$ N'_\nu(x) @f$ respectively. + * These four functions are computed together for numerical + * stability. + * + * @param __nu The order of the Bessel functions. + * @param __x The argument of the Bessel functions. + * @param __Jnu The output Bessel function of the first kind. + * @param __Nnu The output Neumann function (Bessel function of the second kind). + * @param __Jpnu The output derivative of the Bessel function of the first kind. + * @param __Npnu The output derivative of the Neumann function. + */ + template <typename _Tp> + void + __bessel_jn(const _Tp __nu, const _Tp __x, + _Tp & __Jnu, _Tp & __Nnu, _Tp & __Jpnu, _Tp & __Npnu) + { + if (__x == _Tp(0)) + { + if (__nu == _Tp(0)) + { + __Jnu = _Tp(1); + __Jpnu = _Tp(0); + } + else if (__nu == _Tp(1)) + { + __Jnu = _Tp(0); + __Jpnu = _Tp(0.5L); + } + else + { + __Jnu = _Tp(0); + __Jpnu = _Tp(0); + } + __Nnu = -std::numeric_limits<_Tp>::infinity(); + __Npnu = std::numeric_limits<_Tp>::infinity(); + return; + } + + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + // When the multiplier is N i.e. + // fp_min = N * min() + // Then J_0 and N_0 tank at x = 8 * N (J_0 = 0 and N_0 = nan)! + //const _Tp __fp_min = _Tp(20) * std::numeric_limits<_Tp>::min(); + const _Tp __fp_min = std::sqrt(std::numeric_limits<_Tp>::min()); + const int __max_iter = 15000; + const _Tp __x_min = _Tp(2); + + const int __nl = (__x < __x_min + ? static_cast<int>(__nu + _Tp(0.5L)) + : std::max(0, static_cast<int>(__nu - __x + _Tp(1.5L)))); + + const _Tp __mu = __nu - __nl; + const _Tp __mu2 = __mu * __mu; + const _Tp __xi = _Tp(1) / __x; + const _Tp __xi2 = _Tp(2) * __xi; + _Tp __w = __xi2 / __numeric_constants<_Tp>::__pi(); + int __isign = 1; + _Tp __h = __nu * __xi; + if (__h < __fp_min) + __h = __fp_min; + _Tp __b = __xi2 * __nu; + _Tp __d = _Tp(0); + _Tp __c = __h; + int __i; + for (__i = 1; __i <= __max_iter; ++__i) + { + __b += __xi2; + __d = __b - __d; + if (std::abs(__d) < __fp_min) + __d = __fp_min; + __c = __b - _Tp(1) / __c; + if (std::abs(__c) < __fp_min) + __c = __fp_min; + __d = _Tp(1) / __d; + const _Tp __del = __c * __d; + __h *= __del; + if (__d < _Tp(0)) + __isign = -__isign; + if (std::abs(__del - _Tp(1)) < __eps) + break; + } + if (__i > __max_iter) + std::__throw_runtime_error(__N("Argument x too large in __bessel_jn; " + "try asymptotic expansion.")); + _Tp __Jnul = __isign * __fp_min; + _Tp __Jpnul = __h * __Jnul; + _Tp __Jnul1 = __Jnul; + _Tp __Jpnu1 = __Jpnul; + _Tp __fact = __nu * __xi; + for ( int __l = __nl; __l >= 1; --__l ) + { + const _Tp __Jnutemp = __fact * __Jnul + __Jpnul; + __fact -= __xi; + __Jpnul = __fact * __Jnutemp - __Jnul; + __Jnul = __Jnutemp; + } + if (__Jnul == _Tp(0)) + __Jnul = __eps; + _Tp __f= __Jpnul / __Jnul; + _Tp __Nmu, __Nnu1, __Npmu, __Jmu; + if (__x < __x_min) + { + const _Tp __x2 = __x / _Tp(2); + const _Tp __pimu = __numeric_constants<_Tp>::__pi() * __mu; + _Tp __fact = (std::abs(__pimu) < __eps + ? _Tp(1) : __pimu / std::sin(__pimu)); + _Tp __d = -std::log(__x2); + _Tp __e = __mu * __d; + _Tp __fact2 = (std::abs(__e) < __eps + ? _Tp(1) : std::sinh(__e) / __e); + _Tp __gam1, __gam2, __gampl, __gammi; + __gamma_temme(__mu, __gam1, __gam2, __gampl, __gammi); + _Tp __ff = (_Tp(2) / __numeric_constants<_Tp>::__pi()) + * __fact * (__gam1 * std::cosh(__e) + __gam2 * __fact2 * __d); + __e = std::exp(__e); + _Tp __p = __e / (__numeric_constants<_Tp>::__pi() * __gampl); + _Tp __q = _Tp(1) / (__e * __numeric_constants<_Tp>::__pi() * __gammi); + const _Tp __pimu2 = __pimu / _Tp(2); + _Tp __fact3 = (std::abs(__pimu2) < __eps + ? _Tp(1) : std::sin(__pimu2) / __pimu2 ); + _Tp __r = __numeric_constants<_Tp>::__pi() * __pimu2 * __fact3 * __fact3; + _Tp __c = _Tp(1); + __d = -__x2 * __x2; + _Tp __sum = __ff + __r * __q; + _Tp __sum1 = __p; + for (__i = 1; __i <= __max_iter; ++__i) + { + __ff = (__i * __ff + __p + __q) / (__i * __i - __mu2); + __c *= __d / _Tp(__i); + __p /= _Tp(__i) - __mu; + __q /= _Tp(__i) + __mu; + const _Tp __del = __c * (__ff + __r * __q); + __sum += __del; + const _Tp __del1 = __c * __p - __i * __del; + __sum1 += __del1; + if ( std::abs(__del) < __eps * (_Tp(1) + std::abs(__sum)) ) + break; + } + if ( __i > __max_iter ) + std::__throw_runtime_error(__N("Bessel y series failed to converge " + "in __bessel_jn.")); + __Nmu = -__sum; + __Nnu1 = -__sum1 * __xi2; + __Npmu = __mu * __xi * __Nmu - __Nnu1; + __Jmu = __w / (__Npmu - __f * __Nmu); + } + else + { + _Tp __a = _Tp(0.25L) - __mu2; + _Tp __q = _Tp(1); + _Tp __p = -__xi / _Tp(2); + _Tp __br = _Tp(2) * __x; + _Tp __bi = _Tp(2); + _Tp __fact = __a * __xi / (__p * __p + __q * __q); + _Tp __cr = __br + __q * __fact; + _Tp __ci = __bi + __p * __fact; + _Tp __den = __br * __br + __bi * __bi; + _Tp __dr = __br / __den; + _Tp __di = -__bi / __den; + _Tp __dlr = __cr * __dr - __ci * __di; + _Tp __dli = __cr * __di + __ci * __dr; + _Tp __temp = __p * __dlr - __q * __dli; + __q = __p * __dli + __q * __dlr; + __p = __temp; + int __i; + for (__i = 2; __i <= __max_iter; ++__i) + { + __a += _Tp(2 * (__i - 1)); + __bi += _Tp(2); + __dr = __a * __dr + __br; + __di = __a * __di + __bi; + if (std::abs(__dr) + std::abs(__di) < __fp_min) + __dr = __fp_min; + __fact = __a / (__cr * __cr + __ci * __ci); + __cr = __br + __cr * __fact; + __ci = __bi - __ci * __fact; + if (std::abs(__cr) + std::abs(__ci) < __fp_min) + __cr = __fp_min; + __den = __dr * __dr + __di * __di; + __dr /= __den; + __di /= -__den; + __dlr = __cr * __dr - __ci * __di; + __dli = __cr * __di + __ci * __dr; + __temp = __p * __dlr - __q * __dli; + __q = __p * __dli + __q * __dlr; + __p = __temp; + if (std::abs(__dlr - _Tp(1)) + std::abs(__dli) < __eps) + break; + } + if (__i > __max_iter) + std::__throw_runtime_error(__N("Lentz's method failed " + "in __bessel_jn.")); + const _Tp __gam = (__p - __f) / __q; + __Jmu = std::sqrt(__w / ((__p - __f) * __gam + __q)); +#if _GLIBCXX_USE_C99_MATH_TR1 + __Jmu = std::tr1::copysign(__Jmu, __Jnul); +#else + if (__Jmu * __Jnul < _Tp(0)) + __Jmu = -__Jmu; +#endif + __Nmu = __gam * __Jmu; + __Npmu = (__p + __q / __gam) * __Nmu; + __Nnu1 = __mu * __xi * __Nmu - __Npmu; + } + __fact = __Jmu / __Jnul; + __Jnu = __fact * __Jnul1; + __Jpnu = __fact * __Jpnu1; + for (__i = 1; __i <= __nl; ++__i) + { + const _Tp __Nnutemp = (__mu + __i) * __xi2 * __Nnu1 - __Nmu; + __Nmu = __Nnu1; + __Nnu1 = __Nnutemp; + } + __Nnu = __Nmu; + __Npnu = __nu * __xi * __Nmu - __Nnu1; + + return; + } + + + /** + * @brief This routine computes the asymptotic cylindrical Bessel + * and Neumann functions of order nu: \f$ J_{\nu} \f$, + * \f$ N_{\nu} \f$. + * + * References: + * (1) Handbook of Mathematical Functions, + * ed. Milton Abramowitz and Irene A. Stegun, + * Dover Publications, + * Section 9 p. 364, Equations 9.2.5-9.2.10 + * + * @param __nu The order of the Bessel functions. + * @param __x The argument of the Bessel functions. + * @param __Jnu The output Bessel function of the first kind. + * @param __Nnu The output Neumann function (Bessel function of the second kind). + */ + template <typename _Tp> + void + __cyl_bessel_jn_asymp(const _Tp __nu, const _Tp __x, + _Tp & __Jnu, _Tp & __Nnu) + { + const _Tp __coef = std::sqrt(_Tp(2) + / (__numeric_constants<_Tp>::__pi() * __x)); + const _Tp __mu = _Tp(4) * __nu * __nu; + const _Tp __mum1 = __mu - _Tp(1); + const _Tp __mum9 = __mu - _Tp(9); + const _Tp __mum25 = __mu - _Tp(25); + const _Tp __mum49 = __mu - _Tp(49); + const _Tp __xx = _Tp(64) * __x * __x; + const _Tp __P = _Tp(1) - __mum1 * __mum9 / (_Tp(2) * __xx) + * (_Tp(1) - __mum25 * __mum49 / (_Tp(12) * __xx)); + const _Tp __Q = __mum1 / (_Tp(8) * __x) + * (_Tp(1) - __mum9 * __mum25 / (_Tp(6) * __xx)); + + const _Tp __chi = __x - (__nu + _Tp(0.5L)) + * __numeric_constants<_Tp>::__pi_2(); + const _Tp __c = std::cos(__chi); + const _Tp __s = std::sin(__chi); + + __Jnu = __coef * (__c * __P - __s * __Q); + __Nnu = __coef * (__s * __P + __c * __Q); + + return; + } + + + /** + * @brief This routine returns the cylindrical Bessel functions + * of order \f$ \nu \f$: \f$ J_{\nu} \f$ or \f$ I_{\nu} \f$ + * by series expansion. + * + * The modified cylindrical Bessel function is: + * @f[ + * Z_{\nu}(x) = \sum_{k=0}^{\infty} + * \frac{\sigma^k (x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)} + * @f] + * where \f$ \sigma = +1 \f$ or\f$ -1 \f$ for + * \f$ Z = I \f$ or \f$ J \f$ respectively. + * + * See Abramowitz & Stegun, 9.1.10 + * Abramowitz & Stegun, 9.6.7 + * (1) Handbook of Mathematical Functions, + * ed. Milton Abramowitz and Irene A. Stegun, + * Dover Publications, + * Equation 9.1.10 p. 360 and Equation 9.6.10 p. 375 + * + * @param __nu The order of the Bessel function. + * @param __x The argument of the Bessel function. + * @param __sgn The sign of the alternate terms + * -1 for the Bessel function of the first kind. + * +1 for the modified Bessel function of the first kind. + * @return The output Bessel function. + */ + template <typename _Tp> + _Tp + __cyl_bessel_ij_series(const _Tp __nu, const _Tp __x, const _Tp __sgn, + const unsigned int __max_iter) + { + + const _Tp __x2 = __x / _Tp(2); + _Tp __fact = __nu * std::log(__x2); +#if _GLIBCXX_USE_C99_MATH_TR1 + __fact -= std::tr1::lgamma(__nu + _Tp(1)); +#else + __fact -= __log_gamma(__nu + _Tp(1)); +#endif + __fact = std::exp(__fact); + const _Tp __xx4 = __sgn * __x2 * __x2; + _Tp __Jn = _Tp(1); + _Tp __term = _Tp(1); + + for (unsigned int __i = 1; __i < __max_iter; ++__i) + { + __term *= __xx4 / (_Tp(__i) * (__nu + _Tp(__i))); + __Jn += __term; + if (std::abs(__term / __Jn) < std::numeric_limits<_Tp>::epsilon()) + break; + } + + return __fact * __Jn; + } + + + /** + * @brief Return the Bessel function of order \f$ \nu \f$: + * \f$ J_{\nu}(x) \f$. + * + * The cylindrical Bessel function is: + * @f[ + * J_{\nu}(x) = \sum_{k=0}^{\infty} + * \frac{(-1)^k (x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)} + * @f] + * + * @param __nu The order of the Bessel function. + * @param __x The argument of the Bessel function. + * @return The output Bessel function. + */ + template<typename _Tp> + _Tp + __cyl_bessel_j(const _Tp __nu, const _Tp __x) + { + if (__nu < _Tp(0) || __x < _Tp(0)) + std::__throw_domain_error(__N("Bad argument " + "in __cyl_bessel_j.")); + else if (__isnan(__nu) || __isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x * __x < _Tp(10) * (__nu + _Tp(1))) + return __cyl_bessel_ij_series(__nu, __x, -_Tp(1), 200); + else if (__x > _Tp(1000)) + { + _Tp __J_nu, __N_nu; + __cyl_bessel_jn_asymp(__nu, __x, __J_nu, __N_nu); + return __J_nu; + } + else + { + _Tp __J_nu, __N_nu, __Jp_nu, __Np_nu; + __bessel_jn(__nu, __x, __J_nu, __N_nu, __Jp_nu, __Np_nu); + return __J_nu; + } + } + + + /** + * @brief Return the Neumann function of order \f$ \nu \f$: + * \f$ N_{\nu}(x) \f$. + * + * The Neumann function is defined by: + * @f[ + * N_{\nu}(x) = \frac{J_{\nu}(x) \cos \nu\pi - J_{-\nu}(x)} + * {\sin \nu\pi} + * @f] + * where for integral \f$ \nu = n \f$ a limit is taken: + * \f$ lim_{\nu \to n} \f$. + * + * @param __nu The order of the Neumann function. + * @param __x The argument of the Neumann function. + * @return The output Neumann function. + */ + template<typename _Tp> + _Tp + __cyl_neumann_n(const _Tp __nu, const _Tp __x) + { + if (__nu < _Tp(0) || __x < _Tp(0)) + std::__throw_domain_error(__N("Bad argument " + "in __cyl_neumann_n.")); + else if (__isnan(__nu) || __isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x > _Tp(1000)) + { + _Tp __J_nu, __N_nu; + __cyl_bessel_jn_asymp(__nu, __x, __J_nu, __N_nu); + return __N_nu; + } + else + { + _Tp __J_nu, __N_nu, __Jp_nu, __Np_nu; + __bessel_jn(__nu, __x, __J_nu, __N_nu, __Jp_nu, __Np_nu); + return __N_nu; + } + } + + + /** + * @brief Compute the spherical Bessel @f$ j_n(x) @f$ + * and Neumann @f$ n_n(x) @f$ functions and their first + * derivatives @f$ j'_n(x) @f$ and @f$ n'_n(x) @f$ + * respectively. + * + * @param __n The order of the spherical Bessel function. + * @param __x The argument of the spherical Bessel function. + * @param __j_n The output spherical Bessel function. + * @param __n_n The output spherical Neumann function. + * @param __jp_n The output derivative of the spherical Bessel function. + * @param __np_n The output derivative of the spherical Neumann function. + */ + template <typename _Tp> + void + __sph_bessel_jn(const unsigned int __n, const _Tp __x, + _Tp & __j_n, _Tp & __n_n, _Tp & __jp_n, _Tp & __np_n) + { + const _Tp __nu = _Tp(__n) + _Tp(0.5L); + + _Tp __J_nu, __N_nu, __Jp_nu, __Np_nu; + __bessel_jn(__nu, __x, __J_nu, __N_nu, __Jp_nu, __Np_nu); + + const _Tp __factor = __numeric_constants<_Tp>::__sqrtpio2() + / std::sqrt(__x); + + __j_n = __factor * __J_nu; + __n_n = __factor * __N_nu; + __jp_n = __factor * __Jp_nu - __j_n / (_Tp(2) * __x); + __np_n = __factor * __Np_nu - __n_n / (_Tp(2) * __x); + + return; + } + + + /** + * @brief Return the spherical Bessel function + * @f$ j_n(x) @f$ of order n. + * + * The spherical Bessel function is defined by: + * @f[ + * j_n(x) = \left( \frac{\pi}{2x} \right) ^{1/2} J_{n+1/2}(x) + * @f] + * + * @param __n The order of the spherical Bessel function. + * @param __x The argument of the spherical Bessel function. + * @return The output spherical Bessel function. + */ + template <typename _Tp> + _Tp + __sph_bessel(const unsigned int __n, const _Tp __x) + { + if (__x < _Tp(0)) + std::__throw_domain_error(__N("Bad argument " + "in __sph_bessel.")); + else if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x == _Tp(0)) + { + if (__n == 0) + return _Tp(1); + else + return _Tp(0); + } + else + { + _Tp __j_n, __n_n, __jp_n, __np_n; + __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n); + return __j_n; + } + } + + + /** + * @brief Return the spherical Neumann function + * @f$ n_n(x) @f$. + * + * The spherical Neumann function is defined by: + * @f[ + * n_n(x) = \left( \frac{\pi}{2x} \right) ^{1/2} N_{n+1/2}(x) + * @f] + * + * @param __n The order of the spherical Neumann function. + * @param __x The argument of the spherical Neumann function. + * @return The output spherical Neumann function. + */ + template <typename _Tp> + _Tp + __sph_neumann(const unsigned int __n, const _Tp __x) + { + if (__x < _Tp(0)) + std::__throw_domain_error(__N("Bad argument " + "in __sph_neumann.")); + else if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x == _Tp(0)) + return -std::numeric_limits<_Tp>::infinity(); + else + { + _Tp __j_n, __n_n, __jp_n, __np_n; + __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n); + return __n_n; + } + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_BESSEL_FUNCTION_TCC diff --git a/libstdc++-v3/include/tr1/beta_function.tcc b/libstdc++-v3/include/tr1/beta_function.tcc new file mode 100644 index 000000000..219f3cbd4 --- /dev/null +++ b/libstdc++-v3/include/tr1/beta_function.tcc @@ -0,0 +1,198 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/beta_function.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// (1) Handbook of Mathematical Functions, +// ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, +// Section 6, pp. 253-266 +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky, +// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992), +// 2nd ed, pp. 213-216 +// (4) Gamma, Exploring Euler's Constant, Julian Havil, +// Princeton, 2003. + +#ifndef _GLIBCXX_TR1_BETA_FUNCTION_TCC +#define _GLIBCXX_TR1_BETA_FUNCTION_TCC 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Return the beta function: \f$B(x,y)\f$. + * + * The beta function is defined by + * @f[ + * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} + * @f] + * + * @param __x The first argument of the beta function. + * @param __y The second argument of the beta function. + * @return The beta function. + */ + template<typename _Tp> + _Tp + __beta_gamma(_Tp __x, _Tp __y) + { + + _Tp __bet; +#if _GLIBCXX_USE_C99_MATH_TR1 + if (__x > __y) + { + __bet = std::tr1::tgamma(__x) + / std::tr1::tgamma(__x + __y); + __bet *= std::tr1::tgamma(__y); + } + else + { + __bet = std::tr1::tgamma(__y) + / std::tr1::tgamma(__x + __y); + __bet *= std::tr1::tgamma(__x); + } +#else + if (__x > __y) + { + __bet = __gamma(__x) / __gamma(__x + __y); + __bet *= __gamma(__y); + } + else + { + __bet = __gamma(__y) / __gamma(__x + __y); + __bet *= __gamma(__x); + } +#endif + + return __bet; + } + + /** + * @brief Return the beta function \f$B(x,y)\f$ using + * the log gamma functions. + * + * The beta function is defined by + * @f[ + * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} + * @f] + * + * @param __x The first argument of the beta function. + * @param __y The second argument of the beta function. + * @return The beta function. + */ + template<typename _Tp> + _Tp + __beta_lgamma(_Tp __x, _Tp __y) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + _Tp __bet = std::tr1::lgamma(__x) + + std::tr1::lgamma(__y) + - std::tr1::lgamma(__x + __y); +#else + _Tp __bet = __log_gamma(__x) + + __log_gamma(__y) + - __log_gamma(__x + __y); +#endif + __bet = std::exp(__bet); + return __bet; + } + + + /** + * @brief Return the beta function \f$B(x,y)\f$ using + * the product form. + * + * The beta function is defined by + * @f[ + * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} + * @f] + * + * @param __x The first argument of the beta function. + * @param __y The second argument of the beta function. + * @return The beta function. + */ + template<typename _Tp> + _Tp + __beta_product(_Tp __x, _Tp __y) + { + + _Tp __bet = (__x + __y) / (__x * __y); + + unsigned int __max_iter = 1000000; + for (unsigned int __k = 1; __k < __max_iter; ++__k) + { + _Tp __term = (_Tp(1) + (__x + __y) / __k) + / ((_Tp(1) + __x / __k) * (_Tp(1) + __y / __k)); + __bet *= __term; + } + + return __bet; + } + + + /** + * @brief Return the beta function \f$ B(x,y) \f$. + * + * The beta function is defined by + * @f[ + * B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)} + * @f] + * + * @param __x The first argument of the beta function. + * @param __y The second argument of the beta function. + * @return The beta function. + */ + template<typename _Tp> + inline _Tp + __beta(_Tp __x, _Tp __y) + { + if (__isnan(__x) || __isnan(__y)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else + return __beta_lgamma(__x, __y); + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // __GLIBCXX_TR1_BETA_FUNCTION_TCC diff --git a/libstdc++-v3/include/tr1/ccomplex b/libstdc++-v3/include/tr1/ccomplex new file mode 100644 index 000000000..a0ae33e0c --- /dev/null +++ b/libstdc++-v3/include/tr1/ccomplex @@ -0,0 +1,34 @@ +// TR1 ccomplex -*- C++ -*- + +// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/ccomplex + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CCOMPLEX +#define _GLIBCXX_TR1_CCOMPLEX 1 + +#include <tr1/complex> + +#endif // _GLIBCXX_TR1_CCOMPLEX diff --git a/libstdc++-v3/include/tr1/cctype b/libstdc++-v3/include/tr1/cctype new file mode 100644 index 000000000..0cec3d9f4 --- /dev/null +++ b/libstdc++-v3/include/tr1/cctype @@ -0,0 +1,49 @@ +// TR1 cctype -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cctype + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CCTYPE +#define _GLIBCXX_TR1_CCTYPE 1 + +#include <bits/c++config.h> +#include <cctype> + +#ifdef _GLIBCXX_USE_C99_CTYPE_TR1 + +#undef isblank + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + using ::isblank; +} +} + +#endif + +#endif // _GLIBCXX_TR1_CCTYPE diff --git a/libstdc++-v3/include/tr1/cfenv b/libstdc++-v3/include/tr1/cfenv new file mode 100644 index 000000000..980a06c38 --- /dev/null +++ b/libstdc++-v3/include/tr1/cfenv @@ -0,0 +1,81 @@ +// TR1 cfenv -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cfenv + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CFENV +#define _GLIBCXX_TR1_CFENV 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +#if _GLIBCXX_HAVE_FENV_H +# include <fenv.h> +#endif + +#ifdef _GLIBCXX_USE_C99_FENV_TR1 + +#undef feclearexcept +#undef fegetexceptflag +#undef feraiseexcept +#undef fesetexceptflag +#undef fetestexcept +#undef fegetround +#undef fesetround +#undef fegetenv +#undef feholdexcept +#undef fesetenv +#undef feupdateenv + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // types + using ::fenv_t; + using ::fexcept_t; + + // functions + using ::feclearexcept; + using ::fegetexceptflag; + using ::feraiseexcept; + using ::fesetexceptflag; + using ::fetestexcept; + + using ::fegetround; + using ::fesetround; + + using ::fegetenv; + using ::feholdexcept; + using ::fesetenv; + using ::feupdateenv; +} +} + +#endif // _GLIBCXX_USE_C99_FENV_TR1 + +#endif // _GLIBCXX_TR1_CFENV diff --git a/libstdc++-v3/include/tr1/cfloat b/libstdc++-v3/include/tr1/cfloat new file mode 100644 index 000000000..801cfc39e --- /dev/null +++ b/libstdc++-v3/include/tr1/cfloat @@ -0,0 +1,42 @@ +// TR1 cfloat -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cfloat + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CFLOAT +#define _GLIBCXX_TR1_CFLOAT 1 + +#include <cfloat> + +#ifndef DECIMAL_DIG +#define DECIMAL_DIG __DECIMAL_DIG__ +#endif + +#ifndef FLT_EVAL_METHOD +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ +#endif + +#endif //_GLIBCXX_TR1_CFLOAT diff --git a/libstdc++-v3/include/tr1/cinttypes b/libstdc++-v3/include/tr1/cinttypes new file mode 100644 index 000000000..f1ca29279 --- /dev/null +++ b/libstdc++-v3/include/tr1/cinttypes @@ -0,0 +1,84 @@ +// TR1 cinttypes -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cinttypes + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CINTTYPES +#define _GLIBCXX_TR1_CINTTYPES 1 + +#pragma GCC system_header + +#include <tr1/cstdint> + +// For 8.11.1/1 (see C99, Note 184) +#if _GLIBCXX_HAVE_INTTYPES_H +# ifndef __STDC_FORMAT_MACROS +# define _UNDEF__STDC_FORMAT_MACROS +# define __STDC_FORMAT_MACROS +# endif +# include <inttypes.h> +# ifdef _UNDEF__STDC_FORMAT_MACROS +# undef __STDC_FORMAT_MACROS +# undef _UNDEF__STDC_FORMAT_MACROS +# endif +#endif + +#ifdef _GLIBCXX_USE_C99_INTTYPES_TR1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // types + using ::imaxdiv_t; + + // functions + using ::imaxabs; + + // May collide with _Longlong abs(_Longlong), and is not described + // anywhere outside the synopsis. Likely, a defect. + // + // intmax_t abs(intmax_t) + + using ::imaxdiv; + + // Likewise, with lldiv_t div(_Longlong, _Longlong). + // + // imaxdiv_t div(intmax_t, intmax_t) + + using ::strtoimax; + using ::strtoumax; + +#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 + using ::wcstoimax; + using ::wcstoumax; +#endif +} +} + +#endif // _GLIBCXX_USE_C99_INTTYPES_TR1 + +#endif // _GLIBCXX_TR1_CINTTYPES diff --git a/libstdc++-v3/include/tr1/climits b/libstdc++-v3/include/tr1/climits new file mode 100644 index 000000000..91af96bae --- /dev/null +++ b/libstdc++-v3/include/tr1/climits @@ -0,0 +1,46 @@ +// TR1 climits -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/climits + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CLIMITS +#define _GLIBCXX_TR1_CLIMITS 1 + +#include <climits> + +#ifndef LLONG_MIN +#define LLONG_MIN (-__LONG_LONG_MAX__ - 1) +#endif + +#ifndef LLONG_MAX +#define LLONG_MAX __LONG_LONG_MAX__ +#endif + +#ifndef ULLONG_MAX +#define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1) +#endif + +#endif // _GLIBCXX_TR1_CLIMITS diff --git a/libstdc++-v3/include/tr1/cmath b/libstdc++-v3/include/tr1/cmath new file mode 100644 index 000000000..21bdee886 --- /dev/null +++ b/libstdc++-v3/include/tr1/cmath @@ -0,0 +1,1484 @@ +// TR1 cmath -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cmath + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CMATH +#define _GLIBCXX_TR1_CMATH 1 + +#pragma GCC system_header + +#include <cmath> + +#ifdef _GLIBCXX_USE_C99_MATH_TR1 + +#undef acosh +#undef acoshf +#undef acoshl +#undef asinh +#undef asinhf +#undef asinhl +#undef atanh +#undef atanhf +#undef atanhl +#undef cbrt +#undef cbrtf +#undef cbrtl +#undef copysign +#undef copysignf +#undef copysignl +#undef erf +#undef erff +#undef erfl +#undef erfc +#undef erfcf +#undef erfcl +#undef exp2 +#undef exp2f +#undef exp2l +#undef expm1 +#undef expm1f +#undef expm1l +#undef fdim +#undef fdimf +#undef fdiml +#undef fma +#undef fmaf +#undef fmal +#undef fmax +#undef fmaxf +#undef fmaxl +#undef fmin +#undef fminf +#undef fminl +#undef hypot +#undef hypotf +#undef hypotl +#undef ilogb +#undef ilogbf +#undef ilogbl +#undef lgamma +#undef lgammaf +#undef lgammal +#undef llrint +#undef llrintf +#undef llrintl +#undef llround +#undef llroundf +#undef llroundl +#undef log1p +#undef log1pf +#undef log1pl +#undef log2 +#undef log2f +#undef log2l +#undef logb +#undef logbf +#undef logbl +#undef lrint +#undef lrintf +#undef lrintl +#undef lround +#undef lroundf +#undef lroundl +#undef nan +#undef nanf +#undef nanl +#undef nearbyint +#undef nearbyintf +#undef nearbyintl +#undef nextafter +#undef nextafterf +#undef nextafterl +#undef nexttoward +#undef nexttowardf +#undef nexttowardl +#undef remainder +#undef remainderf +#undef remainderl +#undef remquo +#undef remquof +#undef remquol +#undef rint +#undef rintf +#undef rintl +#undef round +#undef roundf +#undef roundl +#undef scalbln +#undef scalblnf +#undef scalblnl +#undef scalbn +#undef scalbnf +#undef scalbnl +#undef tgamma +#undef tgammaf +#undef tgammal +#undef trunc +#undef truncf +#undef truncl + +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +#if _GLIBCXX_USE_C99_MATH_TR1 + + // types + using ::double_t; + using ::float_t; + + // functions + using ::acosh; + using ::acoshf; + using ::acoshl; + + using ::asinh; + using ::asinhf; + using ::asinhl; + + using ::atanh; + using ::atanhf; + using ::atanhl; + + using ::cbrt; + using ::cbrtf; + using ::cbrtl; + + using ::copysign; + using ::copysignf; + using ::copysignl; + + using ::erf; + using ::erff; + using ::erfl; + + using ::erfc; + using ::erfcf; + using ::erfcl; + + using ::exp2; + using ::exp2f; + using ::exp2l; + + using ::expm1; + using ::expm1f; + using ::expm1l; + + using ::fdim; + using ::fdimf; + using ::fdiml; + + using ::fma; + using ::fmaf; + using ::fmal; + + using ::fmax; + using ::fmaxf; + using ::fmaxl; + + using ::fmin; + using ::fminf; + using ::fminl; + + using ::hypot; + using ::hypotf; + using ::hypotl; + + using ::ilogb; + using ::ilogbf; + using ::ilogbl; + + using ::lgamma; + using ::lgammaf; + using ::lgammal; + + using ::llrint; + using ::llrintf; + using ::llrintl; + + using ::llround; + using ::llroundf; + using ::llroundl; + + using ::log1p; + using ::log1pf; + using ::log1pl; + + using ::log2; + using ::log2f; + using ::log2l; + + using ::logb; + using ::logbf; + using ::logbl; + + using ::lrint; + using ::lrintf; + using ::lrintl; + + using ::lround; + using ::lroundf; + using ::lroundl; + + using ::nan; + using ::nanf; + using ::nanl; + + using ::nearbyint; + using ::nearbyintf; + using ::nearbyintl; + + using ::nextafter; + using ::nextafterf; + using ::nextafterl; + + using ::nexttoward; + using ::nexttowardf; + using ::nexttowardl; + + using ::remainder; + using ::remainderf; + using ::remainderl; + + using ::remquo; + using ::remquof; + using ::remquol; + + using ::rint; + using ::rintf; + using ::rintl; + + using ::round; + using ::roundf; + using ::roundl; + + using ::scalbln; + using ::scalblnf; + using ::scalblnl; + + using ::scalbn; + using ::scalbnf; + using ::scalbnl; + + using ::tgamma; + using ::tgammaf; + using ::tgammal; + + using ::trunc; + using ::truncf; + using ::truncl; + +#endif + +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC + + /// Function template definitions [8.16.3]. + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + fpclassify(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, __type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isfinite(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isfinite(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isinf(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isinf(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isnan(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isnan(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isnormal(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isnormal(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + signbit(_Tp __f) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_signbit(__type(__f)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isgreater(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isgreater(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isgreaterequal(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isgreaterequal(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isless(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isless(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + islessequal(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_islessequal(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + islessgreater(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_islessgreater(__type(__f1), __type(__f2)); + } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, + int>::__type + isunordered(_Tp __f1, _Tp __f2) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __builtin_isunordered(__type(__f1), __type(__f2)); + } + +#endif +#endif + +#if _GLIBCXX_USE_C99_MATH_TR1 + + /// Additional overloads [8.16.4]. + using std::acos; + + inline float + acosh(float __x) + { return __builtin_acoshf(__x); } + + inline long double + acosh(long double __x) + { return __builtin_acoshl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + acosh(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return acosh(__type(__x)); + } + + using std::asin; + + inline float + asinh(float __x) + { return __builtin_asinhf(__x); } + + inline long double + asinh(long double __x) + { return __builtin_asinhl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + asinh(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return asinh(__type(__x)); + } + + using std::atan; + using std::atan2; + + inline float + atanh(float __x) + { return __builtin_atanhf(__x); } + + inline long double + atanh(long double __x) + { return __builtin_atanhl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + atanh(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return atanh(__type(__x)); + } + + inline float + cbrt(float __x) + { return __builtin_cbrtf(__x); } + + inline long double + cbrt(long double __x) + { return __builtin_cbrtl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + cbrt(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return cbrt(__type(__x)); + } + + using std::ceil; + + inline float + copysign(float __x, float __y) + { return __builtin_copysignf(__x, __y); } + + inline long double + copysign(long double __x, long double __y) + { return __builtin_copysignl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + copysign(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return copysign(__type(__x), __type(__y)); + } + + using std::cos; + using std::cosh; + + inline float + erf(float __x) + { return __builtin_erff(__x); } + + inline long double + erf(long double __x) + { return __builtin_erfl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + erf(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return erf(__type(__x)); + } + + inline float + erfc(float __x) + { return __builtin_erfcf(__x); } + + inline long double + erfc(long double __x) + { return __builtin_erfcl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + erfc(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return erfc(__type(__x)); + } + + using std::exp; + + inline float + exp2(float __x) + { return __builtin_exp2f(__x); } + + inline long double + exp2(long double __x) + { return __builtin_exp2l(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + exp2(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return exp2(__type(__x)); + } + + inline float + expm1(float __x) + { return __builtin_expm1f(__x); } + + inline long double + expm1(long double __x) + { return __builtin_expm1l(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + expm1(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return expm1(__type(__x)); + } + + // Note: we deal with fabs in a special way, because an using std::fabs + // would bring in also the overloads for complex types, which in C++0x + // mode have a different return type. + using ::fabs; + + inline float + fabs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + fabs(long double __x) + { return __builtin_fabsl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, + double>::__type + fabs(_Tp __x) + { return __builtin_fabs(__x); } + + inline float + fdim(float __x, float __y) + { return __builtin_fdimf(__x, __y); } + + inline long double + fdim(long double __x, long double __y) + { return __builtin_fdiml(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + fdim(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return fdim(__type(__x), __type(__y)); + } + + using std::floor; + + inline float + fma(float __x, float __y, float __z) + { return __builtin_fmaf(__x, __y, __z); } + + inline long double + fma(long double __x, long double __y, long double __z) + { return __builtin_fmal(__x, __y, __z); } + + template<typename _Tp, typename _Up, typename _Vp> + inline typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type + fma(_Tp __x, _Up __y, _Vp __z) + { + typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type; + return fma(__type(__x), __type(__y), __type(__z)); + } + + inline float + fmax(float __x, float __y) + { return __builtin_fmaxf(__x, __y); } + + inline long double + fmax(long double __x, long double __y) + { return __builtin_fmaxl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + fmax(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return fmax(__type(__x), __type(__y)); + } + + inline float + fmin(float __x, float __y) + { return __builtin_fminf(__x, __y); } + + inline long double + fmin(long double __x, long double __y) + { return __builtin_fminl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + fmin(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return fmin(__type(__x), __type(__y)); + } + + using std::fmod; + using std::frexp; + + inline float + hypot(float __x, float __y) + { return __builtin_hypotf(__x, __y); } + + inline long double + hypot(long double __x, long double __y) + { return __builtin_hypotl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + hypot(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return hypot(__type(__x), __type(__y)); + } + + inline int + ilogb(float __x) + { return __builtin_ilogbf(__x); } + + inline int + ilogb(long double __x) + { return __builtin_ilogbl(__x); } + + template<typename _Tp> + inline int + ilogb(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return ilogb(__type(__x)); + } + + using std::ldexp; + + inline float + lgamma(float __x) + { return __builtin_lgammaf(__x); } + + inline long double + lgamma(long double __x) + { return __builtin_lgammal(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + lgamma(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return lgamma(__type(__x)); + } + + inline long long + llrint(float __x) + { return __builtin_llrintf(__x); } + + inline long long + llrint(long double __x) + { return __builtin_llrintl(__x); } + + template<typename _Tp> + inline long long + llrint(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return llrint(__type(__x)); + } + + inline long long + llround(float __x) + { return __builtin_llroundf(__x); } + + inline long long + llround(long double __x) + { return __builtin_llroundl(__x); } + + template<typename _Tp> + inline long long + llround(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return llround(__type(__x)); + } + + using std::log; + using std::log10; + + inline float + log1p(float __x) + { return __builtin_log1pf(__x); } + + inline long double + log1p(long double __x) + { return __builtin_log1pl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + log1p(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return log1p(__type(__x)); + } + + // DR 568. + inline float + log2(float __x) + { return __builtin_log2f(__x); } + + inline long double + log2(long double __x) + { return __builtin_log2l(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + log2(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return log2(__type(__x)); + } + + inline float + logb(float __x) + { return __builtin_logbf(__x); } + + inline long double + logb(long double __x) + { return __builtin_logbl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + logb(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return logb(__type(__x)); + } + + inline long + lrint(float __x) + { return __builtin_lrintf(__x); } + + inline long + lrint(long double __x) + { return __builtin_lrintl(__x); } + + template<typename _Tp> + inline long + lrint(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return lrint(__type(__x)); + } + + inline long + lround(float __x) + { return __builtin_lroundf(__x); } + + inline long + lround(long double __x) + { return __builtin_lroundl(__x); } + + template<typename _Tp> + inline long + lround(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return lround(__type(__x)); + } + + inline float + nearbyint(float __x) + { return __builtin_nearbyintf(__x); } + + inline long double + nearbyint(long double __x) + { return __builtin_nearbyintl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + nearbyint(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return nearbyint(__type(__x)); + } + + inline float + nextafter(float __x, float __y) + { return __builtin_nextafterf(__x, __y); } + + inline long double + nextafter(long double __x, long double __y) + { return __builtin_nextafterl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + nextafter(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return nextafter(__type(__x), __type(__y)); + } + + inline float + nexttoward(float __x, long double __y) + { return __builtin_nexttowardf(__x, __y); } + + inline long double + nexttoward(long double __x, long double __y) + { return __builtin_nexttowardl(__x, __y); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + nexttoward(_Tp __x, long double __y) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return nexttoward(__type(__x), __y); + } + + // DR 550. What should the return type of pow(float,int) be? + // NB: C++0x and TR1 != C++03. + // using std::pow; + + inline float + remainder(float __x, float __y) + { return __builtin_remainderf(__x, __y); } + + inline long double + remainder(long double __x, long double __y) + { return __builtin_remainderl(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + remainder(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return remainder(__type(__x), __type(__y)); + } + + inline float + remquo(float __x, float __y, int* __pquo) + { return __builtin_remquof(__x, __y, __pquo); } + + inline long double + remquo(long double __x, long double __y, int* __pquo) + { return __builtin_remquol(__x, __y, __pquo); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + remquo(_Tp __x, _Up __y, int* __pquo) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return remquo(__type(__x), __type(__y), __pquo); + } + + inline float + rint(float __x) + { return __builtin_rintf(__x); } + + inline long double + rint(long double __x) + { return __builtin_rintl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + rint(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return rint(__type(__x)); + } + + inline float + round(float __x) + { return __builtin_roundf(__x); } + + inline long double + round(long double __x) + { return __builtin_roundl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + round(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return round(__type(__x)); + } + + inline float + scalbln(float __x, long __ex) + { return __builtin_scalblnf(__x, __ex); } + + inline long double + scalbln(long double __x, long __ex) + { return __builtin_scalblnl(__x, __ex); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + scalbln(_Tp __x, long __ex) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return scalbln(__type(__x), __ex); + } + + inline float + scalbn(float __x, int __ex) + { return __builtin_scalbnf(__x, __ex); } + + inline long double + scalbn(long double __x, int __ex) + { return __builtin_scalbnl(__x, __ex); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + scalbn(_Tp __x, int __ex) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return scalbn(__type(__x), __ex); + } + + using std::sin; + using std::sinh; + using std::sqrt; + using std::tan; + using std::tanh; + + inline float + tgamma(float __x) + { return __builtin_tgammaf(__x); } + + inline long double + tgamma(long double __x) + { return __builtin_tgammal(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + tgamma(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return tgamma(__type(__x)); + } + + inline float + trunc(float __x) + { return __builtin_truncf(__x); } + + inline long double + trunc(long double __x) + { return __builtin_truncl(__x); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + trunc(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return trunc(__type(__x)); + } + +#endif +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // DR 550. What should the return type of pow(float,int) be? + // NB: C++0x and TR1 != C++03. + inline double + pow(double __x, double __y) + { return std::pow(__x, __y); } + + inline float + pow(float __x, float __y) + { return std::pow(__x, __y); } + + inline long double + pow(long double __x, long double __y) + { return std::pow(__x, __y); } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + pow(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return std::pow(__type(__x), __type(__y)); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#include <bits/stl_algobase.h> +#include <limits> +#include <tr1/type_traits> + +#include <tr1/gamma.tcc> +#include <tr1/bessel_function.tcc> +#include <tr1/beta_function.tcc> +#include <tr1/ell_integral.tcc> +#include <tr1/exp_integral.tcc> +#include <tr1/hypergeometric.tcc> +#include <tr1/legendre_function.tcc> +#include <tr1/modified_bessel_func.tcc> +#include <tr1/poly_hermite.tcc> +#include <tr1/poly_laguerre.tcc> +#include <tr1/riemann_zeta.tcc> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup tr1_math_spec_func Mathematical Special Functions + * @ingroup numerics + * + * A collection of advanced mathematical special functions. + * @{ + */ + + inline float + assoc_laguerref(unsigned int __n, unsigned int __m, float __x) + { return __detail::__assoc_laguerre<float>(__n, __m, __x); } + + inline long double + assoc_laguerrel(unsigned int __n, unsigned int __m, long double __x) + { + return __detail::__assoc_laguerre<long double>(__n, __m, __x); + } + + /// 5.2.1.1 Associated Laguerre polynomials. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__assoc_laguerre<__type>(__n, __m, __x); + } + + inline float + assoc_legendref(unsigned int __l, unsigned int __m, float __x) + { return __detail::__assoc_legendre_p<float>(__l, __m, __x); } + + inline long double + assoc_legendrel(unsigned int __l, unsigned int __m, long double __x) + { return __detail::__assoc_legendre_p<long double>(__l, __m, __x); } + + /// 5.2.1.2 Associated Legendre functions. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + assoc_legendre(unsigned int __l, unsigned int __m, _Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__assoc_legendre_p<__type>(__l, __m, __x); + } + + inline float + betaf(float __x, float __y) + { return __detail::__beta<float>(__x, __y); } + + inline long double + betal(long double __x, long double __y) + { return __detail::__beta<long double>(__x, __y); } + + /// 5.2.1.3 Beta functions. + template<typename _Tpx, typename _Tpy> + inline typename __gnu_cxx::__promote_2<_Tpx, _Tpy>::__type + beta(_Tpx __x, _Tpy __y) + { + typedef typename __gnu_cxx::__promote_2<_Tpx, _Tpy>::__type __type; + return __detail::__beta<__type>(__x, __y); + } + + inline float + comp_ellint_1f(float __k) + { return __detail::__comp_ellint_1<float>(__k); } + + inline long double + comp_ellint_1l(long double __k) + { return __detail::__comp_ellint_1<long double>(__k); } + + /// 5.2.1.4 Complete elliptic integrals of the first kind. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + comp_ellint_1(_Tp __k) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__comp_ellint_1<__type>(__k); + } + + inline float + comp_ellint_2f(float __k) + { return __detail::__comp_ellint_2<float>(__k); } + + inline long double + comp_ellint_2l(long double __k) + { return __detail::__comp_ellint_2<long double>(__k); } + + /// 5.2.1.5 Complete elliptic integrals of the second kind. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + comp_ellint_2(_Tp __k) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__comp_ellint_2<__type>(__k); + } + + inline float + comp_ellint_3f(float __k, float __nu) + { return __detail::__comp_ellint_3<float>(__k, __nu); } + + inline long double + comp_ellint_3l(long double __k, long double __nu) + { return __detail::__comp_ellint_3<long double>(__k, __nu); } + + /// 5.2.1.6 Complete elliptic integrals of the third kind. + template<typename _Tp, typename _Tpn> + inline typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type + comp_ellint_3(_Tp __k, _Tpn __nu) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type __type; + return __detail::__comp_ellint_3<__type>(__k, __nu); + } + + inline float + conf_hypergf(float __a, float __c, float __x) + { return __detail::__conf_hyperg<float>(__a, __c, __x); } + + inline long double + conf_hypergl(long double __a, long double __c, long double __x) + { return __detail::__conf_hyperg<long double>(__a, __c, __x); } + + /// 5.2.1.7 Confluent hypergeometric functions. + template<typename _Tpa, typename _Tpc, typename _Tp> + inline typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type + conf_hyperg(_Tpa __a, _Tpc __c, _Tp __x) + { + typedef typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type __type; + return __detail::__conf_hyperg<__type>(__a, __c, __x); + } + + inline float + cyl_bessel_if(float __nu, float __x) + { return __detail::__cyl_bessel_i<float>(__nu, __x); } + + inline long double + cyl_bessel_il(long double __nu, long double __x) + { return __detail::__cyl_bessel_i<long double>(__nu, __x); } + + /// 5.2.1.8 Regular modified cylindrical Bessel functions. + template<typename _Tpnu, typename _Tp> + inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type + cyl_bessel_i(_Tpnu __nu, _Tp __x) + { + typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; + return __detail::__cyl_bessel_i<__type>(__nu, __x); + } + + inline float + cyl_bessel_jf(float __nu, float __x) + { return __detail::__cyl_bessel_j<float>(__nu, __x); } + + inline long double + cyl_bessel_jl(long double __nu, long double __x) + { return __detail::__cyl_bessel_j<long double>(__nu, __x); } + + /// 5.2.1.9 Cylindrical Bessel functions (of the first kind). + template<typename _Tpnu, typename _Tp> + inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type + cyl_bessel_j(_Tpnu __nu, _Tp __x) + { + typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; + return __detail::__cyl_bessel_j<__type>(__nu, __x); + } + + inline float + cyl_bessel_kf(float __nu, float __x) + { return __detail::__cyl_bessel_k<float>(__nu, __x); } + + inline long double + cyl_bessel_kl(long double __nu, long double __x) + { return __detail::__cyl_bessel_k<long double>(__nu, __x); } + + /// 5.2.1.10 Irregular modified cylindrical Bessel functions. + template<typename _Tpnu, typename _Tp> + inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type + cyl_bessel_k(_Tpnu __nu, _Tp __x) + { + typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; + return __detail::__cyl_bessel_k<__type>(__nu, __x); + } + + inline float + cyl_neumannf(float __nu, float __x) + { return __detail::__cyl_neumann_n<float>(__nu, __x); } + + inline long double + cyl_neumannl(long double __nu, long double __x) + { return __detail::__cyl_neumann_n<long double>(__nu, __x); } + + /// 5.2.1.11 Cylindrical Neumann functions. + template<typename _Tpnu, typename _Tp> + inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type + cyl_neumann(_Tpnu __nu, _Tp __x) + { + typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; + return __detail::__cyl_neumann_n<__type>(__nu, __x); + } + + inline float + ellint_1f(float __k, float __phi) + { return __detail::__ellint_1<float>(__k, __phi); } + + inline long double + ellint_1l(long double __k, long double __phi) + { return __detail::__ellint_1<long double>(__k, __phi); } + + /// 5.2.1.12 Incomplete elliptic integrals of the first kind. + template<typename _Tp, typename _Tpp> + inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type + ellint_1(_Tp __k, _Tpp __phi) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type; + return __detail::__ellint_1<__type>(__k, __phi); + } + + inline float + ellint_2f(float __k, float __phi) + { return __detail::__ellint_2<float>(__k, __phi); } + + inline long double + ellint_2l(long double __k, long double __phi) + { return __detail::__ellint_2<long double>(__k, __phi); } + + /// 5.2.1.13 Incomplete elliptic integrals of the second kind. + template<typename _Tp, typename _Tpp> + inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type + ellint_2(_Tp __k, _Tpp __phi) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type; + return __detail::__ellint_2<__type>(__k, __phi); + } + + inline float + ellint_3f(float __k, float __nu, float __phi) + { return __detail::__ellint_3<float>(__k, __nu, __phi); } + + inline long double + ellint_3l(long double __k, long double __nu, long double __phi) + { return __detail::__ellint_3<long double>(__k, __nu, __phi); } + + /// 5.2.1.14 Incomplete elliptic integrals of the third kind. + template<typename _Tp, typename _Tpn, typename _Tpp> + inline typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type + ellint_3(_Tp __k, _Tpn __nu, _Tpp __phi) + { + typedef typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type __type; + return __detail::__ellint_3<__type>(__k, __nu, __phi); + } + + inline float + expintf(float __x) + { return __detail::__expint<float>(__x); } + + inline long double + expintl(long double __x) + { return __detail::__expint<long double>(__x); } + + /// 5.2.1.15 Exponential integrals. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + expint(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__expint<__type>(__x); + } + + inline float + hermitef(unsigned int __n, float __x) + { return __detail::__poly_hermite<float>(__n, __x); } + + inline long double + hermitel(unsigned int __n, long double __x) + { return __detail::__poly_hermite<long double>(__n, __x); } + + /// 5.2.1.16 Hermite polynomials. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + hermite(unsigned int __n, _Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__poly_hermite<__type>(__n, __x); + } + + inline float + hypergf(float __a, float __b, float __c, float __x) + { return __detail::__hyperg<float>(__a, __b, __c, __x); } + + inline long double + hypergl(long double __a, long double __b, long double __c, long double __x) + { return __detail::__hyperg<long double>(__a, __b, __c, __x); } + + /// 5.2.1.17 Hypergeometric functions. + template<typename _Tpa, typename _Tpb, typename _Tpc, typename _Tp> + inline typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type + hyperg(_Tpa __a, _Tpb __b, _Tpc __c, _Tp __x) + { + typedef typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type __type; + return __detail::__hyperg<__type>(__a, __b, __c, __x); + } + + inline float + laguerref(unsigned int __n, float __x) + { return __detail::__laguerre<float>(__n, __x); } + + inline long double + laguerrel(unsigned int __n, long double __x) + { return __detail::__laguerre<long double>(__n, __x); } + + /// 5.2.1.18 Laguerre polynomials. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + laguerre(unsigned int __n, _Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__laguerre<__type>(__n, __x); + } + + inline float + legendref(unsigned int __n, float __x) + { return __detail::__poly_legendre_p<float>(__n, __x); } + + inline long double + legendrel(unsigned int __n, long double __x) + { return __detail::__poly_legendre_p<long double>(__n, __x); } + + /// 5.2.1.19 Legendre polynomials. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + legendre(unsigned int __n, _Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__poly_legendre_p<__type>(__n, __x); + } + + inline float + riemann_zetaf(float __x) + { return __detail::__riemann_zeta<float>(__x); } + + inline long double + riemann_zetal(long double __x) + { return __detail::__riemann_zeta<long double>(__x); } + + /// 5.2.1.20 Riemann zeta function. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + riemann_zeta(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__riemann_zeta<__type>(__x); + } + + inline float + sph_besself(unsigned int __n, float __x) + { return __detail::__sph_bessel<float>(__n, __x); } + + inline long double + sph_bessell(unsigned int __n, long double __x) + { return __detail::__sph_bessel<long double>(__n, __x); } + + /// 5.2.1.21 Spherical Bessel functions. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + sph_bessel(unsigned int __n, _Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__sph_bessel<__type>(__n, __x); + } + + inline float + sph_legendref(unsigned int __l, unsigned int __m, float __theta) + { return __detail::__sph_legendre<float>(__l, __m, __theta); } + + inline long double + sph_legendrel(unsigned int __l, unsigned int __m, long double __theta) + { return __detail::__sph_legendre<long double>(__l, __m, __theta); } + + /// 5.2.1.22 Spherical associated Legendre functions. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + sph_legendre(unsigned int __l, unsigned int __m, _Tp __theta) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__sph_legendre<__type>(__l, __m, __theta); + } + + inline float + sph_neumannf(unsigned int __n, float __x) + { return __detail::__sph_neumann<float>(__n, __x); } + + inline long double + sph_neumannl(unsigned int __n, long double __x) + { return __detail::__sph_neumann<long double>(__n, __x); } + + /// 5.2.1.23 Spherical Neumann functions. + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + sph_neumann(unsigned int __n, _Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __detail::__sph_neumann<__type>(__n, __x); + } + + /* @} */ // tr1_math_spec_func +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_CMATH diff --git a/libstdc++-v3/include/tr1/complex b/libstdc++-v3/include/tr1/complex new file mode 100644 index 000000000..689ea167b --- /dev/null +++ b/libstdc++-v3/include/tr1/complex @@ -0,0 +1,419 @@ +// TR1 complex -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/complex + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_COMPLEX +#define _GLIBCXX_TR1_COMPLEX 1 + +#pragma GCC system_header + +#include <complex> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @addtogroup complex_numbers + * @{ + */ + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + using std::acos; + using std::asin; + using std::atan; +#else + template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); +#endif + + template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); + template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); + + // The std::fabs return type in C++0x mode is different (just _Tp). + template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&); + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ + template<typename _Tp> + inline std::complex<_Tp> + __complex_acos(const std::complex<_Tp>& __z) + { + const std::complex<_Tp> __t = std::tr1::asin(__z); + const _Tp __pi_2 = 1.5707963267948966192313216916397514L; + return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_acos(__complex__ float __z) + { return __builtin_cacosf(__z); } + + inline __complex__ double + __complex_acos(__complex__ double __z) + { return __builtin_cacos(__z); } + + inline __complex__ long double + __complex_acos(const __complex__ long double& __z) + { return __builtin_cacosl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + acos(const std::complex<_Tp>& __z) + { return __complex_acos(__z.__rep()); } +#else + /// acos(__z) [8.1.2]. + // Effects: Behaves the same as C99 function cacos, defined + // in subclause 7.3.5.1. + template<typename _Tp> + inline std::complex<_Tp> + acos(const std::complex<_Tp>& __z) + { return __complex_acos(__z); } +#endif + + template<typename _Tp> + inline std::complex<_Tp> + __complex_asin(const std::complex<_Tp>& __z) + { + std::complex<_Tp> __t(-__z.imag(), __z.real()); + __t = std::tr1::asinh(__t); + return std::complex<_Tp>(__t.imag(), -__t.real()); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_asin(__complex__ float __z) + { return __builtin_casinf(__z); } + + inline __complex__ double + __complex_asin(__complex__ double __z) + { return __builtin_casin(__z); } + + inline __complex__ long double + __complex_asin(const __complex__ long double& __z) + { return __builtin_casinl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + asin(const std::complex<_Tp>& __z) + { return __complex_asin(__z.__rep()); } +#else + /// asin(__z) [8.1.3]. + // Effects: Behaves the same as C99 function casin, defined + // in subclause 7.3.5.2. + template<typename _Tp> + inline std::complex<_Tp> + asin(const std::complex<_Tp>& __z) + { return __complex_asin(__z); } +#endif + + template<typename _Tp> + std::complex<_Tp> + __complex_atan(const std::complex<_Tp>& __z) + { + const _Tp __r2 = __z.real() * __z.real(); + const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); + + _Tp __num = __z.imag() + _Tp(1.0); + _Tp __den = __z.imag() - _Tp(1.0); + + __num = __r2 + __num * __num; + __den = __r2 + __den * __den; + + return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), + _Tp(0.25) * log(__num / __den)); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_atan(__complex__ float __z) + { return __builtin_catanf(__z); } + + inline __complex__ double + __complex_atan(__complex__ double __z) + { return __builtin_catan(__z); } + + inline __complex__ long double + __complex_atan(const __complex__ long double& __z) + { return __builtin_catanl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + atan(const std::complex<_Tp>& __z) + { return __complex_atan(__z.__rep()); } +#else + /// atan(__z) [8.1.4]. + // Effects: Behaves the same as C99 function catan, defined + // in subclause 7.3.5.3. + template<typename _Tp> + inline std::complex<_Tp> + atan(const std::complex<_Tp>& __z) + { return __complex_atan(__z); } +#endif + +#endif // __GXX_EXPERIMENTAL_CXX0X__ + + template<typename _Tp> + std::complex<_Tp> + __complex_acosh(const std::complex<_Tp>& __z) + { + // Kahan's formula. + return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0))) + + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0)))); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_acosh(__complex__ float __z) + { return __builtin_cacoshf(__z); } + + inline __complex__ double + __complex_acosh(__complex__ double __z) + { return __builtin_cacosh(__z); } + + inline __complex__ long double + __complex_acosh(const __complex__ long double& __z) + { return __builtin_cacoshl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + acosh(const std::complex<_Tp>& __z) + { return __complex_acosh(__z.__rep()); } +#else + /// acosh(__z) [8.1.5]. + // Effects: Behaves the same as C99 function cacosh, defined + // in subclause 7.3.6.1. + template<typename _Tp> + inline std::complex<_Tp> + acosh(const std::complex<_Tp>& __z) + { return __complex_acosh(__z); } +#endif + + template<typename _Tp> + std::complex<_Tp> + __complex_asinh(const std::complex<_Tp>& __z) + { + std::complex<_Tp> __t((__z.real() - __z.imag()) + * (__z.real() + __z.imag()) + _Tp(1.0), + _Tp(2.0) * __z.real() * __z.imag()); + __t = std::sqrt(__t); + + return std::log(__t + __z); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_asinh(__complex__ float __z) + { return __builtin_casinhf(__z); } + + inline __complex__ double + __complex_asinh(__complex__ double __z) + { return __builtin_casinh(__z); } + + inline __complex__ long double + __complex_asinh(const __complex__ long double& __z) + { return __builtin_casinhl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + asinh(const std::complex<_Tp>& __z) + { return __complex_asinh(__z.__rep()); } +#else + /// asinh(__z) [8.1.6]. + // Effects: Behaves the same as C99 function casin, defined + // in subclause 7.3.6.2. + template<typename _Tp> + inline std::complex<_Tp> + asinh(const std::complex<_Tp>& __z) + { return __complex_asinh(__z); } +#endif + + template<typename _Tp> + std::complex<_Tp> + __complex_atanh(const std::complex<_Tp>& __z) + { + const _Tp __i2 = __z.imag() * __z.imag(); + const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); + + _Tp __num = _Tp(1.0) + __z.real(); + _Tp __den = _Tp(1.0) - __z.real(); + + __num = __i2 + __num * __num; + __den = __i2 + __den * __den; + + return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), + _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); + } + +#if _GLIBCXX_USE_C99_COMPLEX_TR1 + inline __complex__ float + __complex_atanh(__complex__ float __z) + { return __builtin_catanhf(__z); } + + inline __complex__ double + __complex_atanh(__complex__ double __z) + { return __builtin_catanh(__z); } + + inline __complex__ long double + __complex_atanh(const __complex__ long double& __z) + { return __builtin_catanhl(__z); } + + template<typename _Tp> + inline std::complex<_Tp> + atanh(const std::complex<_Tp>& __z) + { return __complex_atanh(__z.__rep()); } +#else + /// atanh(__z) [8.1.7]. + // Effects: Behaves the same as C99 function catanh, defined + // in subclause 7.3.6.3. + template<typename _Tp> + inline std::complex<_Tp> + atanh(const std::complex<_Tp>& __z) + { return __complex_atanh(__z); } +#endif + + template<typename _Tp> + inline std::complex<_Tp> + /// fabs(__z) [8.1.8]. + // Effects: Behaves the same as C99 function cabs, defined + // in subclause 7.3.8.1. + fabs(const std::complex<_Tp>& __z) + { return std::abs(__z); } + + /// Additional overloads [8.1.9]. +#ifndef __GXX_EXPERIMENTAL_CXX0X__ + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + arg(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; +#if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) + return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L) + : __type(); +#else + return std::arg(std::complex<__type>(__x)); +#endif + } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + imag(_Tp) + { return _Tp(); } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + norm(_Tp __x) + { + typedef typename __gnu_cxx::__promote<_Tp>::__type __type; + return __type(__x) * __type(__x); + } + + template<typename _Tp> + inline typename __gnu_cxx::__promote<_Tp>::__type + real(_Tp __x) + { return __x; } + +#endif + + template<typename _Tp, typename _Up> + inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> + pow(const std::complex<_Tp>& __x, const _Up& __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return std::pow(std::complex<__type>(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> + pow(const _Tp& __x, const std::complex<_Up>& __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return std::pow(__type(__x), std::complex<__type>(__y)); + } + + template<typename _Tp, typename _Up> + inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> + pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return std::pow(std::complex<__type>(__x), + std::complex<__type>(__y)); + } + + using std::arg; + + template<typename _Tp> + inline std::complex<_Tp> + conj(const std::complex<_Tp>& __z) + { return std::conj(__z); } + + template<typename _Tp> + inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type> + conj(_Tp __x) + { return __x; } + + using std::imag; + using std::norm; + using std::polar; + + template<typename _Tp, typename _Up> + inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> + polar(const _Tp& __rho, const _Up& __theta) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return std::polar(__type(__rho), __type(__theta)); + } + + using std::real; + + template<typename _Tp> + inline std::complex<_Tp> + pow(const std::complex<_Tp>& __x, const _Tp& __y) + { return std::pow(__x, __y); } + + template<typename _Tp> + inline std::complex<_Tp> + pow(const _Tp& __x, const std::complex<_Tp>& __y) + { return std::pow(__x, __y); } + + template<typename _Tp> + inline std::complex<_Tp> + pow(const std::complex<_Tp>& __x, const std::complex<_Tp>& __y) + { return std::pow(__x, __y); } + +// @} group complex_numbers + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_COMPLEX diff --git a/libstdc++-v3/include/tr1/complex.h b/libstdc++-v3/include/tr1/complex.h new file mode 100644 index 000000000..0f28810b7 --- /dev/null +++ b/libstdc++-v3/include/tr1/complex.h @@ -0,0 +1,34 @@ +// TR1 complex.h -*- C++ -*- + +// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/complex.h + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_COMPLEX_H +#define _GLIBCXX_TR1_COMPLEX_H 1 + +#include <tr1/ccomplex> + +#endif // _GLIBCXX_TR1_COMPLEX_H diff --git a/libstdc++-v3/include/tr1/cstdarg b/libstdc++-v3/include/tr1/cstdarg new file mode 100644 index 000000000..bc2e88153 --- /dev/null +++ b/libstdc++-v3/include/tr1/cstdarg @@ -0,0 +1,34 @@ +// TR1 cstdarg -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cstdarg + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CSTDARG +#define _GLIBCXX_TR1_CSTDARG 1 + +#include <cstdarg> + +#endif // _GLIBCXX_TR1_CSTDARG diff --git a/libstdc++-v3/include/tr1/cstdbool b/libstdc++-v3/include/tr1/cstdbool new file mode 100644 index 000000000..d68e4b896 --- /dev/null +++ b/libstdc++-v3/include/tr1/cstdbool @@ -0,0 +1,40 @@ +// TR1 cstdbool -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cstdbool + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CSTDBOOL +#define _GLIBCXX_TR1_CSTDBOOL 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +#if _GLIBCXX_HAVE_STDBOOL_H +#include <stdbool.h> +#endif + +#endif // _GLIBCXX_TR1_CSTDBOOL diff --git a/libstdc++-v3/include/tr1/cstdint b/libstdc++-v3/include/tr1/cstdint new file mode 100644 index 000000000..55ce4bcef --- /dev/null +++ b/libstdc++-v3/include/tr1/cstdint @@ -0,0 +1,104 @@ +// TR1 cstdint -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cstdint + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CSTDINT +#define _GLIBCXX_TR1_CSTDINT 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +// For 8.22.1/1 (see C99, Notes 219, 220, 222) +# if _GLIBCXX_HAVE_STDINT_H +# ifndef __STDC_LIMIT_MACROS +# define _UNDEF__STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS +# endif +# ifndef __STDC_CONSTANT_MACROS +# define _UNDEF__STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS +# endif +# include <stdint.h> +# ifdef _UNDEF__STDC_LIMIT_MACROS +# undef __STDC_LIMIT_MACROS +# undef _UNDEF__STDC_LIMIT_MACROS +# endif +# ifdef _UNDEF__STDC_CONSTANT_MACROS +# undef __STDC_CONSTANT_MACROS +# undef _UNDEF__STDC_CONSTANT_MACROS +# endif +# endif + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + using ::int8_t; + using ::int16_t; + using ::int32_t; + using ::int64_t; + + using ::int_fast8_t; + using ::int_fast16_t; + using ::int_fast32_t; + using ::int_fast64_t; + + using ::int_least8_t; + using ::int_least16_t; + using ::int_least32_t; + using ::int_least64_t; + + using ::intmax_t; + using ::intptr_t; + + using ::uint8_t; + using ::uint16_t; + using ::uint32_t; + using ::uint64_t; + + using ::uint_fast8_t; + using ::uint_fast16_t; + using ::uint_fast32_t; + using ::uint_fast64_t; + + using ::uint_least8_t; + using ::uint_least16_t; + using ::uint_least32_t; + using ::uint_least64_t; + + using ::uintmax_t; + using ::uintptr_t; +} +} + +#endif // _GLIBCXX_USE_C99_STDINT_TR1 + +#endif // _GLIBCXX_TR1_CSTDINT + diff --git a/libstdc++-v3/include/tr1/cstdio b/libstdc++-v3/include/tr1/cstdio new file mode 100644 index 000000000..415e8a4d6 --- /dev/null +++ b/libstdc++-v3/include/tr1/cstdio @@ -0,0 +1,53 @@ +// TR1 cstdio -*- C++ -*- + +// Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cstdio + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CSTDIO +#define _GLIBCXX_TR1_CSTDIO 1 + +#pragma GCC system_header + +#include <cstdio> + +#if _GLIBCXX_USE_C99 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + using std::snprintf; + using std::vsnprintf; + + using std::vfscanf; + using std::vscanf; + using std::vsscanf; +} +} + +#endif + +#endif // _GLIBCXX_TR1_CSTDIO diff --git a/libstdc++-v3/include/tr1/cstdlib b/libstdc++-v3/include/tr1/cstdlib new file mode 100644 index 000000000..6e3e16d0f --- /dev/null +++ b/libstdc++-v3/include/tr1/cstdlib @@ -0,0 +1,72 @@ +// TR1 cstdlib -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cstdlib + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CSTDLIB +#define _GLIBCXX_TR1_CSTDLIB 1 + +#pragma GCC system_header + +#include <cstdlib> + +#if _GLIBCXX_HOSTED + +#if _GLIBCXX_USE_C99 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + // types + using std::lldiv_t; + + // functions + using std::llabs; + using std::lldiv; +#endif + + using std::atoll; + using std::strtoll; + using std::strtoull; + + using std::strtof; + using std::strtold; + + // overloads + using std::abs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using std::div; +#endif +} +} + +#endif // _GLIBCXX_USE_C99 + +#endif // _GLIBCXX_HOSTED + +#endif // _GLIBCXX_TR1_CSTDLIB diff --git a/libstdc++-v3/include/tr1/ctgmath b/libstdc++-v3/include/tr1/ctgmath new file mode 100644 index 000000000..e82a9a15f --- /dev/null +++ b/libstdc++-v3/include/tr1/ctgmath @@ -0,0 +1,34 @@ +// TR1 ctgmath -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/ctgmath + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CTGMATH +#define _GLIBCXX_TR1_CTGMATH 1 + +#include <tr1/cmath> + +#endif // _GLIBCXX_TR1_CTGMATH diff --git a/libstdc++-v3/include/tr1/ctime b/libstdc++-v3/include/tr1/ctime new file mode 100644 index 000000000..bf763377d --- /dev/null +++ b/libstdc++-v3/include/tr1/ctime @@ -0,0 +1,34 @@ +// TR1 ctime -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/ctime + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CTIME +#define _GLIBCXX_TR1_CTIME 1 + +#include <ctime> + +#endif // _GLIBCXX_TR1_CTIME diff --git a/libstdc++-v3/include/tr1/ctype.h b/libstdc++-v3/include/tr1/ctype.h new file mode 100644 index 000000000..712bedb67 --- /dev/null +++ b/libstdc++-v3/include/tr1/ctype.h @@ -0,0 +1,34 @@ +// TR1 ctype.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/ctype.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_CTYPE_H +#define _TR1_CTYPE_H 1 + +#include <tr1/cctype> + +#endif diff --git a/libstdc++-v3/include/tr1/cwchar b/libstdc++-v3/include/tr1/cwchar new file mode 100644 index 000000000..8bf775be1 --- /dev/null +++ b/libstdc++-v3/include/tr1/cwchar @@ -0,0 +1,65 @@ +// TR1 cwchar -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cwchar + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CWCHAR +#define _GLIBCXX_TR1_CWCHAR 1 + +#pragma GCC system_header + +#include <cwchar> + +#ifdef _GLIBCXX_USE_WCHAR_T + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +#if _GLIBCXX_HAVE_WCSTOF + using std::wcstof; +#endif +#if _GLIBCXX_HAVE_VFWSCANF + using std::vfwscanf; +#endif +#if _GLIBCXX_HAVE_VSWSCANF + using std::vswscanf; +#endif +#if _GLIBCXX_HAVE_VWSCANF + using std::vwscanf; +#endif + +#if _GLIBCXX_USE_C99 + using std::wcstold; + using std::wcstoll; + using std::wcstoull; +#endif +} +} + +#endif // _GLIBCXX_USE_WCHAR_T + +#endif // _GLIBCXX_TR1_CWCHAR diff --git a/libstdc++-v3/include/tr1/cwctype b/libstdc++-v3/include/tr1/cwctype new file mode 100644 index 000000000..452a7b456 --- /dev/null +++ b/libstdc++-v3/include/tr1/cwctype @@ -0,0 +1,50 @@ +// TR1 cwctype -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/cwctype + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_CWCTYPE +#define _GLIBCXX_TR1_CWCTYPE 1 + +#pragma GCC system_header + +#include <cwctype> + +#ifdef _GLIBCXX_USE_WCHAR_T + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +#if _GLIBCXX_HAVE_ISWBLANK + using std::iswblank; +#endif +} +} + +#endif // _GLIBCXX_USE_WCHAR_T + +#endif // _GLIBCXX_TR1_CWCTYPE diff --git a/libstdc++-v3/include/tr1/ell_integral.tcc b/libstdc++-v3/include/tr1/ell_integral.tcc new file mode 100644 index 000000000..4dfe6169c --- /dev/null +++ b/libstdc++-v3/include/tr1/ell_integral.tcc @@ -0,0 +1,751 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/ell_integral.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// (1) B. C. Carlson Numer. Math. 33, 1 (1979) +// (2) B. C. Carlson, Special Functions of Applied Mathematics (1977) +// (3) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (4) Numerical Recipes in C, 2nd ed, by W. H. Press, S. A. Teukolsky, +// W. T. Vetterling, B. P. Flannery, Cambridge University Press +// (1992), pp. 261-269 + +#ifndef _GLIBCXX_TR1_ELL_INTEGRAL_TCC +#define _GLIBCXX_TR1_ELL_INTEGRAL_TCC 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Return the Carlson elliptic function @f$ R_F(x,y,z) @f$ + * of the first kind. + * + * The Carlson elliptic function of the first kind is defined by: + * @f[ + * R_F(x,y,z) = \frac{1}{2} \int_0^\infty + * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}} + * @f] + * + * @param __x The first of three symmetric arguments. + * @param __y The second of three symmetric arguments. + * @param __z The third of three symmetric arguments. + * @return The Carlson elliptic function of the first kind. + */ + template<typename _Tp> + _Tp + __ellint_rf(const _Tp __x, const _Tp __y, const _Tp __z) + { + const _Tp __min = std::numeric_limits<_Tp>::min(); + const _Tp __max = std::numeric_limits<_Tp>::max(); + const _Tp __lolim = _Tp(5) * __min; + const _Tp __uplim = __max / _Tp(5); + + if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0)) + std::__throw_domain_error(__N("Argument less than zero " + "in __ellint_rf.")); + else if (__x + __y < __lolim || __x + __z < __lolim + || __y + __z < __lolim) + std::__throw_domain_error(__N("Argument too small in __ellint_rf")); + else + { + const _Tp __c0 = _Tp(1) / _Tp(4); + const _Tp __c1 = _Tp(1) / _Tp(24); + const _Tp __c2 = _Tp(1) / _Tp(10); + const _Tp __c3 = _Tp(3) / _Tp(44); + const _Tp __c4 = _Tp(1) / _Tp(14); + + _Tp __xn = __x; + _Tp __yn = __y; + _Tp __zn = __z; + + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __errtol = std::pow(__eps, _Tp(1) / _Tp(6)); + _Tp __mu; + _Tp __xndev, __yndev, __zndev; + + const unsigned int __max_iter = 100; + for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) + { + __mu = (__xn + __yn + __zn) / _Tp(3); + __xndev = 2 - (__mu + __xn) / __mu; + __yndev = 2 - (__mu + __yn) / __mu; + __zndev = 2 - (__mu + __zn) / __mu; + _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); + __epsilon = std::max(__epsilon, std::abs(__zndev)); + if (__epsilon < __errtol) + break; + const _Tp __xnroot = std::sqrt(__xn); + const _Tp __ynroot = std::sqrt(__yn); + const _Tp __znroot = std::sqrt(__zn); + const _Tp __lambda = __xnroot * (__ynroot + __znroot) + + __ynroot * __znroot; + __xn = __c0 * (__xn + __lambda); + __yn = __c0 * (__yn + __lambda); + __zn = __c0 * (__zn + __lambda); + } + + const _Tp __e2 = __xndev * __yndev - __zndev * __zndev; + const _Tp __e3 = __xndev * __yndev * __zndev; + const _Tp __s = _Tp(1) + (__c1 * __e2 - __c2 - __c3 * __e3) * __e2 + + __c4 * __e3; + + return __s / std::sqrt(__mu); + } + } + + + /** + * @brief Return the complete elliptic integral of the first kind + * @f$ K(k) @f$ by series expansion. + * + * The complete elliptic integral of the first kind is defined as + * @f[ + * K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta} + * {\sqrt{1 - k^2sin^2\theta}} + * @f] + * + * This routine is not bad as long as |k| is somewhat smaller than 1 + * but is not is good as the Carlson elliptic integral formulation. + * + * @param __k The argument of the complete elliptic function. + * @return The complete elliptic function of the first kind. + */ + template<typename _Tp> + _Tp + __comp_ellint_1_series(const _Tp __k) + { + + const _Tp __kk = __k * __k; + + _Tp __term = __kk / _Tp(4); + _Tp __sum = _Tp(1) + __term; + + const unsigned int __max_iter = 1000; + for (unsigned int __i = 2; __i < __max_iter; ++__i) + { + __term *= (2 * __i - 1) * __kk / (2 * __i); + if (__term < std::numeric_limits<_Tp>::epsilon()) + break; + __sum += __term; + } + + return __numeric_constants<_Tp>::__pi_2() * __sum; + } + + + /** + * @brief Return the complete elliptic integral of the first kind + * @f$ K(k) @f$ using the Carlson formulation. + * + * The complete elliptic integral of the first kind is defined as + * @f[ + * K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta} + * {\sqrt{1 - k^2 sin^2\theta}} + * @f] + * where @f$ F(k,\phi) @f$ is the incomplete elliptic integral of the + * first kind. + * + * @param __k The argument of the complete elliptic function. + * @return The complete elliptic function of the first kind. + */ + template<typename _Tp> + _Tp + __comp_ellint_1(const _Tp __k) + { + + if (__isnan(__k)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (std::abs(__k) >= _Tp(1)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else + return __ellint_rf(_Tp(0), _Tp(1) - __k * __k, _Tp(1)); + } + + + /** + * @brief Return the incomplete elliptic integral of the first kind + * @f$ F(k,\phi) @f$ using the Carlson formulation. + * + * The incomplete elliptic integral of the first kind is defined as + * @f[ + * F(k,\phi) = \int_0^{\phi}\frac{d\theta} + * {\sqrt{1 - k^2 sin^2\theta}} + * @f] + * + * @param __k The argument of the elliptic function. + * @param __phi The integral limit argument of the elliptic function. + * @return The elliptic function of the first kind. + */ + template<typename _Tp> + _Tp + __ellint_1(const _Tp __k, const _Tp __phi) + { + + if (__isnan(__k) || __isnan(__phi)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (std::abs(__k) > _Tp(1)) + std::__throw_domain_error(__N("Bad argument in __ellint_1.")); + else + { + // Reduce phi to -pi/2 < phi < +pi/2. + const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() + + _Tp(0.5L)); + const _Tp __phi_red = __phi + - __n * __numeric_constants<_Tp>::__pi(); + + const _Tp __s = std::sin(__phi_red); + const _Tp __c = std::cos(__phi_red); + + const _Tp __F = __s + * __ellint_rf(__c * __c, + _Tp(1) - __k * __k * __s * __s, _Tp(1)); + + if (__n == 0) + return __F; + else + return __F + _Tp(2) * __n * __comp_ellint_1(__k); + } + } + + + /** + * @brief Return the complete elliptic integral of the second kind + * @f$ E(k) @f$ by series expansion. + * + * The complete elliptic integral of the second kind is defined as + * @f[ + * E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta} + * @f] + * + * This routine is not bad as long as |k| is somewhat smaller than 1 + * but is not is good as the Carlson elliptic integral formulation. + * + * @param __k The argument of the complete elliptic function. + * @return The complete elliptic function of the second kind. + */ + template<typename _Tp> + _Tp + __comp_ellint_2_series(const _Tp __k) + { + + const _Tp __kk = __k * __k; + + _Tp __term = __kk; + _Tp __sum = __term; + + const unsigned int __max_iter = 1000; + for (unsigned int __i = 2; __i < __max_iter; ++__i) + { + const _Tp __i2m = 2 * __i - 1; + const _Tp __i2 = 2 * __i; + __term *= __i2m * __i2m * __kk / (__i2 * __i2); + if (__term < std::numeric_limits<_Tp>::epsilon()) + break; + __sum += __term / __i2m; + } + + return __numeric_constants<_Tp>::__pi_2() * (_Tp(1) - __sum); + } + + + /** + * @brief Return the Carlson elliptic function of the second kind + * @f$ R_D(x,y,z) = R_J(x,y,z,z) @f$ where + * @f$ R_J(x,y,z,p) @f$ is the Carlson elliptic function + * of the third kind. + * + * The Carlson elliptic function of the second kind is defined by: + * @f[ + * R_D(x,y,z) = \frac{3}{2} \int_0^\infty + * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{3/2}} + * @f] + * + * Based on Carlson's algorithms: + * - B. C. Carlson Numer. Math. 33, 1 (1979) + * - B. C. Carlson, Special Functions of Applied Mathematics (1977) + * - Numerical Recipes in C, 2nd ed, pp. 261-269, + * by Press, Teukolsky, Vetterling, Flannery (1992) + * + * @param __x The first of two symmetric arguments. + * @param __y The second of two symmetric arguments. + * @param __z The third argument. + * @return The Carlson elliptic function of the second kind. + */ + template<typename _Tp> + _Tp + __ellint_rd(const _Tp __x, const _Tp __y, const _Tp __z) + { + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6)); + const _Tp __min = std::numeric_limits<_Tp>::min(); + const _Tp __max = std::numeric_limits<_Tp>::max(); + const _Tp __lolim = _Tp(2) / std::pow(__max, _Tp(2) / _Tp(3)); + const _Tp __uplim = std::pow(_Tp(0.1L) * __errtol / __min, _Tp(2) / _Tp(3)); + + if (__x < _Tp(0) || __y < _Tp(0)) + std::__throw_domain_error(__N("Argument less than zero " + "in __ellint_rd.")); + else if (__x + __y < __lolim || __z < __lolim) + std::__throw_domain_error(__N("Argument too small " + "in __ellint_rd.")); + else + { + const _Tp __c0 = _Tp(1) / _Tp(4); + const _Tp __c1 = _Tp(3) / _Tp(14); + const _Tp __c2 = _Tp(1) / _Tp(6); + const _Tp __c3 = _Tp(9) / _Tp(22); + const _Tp __c4 = _Tp(3) / _Tp(26); + + _Tp __xn = __x; + _Tp __yn = __y; + _Tp __zn = __z; + _Tp __sigma = _Tp(0); + _Tp __power4 = _Tp(1); + + _Tp __mu; + _Tp __xndev, __yndev, __zndev; + + const unsigned int __max_iter = 100; + for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) + { + __mu = (__xn + __yn + _Tp(3) * __zn) / _Tp(5); + __xndev = (__mu - __xn) / __mu; + __yndev = (__mu - __yn) / __mu; + __zndev = (__mu - __zn) / __mu; + _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); + __epsilon = std::max(__epsilon, std::abs(__zndev)); + if (__epsilon < __errtol) + break; + _Tp __xnroot = std::sqrt(__xn); + _Tp __ynroot = std::sqrt(__yn); + _Tp __znroot = std::sqrt(__zn); + _Tp __lambda = __xnroot * (__ynroot + __znroot) + + __ynroot * __znroot; + __sigma += __power4 / (__znroot * (__zn + __lambda)); + __power4 *= __c0; + __xn = __c0 * (__xn + __lambda); + __yn = __c0 * (__yn + __lambda); + __zn = __c0 * (__zn + __lambda); + } + + // Note: __ea is an SPU badname. + _Tp __eaa = __xndev * __yndev; + _Tp __eb = __zndev * __zndev; + _Tp __ec = __eaa - __eb; + _Tp __ed = __eaa - _Tp(6) * __eb; + _Tp __ef = __ed + __ec + __ec; + _Tp __s1 = __ed * (-__c1 + __c3 * __ed + / _Tp(3) - _Tp(3) * __c4 * __zndev * __ef + / _Tp(2)); + _Tp __s2 = __zndev + * (__c2 * __ef + + __zndev * (-__c3 * __ec - __zndev * __c4 - __eaa)); + + return _Tp(3) * __sigma + __power4 * (_Tp(1) + __s1 + __s2) + / (__mu * std::sqrt(__mu)); + } + } + + + /** + * @brief Return the complete elliptic integral of the second kind + * @f$ E(k) @f$ using the Carlson formulation. + * + * The complete elliptic integral of the second kind is defined as + * @f[ + * E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta} + * @f] + * + * @param __k The argument of the complete elliptic function. + * @return The complete elliptic function of the second kind. + */ + template<typename _Tp> + _Tp + __comp_ellint_2(const _Tp __k) + { + + if (__isnan(__k)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (std::abs(__k) == 1) + return _Tp(1); + else if (std::abs(__k) > _Tp(1)) + std::__throw_domain_error(__N("Bad argument in __comp_ellint_2.")); + else + { + const _Tp __kk = __k * __k; + + return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1)) + - __kk * __ellint_rd(_Tp(0), _Tp(1) - __kk, _Tp(1)) / _Tp(3); + } + } + + + /** + * @brief Return the incomplete elliptic integral of the second kind + * @f$ E(k,\phi) @f$ using the Carlson formulation. + * + * The incomplete elliptic integral of the second kind is defined as + * @f[ + * E(k,\phi) = \int_0^{\phi} \sqrt{1 - k^2 sin^2\theta} + * @f] + * + * @param __k The argument of the elliptic function. + * @param __phi The integral limit argument of the elliptic function. + * @return The elliptic function of the second kind. + */ + template<typename _Tp> + _Tp + __ellint_2(const _Tp __k, const _Tp __phi) + { + + if (__isnan(__k) || __isnan(__phi)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (std::abs(__k) > _Tp(1)) + std::__throw_domain_error(__N("Bad argument in __ellint_2.")); + else + { + // Reduce phi to -pi/2 < phi < +pi/2. + const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() + + _Tp(0.5L)); + const _Tp __phi_red = __phi + - __n * __numeric_constants<_Tp>::__pi(); + + const _Tp __kk = __k * __k; + const _Tp __s = std::sin(__phi_red); + const _Tp __ss = __s * __s; + const _Tp __sss = __ss * __s; + const _Tp __c = std::cos(__phi_red); + const _Tp __cc = __c * __c; + + const _Tp __E = __s + * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1)) + - __kk * __sss + * __ellint_rd(__cc, _Tp(1) - __kk * __ss, _Tp(1)) + / _Tp(3); + + if (__n == 0) + return __E; + else + return __E + _Tp(2) * __n * __comp_ellint_2(__k); + } + } + + + /** + * @brief Return the Carlson elliptic function + * @f$ R_C(x,y) = R_F(x,y,y) @f$ where @f$ R_F(x,y,z) @f$ + * is the Carlson elliptic function of the first kind. + * + * The Carlson elliptic function is defined by: + * @f[ + * R_C(x,y) = \frac{1}{2} \int_0^\infty + * \frac{dt}{(t + x)^{1/2}(t + y)} + * @f] + * + * Based on Carlson's algorithms: + * - B. C. Carlson Numer. Math. 33, 1 (1979) + * - B. C. Carlson, Special Functions of Applied Mathematics (1977) + * - Numerical Recipes in C, 2nd ed, pp. 261-269, + * by Press, Teukolsky, Vetterling, Flannery (1992) + * + * @param __x The first argument. + * @param __y The second argument. + * @return The Carlson elliptic function. + */ + template<typename _Tp> + _Tp + __ellint_rc(const _Tp __x, const _Tp __y) + { + const _Tp __min = std::numeric_limits<_Tp>::min(); + const _Tp __max = std::numeric_limits<_Tp>::max(); + const _Tp __lolim = _Tp(5) * __min; + const _Tp __uplim = __max / _Tp(5); + + if (__x < _Tp(0) || __y < _Tp(0) || __x + __y < __lolim) + std::__throw_domain_error(__N("Argument less than zero " + "in __ellint_rc.")); + else + { + const _Tp __c0 = _Tp(1) / _Tp(4); + const _Tp __c1 = _Tp(1) / _Tp(7); + const _Tp __c2 = _Tp(9) / _Tp(22); + const _Tp __c3 = _Tp(3) / _Tp(10); + const _Tp __c4 = _Tp(3) / _Tp(8); + + _Tp __xn = __x; + _Tp __yn = __y; + + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __errtol = std::pow(__eps / _Tp(30), _Tp(1) / _Tp(6)); + _Tp __mu; + _Tp __sn; + + const unsigned int __max_iter = 100; + for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) + { + __mu = (__xn + _Tp(2) * __yn) / _Tp(3); + __sn = (__yn + __mu) / __mu - _Tp(2); + if (std::abs(__sn) < __errtol) + break; + const _Tp __lambda = _Tp(2) * std::sqrt(__xn) * std::sqrt(__yn) + + __yn; + __xn = __c0 * (__xn + __lambda); + __yn = __c0 * (__yn + __lambda); + } + + _Tp __s = __sn * __sn + * (__c3 + __sn*(__c1 + __sn * (__c4 + __sn * __c2))); + + return (_Tp(1) + __s) / std::sqrt(__mu); + } + } + + + /** + * @brief Return the Carlson elliptic function @f$ R_J(x,y,z,p) @f$ + * of the third kind. + * + * The Carlson elliptic function of the third kind is defined by: + * @f[ + * R_J(x,y,z,p) = \frac{3}{2} \int_0^\infty + * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}(t + p)} + * @f] + * + * Based on Carlson's algorithms: + * - B. C. Carlson Numer. Math. 33, 1 (1979) + * - B. C. Carlson, Special Functions of Applied Mathematics (1977) + * - Numerical Recipes in C, 2nd ed, pp. 261-269, + * by Press, Teukolsky, Vetterling, Flannery (1992) + * + * @param __x The first of three symmetric arguments. + * @param __y The second of three symmetric arguments. + * @param __z The third of three symmetric arguments. + * @param __p The fourth argument. + * @return The Carlson elliptic function of the fourth kind. + */ + template<typename _Tp> + _Tp + __ellint_rj(const _Tp __x, const _Tp __y, const _Tp __z, const _Tp __p) + { + const _Tp __min = std::numeric_limits<_Tp>::min(); + const _Tp __max = std::numeric_limits<_Tp>::max(); + const _Tp __lolim = std::pow(_Tp(5) * __min, _Tp(1)/_Tp(3)); + const _Tp __uplim = _Tp(0.3L) + * std::pow(_Tp(0.2L) * __max, _Tp(1)/_Tp(3)); + + if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0)) + std::__throw_domain_error(__N("Argument less than zero " + "in __ellint_rj.")); + else if (__x + __y < __lolim || __x + __z < __lolim + || __y + __z < __lolim || __p < __lolim) + std::__throw_domain_error(__N("Argument too small " + "in __ellint_rj")); + else + { + const _Tp __c0 = _Tp(1) / _Tp(4); + const _Tp __c1 = _Tp(3) / _Tp(14); + const _Tp __c2 = _Tp(1) / _Tp(3); + const _Tp __c3 = _Tp(3) / _Tp(22); + const _Tp __c4 = _Tp(3) / _Tp(26); + + _Tp __xn = __x; + _Tp __yn = __y; + _Tp __zn = __z; + _Tp __pn = __p; + _Tp __sigma = _Tp(0); + _Tp __power4 = _Tp(1); + + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6)); + + _Tp __lambda, __mu; + _Tp __xndev, __yndev, __zndev, __pndev; + + const unsigned int __max_iter = 100; + for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) + { + __mu = (__xn + __yn + __zn + _Tp(2) * __pn) / _Tp(5); + __xndev = (__mu - __xn) / __mu; + __yndev = (__mu - __yn) / __mu; + __zndev = (__mu - __zn) / __mu; + __pndev = (__mu - __pn) / __mu; + _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); + __epsilon = std::max(__epsilon, std::abs(__zndev)); + __epsilon = std::max(__epsilon, std::abs(__pndev)); + if (__epsilon < __errtol) + break; + const _Tp __xnroot = std::sqrt(__xn); + const _Tp __ynroot = std::sqrt(__yn); + const _Tp __znroot = std::sqrt(__zn); + const _Tp __lambda = __xnroot * (__ynroot + __znroot) + + __ynroot * __znroot; + const _Tp __alpha1 = __pn * (__xnroot + __ynroot + __znroot) + + __xnroot * __ynroot * __znroot; + const _Tp __alpha2 = __alpha1 * __alpha1; + const _Tp __beta = __pn * (__pn + __lambda) + * (__pn + __lambda); + __sigma += __power4 * __ellint_rc(__alpha2, __beta); + __power4 *= __c0; + __xn = __c0 * (__xn + __lambda); + __yn = __c0 * (__yn + __lambda); + __zn = __c0 * (__zn + __lambda); + __pn = __c0 * (__pn + __lambda); + } + + // Note: __ea is an SPU badname. + _Tp __eaa = __xndev * (__yndev + __zndev) + __yndev * __zndev; + _Tp __eb = __xndev * __yndev * __zndev; + _Tp __ec = __pndev * __pndev; + _Tp __e2 = __eaa - _Tp(3) * __ec; + _Tp __e3 = __eb + _Tp(2) * __pndev * (__eaa - __ec); + _Tp __s1 = _Tp(1) + __e2 * (-__c1 + _Tp(3) * __c3 * __e2 / _Tp(4) + - _Tp(3) * __c4 * __e3 / _Tp(2)); + _Tp __s2 = __eb * (__c2 / _Tp(2) + + __pndev * (-__c3 - __c3 + __pndev * __c4)); + _Tp __s3 = __pndev * __eaa * (__c2 - __pndev * __c3) + - __c2 * __pndev * __ec; + + return _Tp(3) * __sigma + __power4 * (__s1 + __s2 + __s3) + / (__mu * std::sqrt(__mu)); + } + } + + + /** + * @brief Return the complete elliptic integral of the third kind + * @f$ \Pi(k,\nu) = \Pi(k,\nu,\pi/2) @f$ using the + * Carlson formulation. + * + * The complete elliptic integral of the third kind is defined as + * @f[ + * \Pi(k,\nu) = \int_0^{\pi/2} + * \frac{d\theta} + * {(1 - \nu \sin^2\theta)\sqrt{1 - k^2 \sin^2\theta}} + * @f] + * + * @param __k The argument of the elliptic function. + * @param __nu The second argument of the elliptic function. + * @return The complete elliptic function of the third kind. + */ + template<typename _Tp> + _Tp + __comp_ellint_3(const _Tp __k, const _Tp __nu) + { + + if (__isnan(__k) || __isnan(__nu)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__nu == _Tp(1)) + return std::numeric_limits<_Tp>::infinity(); + else if (std::abs(__k) > _Tp(1)) + std::__throw_domain_error(__N("Bad argument in __comp_ellint_3.")); + else + { + const _Tp __kk = __k * __k; + + return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1)) + - __nu + * __ellint_rj(_Tp(0), _Tp(1) - __kk, _Tp(1), _Tp(1) + __nu) + / _Tp(3); + } + } + + + /** + * @brief Return the incomplete elliptic integral of the third kind + * @f$ \Pi(k,\nu,\phi) @f$ using the Carlson formulation. + * + * The incomplete elliptic integral of the third kind is defined as + * @f[ + * \Pi(k,\nu,\phi) = \int_0^{\phi} + * \frac{d\theta} + * {(1 - \nu \sin^2\theta) + * \sqrt{1 - k^2 \sin^2\theta}} + * @f] + * + * @param __k The argument of the elliptic function. + * @param __nu The second argument of the elliptic function. + * @param __phi The integral limit argument of the elliptic function. + * @return The elliptic function of the third kind. + */ + template<typename _Tp> + _Tp + __ellint_3(const _Tp __k, const _Tp __nu, const _Tp __phi) + { + + if (__isnan(__k) || __isnan(__nu) || __isnan(__phi)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (std::abs(__k) > _Tp(1)) + std::__throw_domain_error(__N("Bad argument in __ellint_3.")); + else + { + // Reduce phi to -pi/2 < phi < +pi/2. + const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() + + _Tp(0.5L)); + const _Tp __phi_red = __phi + - __n * __numeric_constants<_Tp>::__pi(); + + const _Tp __kk = __k * __k; + const _Tp __s = std::sin(__phi_red); + const _Tp __ss = __s * __s; + const _Tp __sss = __ss * __s; + const _Tp __c = std::cos(__phi_red); + const _Tp __cc = __c * __c; + + const _Tp __Pi = __s + * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1)) + - __nu * __sss + * __ellint_rj(__cc, _Tp(1) - __kk * __ss, _Tp(1), + _Tp(1) + __nu * __ss) / _Tp(3); + + if (__n == 0) + return __Pi; + else + return __Pi + _Tp(2) * __n * __comp_ellint_3(__k, __nu); + } + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_ELL_INTEGRAL_TCC + diff --git a/libstdc++-v3/include/tr1/exp_integral.tcc b/libstdc++-v3/include/tr1/exp_integral.tcc new file mode 100644 index 000000000..cf3bd6353 --- /dev/null +++ b/libstdc++-v3/include/tr1/exp_integral.tcc @@ -0,0 +1,525 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/exp_integral.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// +// (1) Handbook of Mathematical Functions, +// Ed. by Milton Abramowitz and Irene A. Stegun, +// Dover Publications, New-York, Section 5, pp. 228-251. +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky, +// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992), +// 2nd ed, pp. 222-225. +// + +#ifndef _GLIBCXX_TR1_EXP_INTEGRAL_TCC +#define _GLIBCXX_TR1_EXP_INTEGRAL_TCC 1 + +#include "special_function_util.h" + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Return the exponential integral @f$ E_1(x) @f$ + * by series summation. This should be good + * for @f$ x < 1 @f$. + * + * The exponential integral is given by + * \f[ + * E_1(x) = \int_{1}^{\infty} \frac{e^{-xt}}{t} dt + * \f] + * + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_E1_series(const _Tp __x) + { + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + _Tp __term = _Tp(1); + _Tp __esum = _Tp(0); + _Tp __osum = _Tp(0); + const unsigned int __max_iter = 100; + for (unsigned int __i = 1; __i < __max_iter; ++__i) + { + __term *= - __x / __i; + if (std::abs(__term) < __eps) + break; + if (__term >= _Tp(0)) + __esum += __term / __i; + else + __osum += __term / __i; + } + + return - __esum - __osum + - __numeric_constants<_Tp>::__gamma_e() - std::log(__x); + } + + + /** + * @brief Return the exponential integral @f$ E_1(x) @f$ + * by asymptotic expansion. + * + * The exponential integral is given by + * \f[ + * E_1(x) = \int_{1}^\infty \frac{e^{-xt}}{t} dt + * \f] + * + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_E1_asymp(const _Tp __x) + { + _Tp __term = _Tp(1); + _Tp __esum = _Tp(1); + _Tp __osum = _Tp(0); + const unsigned int __max_iter = 1000; + for (unsigned int __i = 1; __i < __max_iter; ++__i) + { + _Tp __prev = __term; + __term *= - __i / __x; + if (std::abs(__term) > std::abs(__prev)) + break; + if (__term >= _Tp(0)) + __esum += __term; + else + __osum += __term; + } + + return std::exp(- __x) * (__esum + __osum) / __x; + } + + + /** + * @brief Return the exponential integral @f$ E_n(x) @f$ + * by series summation. + * + * The exponential integral is given by + * \f[ + * E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt + * \f] + * + * @param __n The order of the exponential integral function. + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_En_series(const unsigned int __n, const _Tp __x) + { + const unsigned int __max_iter = 100; + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const int __nm1 = __n - 1; + _Tp __ans = (__nm1 != 0 + ? _Tp(1) / __nm1 : -std::log(__x) + - __numeric_constants<_Tp>::__gamma_e()); + _Tp __fact = _Tp(1); + for (int __i = 1; __i <= __max_iter; ++__i) + { + __fact *= -__x / _Tp(__i); + _Tp __del; + if ( __i != __nm1 ) + __del = -__fact / _Tp(__i - __nm1); + else + { + _Tp __psi = -__numeric_constants<_Tp>::gamma_e(); + for (int __ii = 1; __ii <= __nm1; ++__ii) + __psi += _Tp(1) / _Tp(__ii); + __del = __fact * (__psi - std::log(__x)); + } + __ans += __del; + if (std::abs(__del) < __eps * std::abs(__ans)) + return __ans; + } + std::__throw_runtime_error(__N("Series summation failed " + "in __expint_En_series.")); + } + + + /** + * @brief Return the exponential integral @f$ E_n(x) @f$ + * by continued fractions. + * + * The exponential integral is given by + * \f[ + * E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt + * \f] + * + * @param __n The order of the exponential integral function. + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_En_cont_frac(const unsigned int __n, const _Tp __x) + { + const unsigned int __max_iter = 100; + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __fp_min = std::numeric_limits<_Tp>::min(); + const int __nm1 = __n - 1; + _Tp __b = __x + _Tp(__n); + _Tp __c = _Tp(1) / __fp_min; + _Tp __d = _Tp(1) / __b; + _Tp __h = __d; + for ( unsigned int __i = 1; __i <= __max_iter; ++__i ) + { + _Tp __a = -_Tp(__i * (__nm1 + __i)); + __b += _Tp(2); + __d = _Tp(1) / (__a * __d + __b); + __c = __b + __a / __c; + const _Tp __del = __c * __d; + __h *= __del; + if (std::abs(__del - _Tp(1)) < __eps) + { + const _Tp __ans = __h * std::exp(-__x); + return __ans; + } + } + std::__throw_runtime_error(__N("Continued fraction failed " + "in __expint_En_cont_frac.")); + } + + + /** + * @brief Return the exponential integral @f$ E_n(x) @f$ + * by recursion. Use upward recursion for @f$ x < n @f$ + * and downward recursion (Miller's algorithm) otherwise. + * + * The exponential integral is given by + * \f[ + * E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt + * \f] + * + * @param __n The order of the exponential integral function. + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_En_recursion(const unsigned int __n, const _Tp __x) + { + _Tp __En; + _Tp __E1 = __expint_E1(__x); + if (__x < _Tp(__n)) + { + // Forward recursion is stable only for n < x. + __En = __E1; + for (unsigned int __j = 2; __j < __n; ++__j) + __En = (std::exp(-__x) - __x * __En) / _Tp(__j - 1); + } + else + { + // Backward recursion is stable only for n >= x. + __En = _Tp(1); + const int __N = __n + 20; // TODO: Check this starting number. + _Tp __save = _Tp(0); + for (int __j = __N; __j > 0; --__j) + { + __En = (std::exp(-__x) - __j * __En) / __x; + if (__j == __n) + __save = __En; + } + _Tp __norm = __En / __E1; + __En /= __norm; + } + + return __En; + } + + /** + * @brief Return the exponential integral @f$ Ei(x) @f$ + * by series summation. + * + * The exponential integral is given by + * \f[ + * Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt + * \f] + * + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_Ei_series(const _Tp __x) + { + _Tp __term = _Tp(1); + _Tp __sum = _Tp(0); + const unsigned int __max_iter = 1000; + for (unsigned int __i = 1; __i < __max_iter; ++__i) + { + __term *= __x / __i; + __sum += __term / __i; + if (__term < std::numeric_limits<_Tp>::epsilon() * __sum) + break; + } + + return __numeric_constants<_Tp>::__gamma_e() + __sum + std::log(__x); + } + + + /** + * @brief Return the exponential integral @f$ Ei(x) @f$ + * by asymptotic expansion. + * + * The exponential integral is given by + * \f[ + * Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt + * \f] + * + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_Ei_asymp(const _Tp __x) + { + _Tp __term = _Tp(1); + _Tp __sum = _Tp(1); + const unsigned int __max_iter = 1000; + for (unsigned int __i = 1; __i < __max_iter; ++__i) + { + _Tp __prev = __term; + __term *= __i / __x; + if (__term < std::numeric_limits<_Tp>::epsilon()) + break; + if (__term >= __prev) + break; + __sum += __term; + } + + return std::exp(__x) * __sum / __x; + } + + + /** + * @brief Return the exponential integral @f$ Ei(x) @f$. + * + * The exponential integral is given by + * \f[ + * Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt + * \f] + * + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_Ei(const _Tp __x) + { + if (__x < _Tp(0)) + return -__expint_E1(-__x); + else if (__x < -std::log(std::numeric_limits<_Tp>::epsilon())) + return __expint_Ei_series(__x); + else + return __expint_Ei_asymp(__x); + } + + + /** + * @brief Return the exponential integral @f$ E_1(x) @f$. + * + * The exponential integral is given by + * \f[ + * E_1(x) = \int_{1}^\infty \frac{e^{-xt}}{t} dt + * \f] + * + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_E1(const _Tp __x) + { + if (__x < _Tp(0)) + return -__expint_Ei(-__x); + else if (__x < _Tp(1)) + return __expint_E1_series(__x); + else if (__x < _Tp(100)) // TODO: Find a good asymptotic switch point. + return __expint_En_cont_frac(1, __x); + else + return __expint_E1_asymp(__x); + } + + + /** + * @brief Return the exponential integral @f$ E_n(x) @f$ + * for large argument. + * + * The exponential integral is given by + * \f[ + * E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt + * \f] + * + * This is something of an extension. + * + * @param __n The order of the exponential integral function. + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_asymp(const unsigned int __n, const _Tp __x) + { + _Tp __term = _Tp(1); + _Tp __sum = _Tp(1); + for (unsigned int __i = 1; __i <= __n; ++__i) + { + _Tp __prev = __term; + __term *= -(__n - __i + 1) / __x; + if (std::abs(__term) > std::abs(__prev)) + break; + __sum += __term; + } + + return std::exp(-__x) * __sum / __x; + } + + + /** + * @brief Return the exponential integral @f$ E_n(x) @f$ + * for large order. + * + * The exponential integral is given by + * \f[ + * E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt + * \f] + * + * This is something of an extension. + * + * @param __n The order of the exponential integral function. + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint_large_n(const unsigned int __n, const _Tp __x) + { + const _Tp __xpn = __x + __n; + const _Tp __xpn2 = __xpn * __xpn; + _Tp __term = _Tp(1); + _Tp __sum = _Tp(1); + for (unsigned int __i = 1; __i <= __n; ++__i) + { + _Tp __prev = __term; + __term *= (__n - 2 * (__i - 1) * __x) / __xpn2; + if (std::abs(__term) < std::numeric_limits<_Tp>::epsilon()) + break; + __sum += __term; + } + + return std::exp(-__x) * __sum / __xpn; + } + + + /** + * @brief Return the exponential integral @f$ E_n(x) @f$. + * + * The exponential integral is given by + * \f[ + * E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt + * \f] + * This is something of an extension. + * + * @param __n The order of the exponential integral function. + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + _Tp + __expint(const unsigned int __n, const _Tp __x) + { + // Return NaN on NaN input. + if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__n <= 1 && __x == _Tp(0)) + return std::numeric_limits<_Tp>::infinity(); + else + { + _Tp __E0 = std::exp(__x) / __x; + if (__n == 0) + return __E0; + + _Tp __E1 = __expint_E1(__x); + if (__n == 1) + return __E1; + + if (__x == _Tp(0)) + return _Tp(1) / static_cast<_Tp>(__n - 1); + + _Tp __En = __expint_En_recursion(__n, __x); + + return __En; + } + } + + + /** + * @brief Return the exponential integral @f$ Ei(x) @f$. + * + * The exponential integral is given by + * \f[ + * Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt + * \f] + * + * @param __x The argument of the exponential integral function. + * @return The exponential integral. + */ + template<typename _Tp> + inline _Tp + __expint(const _Tp __x) + { + if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else + return __expint_Ei(__x); + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_EXP_INTEGRAL_TCC diff --git a/libstdc++-v3/include/tr1/fenv.h b/libstdc++-v3/include/tr1/fenv.h new file mode 100644 index 000000000..118630e49 --- /dev/null +++ b/libstdc++-v3/include/tr1/fenv.h @@ -0,0 +1,34 @@ +// TR1 fenv.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/fenv.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_FENV_H +#define _TR1_FENV_H 1 + +#include <tr1/cfenv> + +#endif diff --git a/libstdc++-v3/include/tr1/float.h b/libstdc++-v3/include/tr1/float.h new file mode 100644 index 000000000..bbeff6e3a --- /dev/null +++ b/libstdc++-v3/include/tr1/float.h @@ -0,0 +1,34 @@ +// TR1 float.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/float.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_FLOAT_H +#define _TR1_FLOAT_H 1 + +#include <tr1/cfloat> + +#endif diff --git a/libstdc++-v3/include/tr1/functional b/libstdc++-v3/include/tr1/functional new file mode 100644 index 000000000..31e72d63a --- /dev/null +++ b/libstdc++-v3/include/tr1/functional @@ -0,0 +1,2149 @@ +// TR1 functional header -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/functional + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_FUNCTIONAL +#define _GLIBCXX_TR1_FUNCTIONAL 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/stl_function.h> + +#include <typeinfo> +#include <new> +#include <tr1/tuple> +#include <tr1/type_traits> +#include <bits/stringfwd.h> +#include <tr1/functional_hash.h> +#include <ext/type_traits.h> +#include <bits/move.h> // for std::__addressof + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<typename _MemberPointer> + class _Mem_fn; + + /** + * Actual implementation of _Has_result_type, which uses SFINAE to + * determine if the type _Tp has a publicly-accessible member type + * result_type. + */ + template<typename _Tp> + class _Has_result_type_helper : __sfinae_types + { + template<typename _Up> + struct _Wrap_type + { }; + + template<typename _Up> + static __one __test(_Wrap_type<typename _Up::result_type>*); + + template<typename _Up> + static __two __test(...); + + public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; + }; + + template<typename _Tp> + struct _Has_result_type + : integral_constant<bool, + _Has_result_type_helper<typename remove_cv<_Tp>::type>::value> + { }; + + /** + * + */ + /// If we have found a result_type, extract it. + template<bool _Has_result_type, typename _Functor> + struct _Maybe_get_result_type + { }; + + template<typename _Functor> + struct _Maybe_get_result_type<true, _Functor> + { + typedef typename _Functor::result_type result_type; + }; + + /** + * Base class for any function object that has a weak result type, as + * defined in 3.3/3 of TR1. + */ + template<typename _Functor> + struct _Weak_result_type_impl + : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor> + { + }; + + /// Retrieve the result type for a function type. + template<typename _Res, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /// Retrieve the result type for a function reference. + template<typename _Res, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /// Retrieve the result type for a function pointer. + template<typename _Res, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /// Retrieve result type for a member function pointer. + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)> + { + typedef _Res result_type; + }; + + /// Retrieve result type for a const member function pointer. + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const> + { + typedef _Res result_type; + }; + + /// Retrieve result type for a volatile member function pointer. + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile> + { + typedef _Res result_type; + }; + + /// Retrieve result type for a const volatile member function pointer. + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)const volatile> + { + typedef _Res result_type; + }; + + /** + * Strip top-level cv-qualifiers from the function object and let + * _Weak_result_type_impl perform the real work. + */ + template<typename _Functor> + struct _Weak_result_type + : _Weak_result_type_impl<typename remove_cv<_Functor>::type> + { + }; + + template<typename _Signature> + class result_of; + + /** + * Actual implementation of result_of. When _Has_result_type is + * true, gets its result from _Weak_result_type. Otherwise, uses + * the function object's member template result to extract the + * result type. + */ + template<bool _Has_result_type, typename _Signature> + struct _Result_of_impl; + + // Handle member data pointers using _Mem_fn's logic + template<typename _Res, typename _Class, typename _T1> + struct _Result_of_impl<false, _Res _Class::*(_T1)> + { + typedef typename _Mem_fn<_Res _Class::*> + ::template _Result_type<_T1>::type type; + }; + + /** + * Determine whether we can determine a result type from @c Functor + * alone. + */ + template<typename _Functor, typename... _ArgTypes> + class result_of<_Functor(_ArgTypes...)> + : public _Result_of_impl< + _Has_result_type<_Weak_result_type<_Functor> >::value, + _Functor(_ArgTypes...)> + { + }; + + /// We already know the result type for @c Functor; use it. + template<typename _Functor, typename... _ArgTypes> + struct _Result_of_impl<true, _Functor(_ArgTypes...)> + { + typedef typename _Weak_result_type<_Functor>::result_type type; + }; + + /** + * We need to compute the result type for this invocation the hard + * way. + */ + template<typename _Functor, typename... _ArgTypes> + struct _Result_of_impl<false, _Functor(_ArgTypes...)> + { + typedef typename _Functor + ::template result<_Functor(_ArgTypes...)>::type type; + }; + + /** + * It is unsafe to access ::result when there are zero arguments, so we + * return @c void instead. + */ + template<typename _Functor> + struct _Result_of_impl<false, _Functor()> + { + typedef void type; + }; + + /// Determines if the type _Tp derives from unary_function. + template<typename _Tp> + struct _Derives_from_unary_function : __sfinae_types + { + private: + template<typename _T1, typename _Res> + static __one __test(const volatile unary_function<_T1, _Res>*); + + // It's tempting to change "..." to const volatile void*, but + // that fails when _Tp is a function type. + static __two __test(...); + + public: + static const bool value = sizeof(__test((_Tp*)0)) == 1; + }; + + /// Determines if the type _Tp derives from binary_function. + template<typename _Tp> + struct _Derives_from_binary_function : __sfinae_types + { + private: + template<typename _T1, typename _T2, typename _Res> + static __one __test(const volatile binary_function<_T1, _T2, _Res>*); + + // It's tempting to change "..." to const volatile void*, but + // that fails when _Tp is a function type. + static __two __test(...); + + public: + static const bool value = sizeof(__test((_Tp*)0)) == 1; + }; + + /// Turns a function type into a function pointer type + template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value> + struct _Function_to_function_pointer + { + typedef _Tp type; + }; + + template<typename _Tp> + struct _Function_to_function_pointer<_Tp, true> + { + typedef _Tp* type; + }; + + /** + * Invoke a function object, which may be either a member pointer or a + * function object. The first parameter will tell which. + */ + template<typename _Functor, typename... _Args> + inline + typename __gnu_cxx::__enable_if< + (!is_member_pointer<_Functor>::value + && !is_function<_Functor>::value + && !is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_Args...)>::type + >::__type + __invoke(_Functor& __f, _Args&... __args) + { + return __f(__args...); + } + + template<typename _Functor, typename... _Args> + inline + typename __gnu_cxx::__enable_if< + (is_member_pointer<_Functor>::value + && !is_function<_Functor>::value + && !is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_Args...)>::type + >::__type + __invoke(_Functor& __f, _Args&... __args) + { + return mem_fn(__f)(__args...); + } + + // To pick up function references (that will become function pointers) + template<typename _Functor, typename... _Args> + inline + typename __gnu_cxx::__enable_if< + (is_pointer<_Functor>::value + && is_function<typename remove_pointer<_Functor>::type>::value), + typename result_of<_Functor(_Args...)>::type + >::__type + __invoke(_Functor __f, _Args&... __args) + { + return __f(__args...); + } + + /** + * Knowing which of unary_function and binary_function _Tp derives + * from, derives from the same and ensures that reference_wrapper + * will have a weak result type. See cases below. + */ + template<bool _Unary, bool _Binary, typename _Tp> + struct _Reference_wrapper_base_impl; + + // Not a unary_function or binary_function, so try a weak result type. + template<typename _Tp> + struct _Reference_wrapper_base_impl<false, false, _Tp> + : _Weak_result_type<_Tp> + { }; + + // unary_function but not binary_function + template<typename _Tp> + struct _Reference_wrapper_base_impl<true, false, _Tp> + : unary_function<typename _Tp::argument_type, + typename _Tp::result_type> + { }; + + // binary_function but not unary_function + template<typename _Tp> + struct _Reference_wrapper_base_impl<false, true, _Tp> + : binary_function<typename _Tp::first_argument_type, + typename _Tp::second_argument_type, + typename _Tp::result_type> + { }; + + // Both unary_function and binary_function. Import result_type to + // avoid conflicts. + template<typename _Tp> + struct _Reference_wrapper_base_impl<true, true, _Tp> + : unary_function<typename _Tp::argument_type, + typename _Tp::result_type>, + binary_function<typename _Tp::first_argument_type, + typename _Tp::second_argument_type, + typename _Tp::result_type> + { + typedef typename _Tp::result_type result_type; + }; + + /** + * Derives from unary_function or binary_function when it + * can. Specializations handle all of the easy cases. The primary + * template determines what to do with a class type, which may + * derive from both unary_function and binary_function. + */ + template<typename _Tp> + struct _Reference_wrapper_base + : _Reference_wrapper_base_impl< + _Derives_from_unary_function<_Tp>::value, + _Derives_from_binary_function<_Tp>::value, + _Tp> + { }; + + // - a function type (unary) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res(_T1)> + : unary_function<_T1, _Res> + { }; + + // - a function type (binary) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res(_T1, _T2)> + : binary_function<_T1, _T2, _Res> + { }; + + // - a function pointer type (unary) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res(*)(_T1)> + : unary_function<_T1, _Res> + { }; + + // - a function pointer type (binary) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res(*)(_T1, _T2)> + : binary_function<_T1, _T2, _Res> + { }; + + // - a pointer to member function type (unary, no qualifiers) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)()> + : unary_function<_T1*, _Res> + { }; + + // - a pointer to member function type (binary, no qualifiers) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2)> + : binary_function<_T1*, _T2, _Res> + { }; + + // - a pointer to member function type (unary, const) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)() const> + : unary_function<const _T1*, _Res> + { }; + + // - a pointer to member function type (binary, const) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const> + : binary_function<const _T1*, _T2, _Res> + { }; + + // - a pointer to member function type (unary, volatile) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)() volatile> + : unary_function<volatile _T1*, _Res> + { }; + + // - a pointer to member function type (binary, volatile) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile> + : binary_function<volatile _T1*, _T2, _Res> + { }; + + // - a pointer to member function type (unary, const volatile) + template<typename _Res, typename _T1> + struct _Reference_wrapper_base<_Res (_T1::*)() const volatile> + : unary_function<const volatile _T1*, _Res> + { }; + + // - a pointer to member function type (binary, const volatile) + template<typename _Res, typename _T1, typename _T2> + struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile> + : binary_function<const volatile _T1*, _T2, _Res> + { }; + + /// reference_wrapper + template<typename _Tp> + class reference_wrapper + : public _Reference_wrapper_base<typename remove_cv<_Tp>::type> + { + // If _Tp is a function type, we can't form result_of<_Tp(...)>, + // so turn it into a function pointer type. + typedef typename _Function_to_function_pointer<_Tp>::type + _M_func_type; + + _Tp* _M_data; + public: + typedef _Tp type; + + explicit + reference_wrapper(_Tp& __indata) + : _M_data(std::__addressof(__indata)) + { } + + reference_wrapper(const reference_wrapper<_Tp>& __inref): + _M_data(__inref._M_data) + { } + + reference_wrapper& + operator=(const reference_wrapper<_Tp>& __inref) + { + _M_data = __inref._M_data; + return *this; + } + + operator _Tp&() const + { return this->get(); } + + _Tp& + get() const + { return *_M_data; } + + template<typename... _Args> + typename result_of<_M_func_type(_Args...)>::type + operator()(_Args&... __args) const + { + return __invoke(get(), __args...); + } + }; + + + // Denotes a reference should be taken to a variable. + template<typename _Tp> + inline reference_wrapper<_Tp> + ref(_Tp& __t) + { return reference_wrapper<_Tp>(__t); } + + // Denotes a const reference should be taken to a variable. + template<typename _Tp> + inline reference_wrapper<const _Tp> + cref(const _Tp& __t) + { return reference_wrapper<const _Tp>(__t); } + + template<typename _Tp> + inline reference_wrapper<_Tp> + ref(reference_wrapper<_Tp> __t) + { return ref(__t.get()); } + + template<typename _Tp> + inline reference_wrapper<const _Tp> + cref(reference_wrapper<_Tp> __t) + { return cref(__t.get()); } + + template<typename _Tp, bool> + struct _Mem_fn_const_or_non + { + typedef const _Tp& type; + }; + + template<typename _Tp> + struct _Mem_fn_const_or_non<_Tp, false> + { + typedef _Tp& type; + }; + + /** + * Derives from @c unary_function or @c binary_function, or perhaps + * nothing, depending on the number of arguments provided. The + * primary template is the basis case, which derives nothing. + */ + template<typename _Res, typename... _ArgTypes> + struct _Maybe_unary_or_binary_function { }; + + /// Derives from @c unary_function, as appropriate. + template<typename _Res, typename _T1> + struct _Maybe_unary_or_binary_function<_Res, _T1> + : std::unary_function<_T1, _Res> { }; + + /// Derives from @c binary_function, as appropriate. + template<typename _Res, typename _T1, typename _T2> + struct _Maybe_unary_or_binary_function<_Res, _T1, _T2> + : std::binary_function<_T1, _T2, _Res> { }; + + /// Implementation of @c mem_fn for member function pointers. + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...)> + : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...); + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { } + + // Handle objects + _Res + operator()(_Class& __object, _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + // Handle pointers + _Res + operator()(_Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res + operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + /// Implementation of @c mem_fn for const member function pointers. + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const> + : public _Maybe_unary_or_binary_function<_Res, const _Class*, + _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...) const; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { } + + // Handle objects + _Res + operator()(const _Class& __object, _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + // Handle pointers + _Res + operator()(const _Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + /// Implementation of @c mem_fn for volatile member function pointers. + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile> + : public _Maybe_unary_or_binary_function<_Res, volatile _Class*, + _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { } + + // Handle objects + _Res + operator()(volatile _Class& __object, _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + // Handle pointers + _Res + operator()(volatile _Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res + operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + /// Implementation of @c mem_fn for const volatile member function pointers. + template<typename _Res, typename _Class, typename... _ArgTypes> + class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile> + : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*, + _ArgTypes...> + { + typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile; + + template<typename _Tp> + _Res + _M_call(_Tp& __object, const volatile _Class *, + _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + template<typename _Tp> + _Res + _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const + { return ((*__ptr).*__pmf)(__args...); } + + public: + typedef _Res result_type; + + explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { } + + // Handle objects + _Res + operator()(const volatile _Class& __object, _ArgTypes... __args) const + { return (__object.*__pmf)(__args...); } + + // Handle pointers + _Res + operator()(const volatile _Class* __object, _ArgTypes... __args) const + { return (__object->*__pmf)(__args...); } + + // Handle smart pointers, references and pointers to derived + template<typename _Tp> + _Res operator()(_Tp& __object, _ArgTypes... __args) const + { return _M_call(__object, &__object, __args...); } + + private: + _Functor __pmf; + }; + + + template<typename _Res, typename _Class> + class _Mem_fn<_Res _Class::*> + { + // This bit of genius is due to Peter Dimov, improved slightly by + // Douglas Gregor. + template<typename _Tp> + _Res& + _M_call(_Tp& __object, _Class *) const + { return __object.*__pm; } + + template<typename _Tp, typename _Up> + _Res& + _M_call(_Tp& __object, _Up * const *) const + { return (*__object).*__pm; } + + template<typename _Tp, typename _Up> + const _Res& + _M_call(_Tp& __object, const _Up * const *) const + { return (*__object).*__pm; } + + template<typename _Tp> + const _Res& + _M_call(_Tp& __object, const _Class *) const + { return __object.*__pm; } + + template<typename _Tp> + const _Res& + _M_call(_Tp& __ptr, const volatile void*) const + { return (*__ptr).*__pm; } + + template<typename _Tp> static _Tp& __get_ref(); + + template<typename _Tp> + static __sfinae_types::__one __check_const(_Tp&, _Class*); + template<typename _Tp, typename _Up> + static __sfinae_types::__one __check_const(_Tp&, _Up * const *); + template<typename _Tp, typename _Up> + static __sfinae_types::__two __check_const(_Tp&, const _Up * const *); + template<typename _Tp> + static __sfinae_types::__two __check_const(_Tp&, const _Class*); + template<typename _Tp> + static __sfinae_types::__two __check_const(_Tp&, const volatile void*); + + public: + template<typename _Tp> + struct _Result_type + : _Mem_fn_const_or_non<_Res, + (sizeof(__sfinae_types::__two) + == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))> + { }; + + template<typename _Signature> + struct result; + + template<typename _CVMem, typename _Tp> + struct result<_CVMem(_Tp)> + : public _Result_type<_Tp> { }; + + template<typename _CVMem, typename _Tp> + struct result<_CVMem(_Tp&)> + : public _Result_type<_Tp> { }; + + explicit + _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { } + + // Handle objects + _Res& + operator()(_Class& __object) const + { return __object.*__pm; } + + const _Res& + operator()(const _Class& __object) const + { return __object.*__pm; } + + // Handle pointers + _Res& + operator()(_Class* __object) const + { return __object->*__pm; } + + const _Res& + operator()(const _Class* __object) const + { return __object->*__pm; } + + // Handle smart pointers and derived + template<typename _Tp> + typename _Result_type<_Tp>::type + operator()(_Tp& __unknown) const + { return _M_call(__unknown, &__unknown); } + + private: + _Res _Class::*__pm; + }; + + /** + * @brief Returns a function object that forwards to the member + * pointer @a pm. + */ + template<typename _Tp, typename _Class> + inline _Mem_fn<_Tp _Class::*> + mem_fn(_Tp _Class::* __pm) + { + return _Mem_fn<_Tp _Class::*>(__pm); + } + + /** + * @brief Determines if the given type _Tp is a function object + * should be treated as a subexpression when evaluating calls to + * function objects returned by bind(). [TR1 3.6.1] + */ + template<typename _Tp> + struct is_bind_expression + { static const bool value = false; }; + + template<typename _Tp> + const bool is_bind_expression<_Tp>::value; + + /** + * @brief Determines if the given type _Tp is a placeholder in a + * bind() expression and, if so, which placeholder it is. [TR1 3.6.2] + */ + template<typename _Tp> + struct is_placeholder + { static const int value = 0; }; + + template<typename _Tp> + const int is_placeholder<_Tp>::value; + + /// The type of placeholder objects defined by libstdc++. + template<int _Num> struct _Placeholder { }; + +_GLIBCXX_END_NAMESPACE_VERSION + + /** @namespace std::placeholders + * @brief ISO C++ 0x entities sub namespace for functional. + * + * Define a large number of placeholders. There is no way to + * simplify this with variadic templates, because we're introducing + * unique names for each. + */ + namespace placeholders + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + namespace + { + _Placeholder<1> _1; + _Placeholder<2> _2; + _Placeholder<3> _3; + _Placeholder<4> _4; + _Placeholder<5> _5; + _Placeholder<6> _6; + _Placeholder<7> _7; + _Placeholder<8> _8; + _Placeholder<9> _9; + _Placeholder<10> _10; + _Placeholder<11> _11; + _Placeholder<12> _12; + _Placeholder<13> _13; + _Placeholder<14> _14; + _Placeholder<15> _15; + _Placeholder<16> _16; + _Placeholder<17> _17; + _Placeholder<18> _18; + _Placeholder<19> _19; + _Placeholder<20> _20; + _Placeholder<21> _21; + _Placeholder<22> _22; + _Placeholder<23> _23; + _Placeholder<24> _24; + _Placeholder<25> _25; + _Placeholder<26> _26; + _Placeholder<27> _27; + _Placeholder<28> _28; + _Placeholder<29> _29; + } + _GLIBCXX_END_NAMESPACE_VERSION + } + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + /** + * Partial specialization of is_placeholder that provides the placeholder + * number for the placeholder objects defined by libstdc++. + */ + template<int _Num> + struct is_placeholder<_Placeholder<_Num> > + { static const int value = _Num; }; + + template<int _Num> + const int is_placeholder<_Placeholder<_Num> >::value; + + /** + * Stores a tuple of indices. Used by bind() to extract the elements + * in a tuple. + */ + template<int... _Indexes> + struct _Index_tuple { }; + + /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. + template<std::size_t _Num, typename _Tuple = _Index_tuple<> > + struct _Build_index_tuple; + + template<std::size_t _Num, int... _Indexes> + struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> > + : _Build_index_tuple<_Num - 1, + _Index_tuple<_Indexes..., sizeof...(_Indexes)> > + { + }; + + template<int... _Indexes> + struct _Build_index_tuple<0, _Index_tuple<_Indexes...> > + { + typedef _Index_tuple<_Indexes...> __type; + }; + + /** + * Used by _Safe_tuple_element to indicate that there is no tuple + * element at this position. + */ + struct _No_tuple_element; + + /** + * Implementation helper for _Safe_tuple_element. This primary + * template handles the case where it is safe to use @c + * tuple_element. + */ + template<int __i, typename _Tuple, bool _IsSafe> + struct _Safe_tuple_element_impl + : tuple_element<__i, _Tuple> { }; + + /** + * Implementation helper for _Safe_tuple_element. This partial + * specialization handles the case where it is not safe to use @c + * tuple_element. We just return @c _No_tuple_element. + */ + template<int __i, typename _Tuple> + struct _Safe_tuple_element_impl<__i, _Tuple, false> + { + typedef _No_tuple_element type; + }; + + /** + * Like tuple_element, but returns @c _No_tuple_element when + * tuple_element would return an error. + */ + template<int __i, typename _Tuple> + struct _Safe_tuple_element + : _Safe_tuple_element_impl<__i, _Tuple, + (__i >= 0 && __i < tuple_size<_Tuple>::value)> + { + }; + + /** + * Maps an argument to bind() into an actual argument to the bound + * function object [TR1 3.6.3/5]. Only the first parameter should + * be specified: the rest are used to determine among the various + * implementations. Note that, although this class is a function + * object, it isn't entirely normal because it takes only two + * parameters regardless of the number of parameters passed to the + * bind expression. The first parameter is the bound argument and + * the second parameter is a tuple containing references to the + * rest of the arguments. + */ + template<typename _Arg, + bool _IsBindExp = is_bind_expression<_Arg>::value, + bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> + class _Mu; + + /** + * If the argument is reference_wrapper<_Tp>, returns the + * underlying reference. [TR1 3.6.3/5 bullet 1] + */ + template<typename _Tp> + class _Mu<reference_wrapper<_Tp>, false, false> + { + public: + typedef _Tp& result_type; + + /* Note: This won't actually work for const volatile + * reference_wrappers, because reference_wrapper::get() is const + * but not volatile-qualified. This might be a defect in the TR. + */ + template<typename _CVRef, typename _Tuple> + result_type + operator()(_CVRef& __arg, const _Tuple&) const volatile + { return __arg.get(); } + }; + + /** + * If the argument is a bind expression, we invoke the underlying + * function object with the same cv-qualifiers as we are given and + * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2] + */ + template<typename _Arg> + class _Mu<_Arg, true, false> + { + public: + template<typename _Signature> class result; + + // Determine the result type when we pass the arguments along. This + // involves passing along the cv-qualifiers placed on _Mu and + // unwrapping the argument bundle. + template<typename _CVMu, typename _CVArg, typename... _Args> + class result<_CVMu(_CVArg, tuple<_Args...>)> + : public result_of<_CVArg(_Args...)> { }; + + template<typename _CVArg, typename... _Args> + typename result_of<_CVArg(_Args...)>::type + operator()(_CVArg& __arg, + const tuple<_Args...>& __tuple) const volatile + { + // Construct an index tuple and forward to __call + typedef typename _Build_index_tuple<sizeof...(_Args)>::__type + _Indexes; + return this->__call(__arg, __tuple, _Indexes()); + } + + private: + // Invokes the underlying function object __arg by unpacking all + // of the arguments in the tuple. + template<typename _CVArg, typename... _Args, int... _Indexes> + typename result_of<_CVArg(_Args...)>::type + __call(_CVArg& __arg, const tuple<_Args...>& __tuple, + const _Index_tuple<_Indexes...>&) const volatile + { + return __arg(tr1::get<_Indexes>(__tuple)...); + } + }; + + /** + * If the argument is a placeholder for the Nth argument, returns + * a reference to the Nth argument to the bind function object. + * [TR1 3.6.3/5 bullet 3] + */ + template<typename _Arg> + class _Mu<_Arg, false, true> + { + public: + template<typename _Signature> class result; + + template<typename _CVMu, typename _CVArg, typename _Tuple> + class result<_CVMu(_CVArg, _Tuple)> + { + // Add a reference, if it hasn't already been done for us. + // This allows us to be a little bit sloppy in constructing + // the tuple that we pass to result_of<...>. + typedef typename _Safe_tuple_element<(is_placeholder<_Arg>::value + - 1), _Tuple>::type + __base_type; + + public: + typedef typename add_reference<__base_type>::type type; + }; + + template<typename _Tuple> + typename result<_Mu(_Arg, _Tuple)>::type + operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile + { + return ::std::tr1::get<(is_placeholder<_Arg>::value - 1)>(__tuple); + } + }; + + /** + * If the argument is just a value, returns a reference to that + * value. The cv-qualifiers on the reference are the same as the + * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4] + */ + template<typename _Arg> + class _Mu<_Arg, false, false> + { + public: + template<typename _Signature> struct result; + + template<typename _CVMu, typename _CVArg, typename _Tuple> + struct result<_CVMu(_CVArg, _Tuple)> + { + typedef typename add_reference<_CVArg>::type type; + }; + + // Pick up the cv-qualifiers of the argument + template<typename _CVArg, typename _Tuple> + _CVArg& + operator()(_CVArg& __arg, const _Tuple&) const volatile + { return __arg; } + }; + + /** + * Maps member pointers into instances of _Mem_fn but leaves all + * other function objects untouched. Used by tr1::bind(). The + * primary template handles the non--member-pointer case. + */ + template<typename _Tp> + struct _Maybe_wrap_member_pointer + { + typedef _Tp type; + + static const _Tp& + __do_wrap(const _Tp& __x) + { return __x; } + }; + + /** + * Maps member pointers into instances of _Mem_fn but leaves all + * other function objects untouched. Used by tr1::bind(). This + * partial specialization handles the member pointer case. + */ + template<typename _Tp, typename _Class> + struct _Maybe_wrap_member_pointer<_Tp _Class::*> + { + typedef _Mem_fn<_Tp _Class::*> type; + + static type + __do_wrap(_Tp _Class::* __pm) + { return type(__pm); } + }; + + /// Type of the function object returned from bind(). + template<typename _Signature> + struct _Bind; + + template<typename _Functor, typename... _Bound_args> + class _Bind<_Functor(_Bound_args...)> + : public _Weak_result_type<_Functor> + { + typedef _Bind __self_type; + typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type + _Bound_indexes; + + _Functor _M_f; + tuple<_Bound_args...> _M_bound_args; + + // Call unqualified + template<typename... _Args, int... _Indexes> + typename result_of< + _Functor(typename result_of<_Mu<_Bound_args> + (_Bound_args, tuple<_Args...>)>::type...) + >::type + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const + template<typename... _Args, int... _Indexes> + typename result_of< + const _Functor(typename result_of<_Mu<_Bound_args> + (const _Bound_args, tuple<_Args...>) + >::type...)>::type + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as volatile + template<typename... _Args, int... _Indexes> + typename result_of< + volatile _Functor(typename result_of<_Mu<_Bound_args> + (volatile _Bound_args, tuple<_Args...>) + >::type...)>::type + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) volatile + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const volatile + template<typename... _Args, int... _Indexes> + typename result_of< + const volatile _Functor(typename result_of<_Mu<_Bound_args> + (const volatile _Bound_args, + tuple<_Args...>) + >::type...)>::type + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) const volatile + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + public: + explicit _Bind(_Functor __f, _Bound_args... __bound_args) + : _M_f(__f), _M_bound_args(__bound_args...) { } + + // Call unqualified + template<typename... _Args> + typename result_of< + _Functor(typename result_of<_Mu<_Bound_args> + (_Bound_args, tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + + // Call as const + template<typename... _Args> + typename result_of< + const _Functor(typename result_of<_Mu<_Bound_args> + (const _Bound_args, tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) const + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + + + // Call as volatile + template<typename... _Args> + typename result_of< + volatile _Functor(typename result_of<_Mu<_Bound_args> + (volatile _Bound_args, tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) volatile + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + + + // Call as const volatile + template<typename... _Args> + typename result_of< + const volatile _Functor(typename result_of<_Mu<_Bound_args> + (const volatile _Bound_args, + tuple<_Args...>)>::type...) + >::type + operator()(_Args&... __args) const volatile + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + }; + + /// Type of the function object returned from bind<R>(). + template<typename _Result, typename _Signature> + struct _Bind_result; + + template<typename _Result, typename _Functor, typename... _Bound_args> + class _Bind_result<_Result, _Functor(_Bound_args...)> + { + typedef _Bind_result __self_type; + typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type + _Bound_indexes; + + _Functor _M_f; + tuple<_Bound_args...> _M_bound_args; + + // Call unqualified + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as volatile + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) volatile + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + // Call as const volatile + template<typename... _Args, int... _Indexes> + _Result + __call(const tuple<_Args...>& __args, + _Index_tuple<_Indexes...>) const volatile + { + return _M_f(_Mu<_Bound_args>() + (tr1::get<_Indexes>(_M_bound_args), __args)...); + } + + public: + typedef _Result result_type; + + explicit + _Bind_result(_Functor __f, _Bound_args... __bound_args) + : _M_f(__f), _M_bound_args(__bound_args...) { } + + // Call unqualified + template<typename... _Args> + result_type + operator()(_Args&... __args) + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + + // Call as const + template<typename... _Args> + result_type + operator()(_Args&... __args) const + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + + // Call as volatile + template<typename... _Args> + result_type + operator()(_Args&... __args) volatile + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + + // Call as const volatile + template<typename... _Args> + result_type + operator()(_Args&... __args) const volatile + { + return this->__call(tr1::tie(__args...), _Bound_indexes()); + } + }; + + /// Class template _Bind is always a bind expression. + template<typename _Signature> + struct is_bind_expression<_Bind<_Signature> > + { static const bool value = true; }; + + template<typename _Signature> + const bool is_bind_expression<_Bind<_Signature> >::value; + + /// Class template _Bind_result is always a bind expression. + template<typename _Result, typename _Signature> + struct is_bind_expression<_Bind_result<_Result, _Signature> > + { static const bool value = true; }; + + template<typename _Result, typename _Signature> + const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value; + + /// bind + template<typename _Functor, typename... _ArgTypes> + inline + _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type(_ArgTypes...)> + bind(_Functor __f, _ArgTypes... __args) + { + typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type; + typedef typename __maybe_type::type __functor_type; + typedef _Bind<__functor_type(_ArgTypes...)> __result_type; + return __result_type(__maybe_type::__do_wrap(__f), __args...); + } + + template<typename _Result, typename _Functor, typename... _ArgTypes> + inline + _Bind_result<_Result, + typename _Maybe_wrap_member_pointer<_Functor>::type + (_ArgTypes...)> + bind(_Functor __f, _ArgTypes... __args) + { + typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type; + typedef typename __maybe_type::type __functor_type; + typedef _Bind_result<_Result, __functor_type(_ArgTypes...)> + __result_type; + return __result_type(__maybe_type::__do_wrap(__f), __args...); + } + + /** + * @brief Exception class thrown when class template function's + * operator() is called with an empty target. + * @ingroup exceptions + */ + class bad_function_call : public std::exception { }; + + /** + * The integral constant expression 0 can be converted into a + * pointer to this type. It is used by the function template to + * accept NULL pointers. + */ + struct _M_clear_type; + + /** + * Trait identifying @a location-invariant types, meaning that the + * address of the object (or any of its members) will not escape. + * Also implies a trivial copy constructor and assignment operator. + */ + template<typename _Tp> + struct __is_location_invariant + : integral_constant<bool, + (is_pointer<_Tp>::value + || is_member_pointer<_Tp>::value)> + { + }; + + class _Undefined_class; + + union _Nocopy_types + { + void* _M_object; + const void* _M_const_object; + void (*_M_function_pointer)(); + void (_Undefined_class::*_M_member_pointer)(); + }; + + union _Any_data + { + void* _M_access() { return &_M_pod_data[0]; } + const void* _M_access() const { return &_M_pod_data[0]; } + + template<typename _Tp> + _Tp& + _M_access() + { return *static_cast<_Tp*>(_M_access()); } + + template<typename _Tp> + const _Tp& + _M_access() const + { return *static_cast<const _Tp*>(_M_access()); } + + _Nocopy_types _M_unused; + char _M_pod_data[sizeof(_Nocopy_types)]; + }; + + enum _Manager_operation + { + __get_type_info, + __get_functor_ptr, + __clone_functor, + __destroy_functor + }; + + // Simple type wrapper that helps avoid annoying const problems + // when casting between void pointers and pointers-to-pointers. + template<typename _Tp> + struct _Simple_type_wrapper + { + _Simple_type_wrapper(_Tp __value) : __value(__value) { } + + _Tp __value; + }; + + template<typename _Tp> + struct __is_location_invariant<_Simple_type_wrapper<_Tp> > + : __is_location_invariant<_Tp> + { + }; + + // Converts a reference to a function object into a callable + // function object. + template<typename _Functor> + inline _Functor& + __callable_functor(_Functor& __f) + { return __f; } + + template<typename _Member, typename _Class> + inline _Mem_fn<_Member _Class::*> + __callable_functor(_Member _Class::* &__p) + { return mem_fn(__p); } + + template<typename _Member, typename _Class> + inline _Mem_fn<_Member _Class::*> + __callable_functor(_Member _Class::* const &__p) + { return mem_fn(__p); } + + template<typename _Signature> + class function; + + /// Base class of all polymorphic function object wrappers. + class _Function_base + { + public: + static const std::size_t _M_max_size = sizeof(_Nocopy_types); + static const std::size_t _M_max_align = __alignof__(_Nocopy_types); + + template<typename _Functor> + class _Base_manager + { + protected: + static const bool __stored_locally = + (__is_location_invariant<_Functor>::value + && sizeof(_Functor) <= _M_max_size + && __alignof__(_Functor) <= _M_max_align + && (_M_max_align % __alignof__(_Functor) == 0)); + + typedef integral_constant<bool, __stored_locally> _Local_storage; + + // Retrieve a pointer to the function object + static _Functor* + _M_get_pointer(const _Any_data& __source) + { + const _Functor* __ptr = + __stored_locally? &__source._M_access<_Functor>() + /* have stored a pointer */ : __source._M_access<_Functor*>(); + return const_cast<_Functor*>(__ptr); + } + + // Clone a location-invariant function object that fits within + // an _Any_data structure. + static void + _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) + { + new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); + } + + // Clone a function object that is not location-invariant or + // that cannot fit into an _Any_data structure. + static void + _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) + { + __dest._M_access<_Functor*>() = + new _Functor(*__source._M_access<_Functor*>()); + } + + // Destroying a location-invariant object may still require + // destruction. + static void + _M_destroy(_Any_data& __victim, true_type) + { + __victim._M_access<_Functor>().~_Functor(); + } + + // Destroying an object located on the heap. + static void + _M_destroy(_Any_data& __victim, false_type) + { + delete __victim._M_access<_Functor*>(); + } + + public: + static bool + _M_manager(_Any_data& __dest, const _Any_data& __source, + _Manager_operation __op) + { + switch (__op) + { +#ifdef __GXX_RTTI + case __get_type_info: + __dest._M_access<const type_info*>() = &typeid(_Functor); + break; +#endif + case __get_functor_ptr: + __dest._M_access<_Functor*>() = _M_get_pointer(__source); + break; + + case __clone_functor: + _M_clone(__dest, __source, _Local_storage()); + break; + + case __destroy_functor: + _M_destroy(__dest, _Local_storage()); + break; + } + return false; + } + + static void + _M_init_functor(_Any_data& __functor, const _Functor& __f) + { _M_init_functor(__functor, __f, _Local_storage()); } + + template<typename _Signature> + static bool + _M_not_empty_function(const function<_Signature>& __f) + { return static_cast<bool>(__f); } + + template<typename _Tp> + static bool + _M_not_empty_function(const _Tp*& __fp) + { return __fp; } + + template<typename _Class, typename _Tp> + static bool + _M_not_empty_function(_Tp _Class::* const& __mp) + { return __mp; } + + template<typename _Tp> + static bool + _M_not_empty_function(const _Tp&) + { return true; } + + private: + static void + _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type) + { new (__functor._M_access()) _Functor(__f); } + + static void + _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type) + { __functor._M_access<_Functor*>() = new _Functor(__f); } + }; + + template<typename _Functor> + class _Ref_manager : public _Base_manager<_Functor*> + { + typedef _Function_base::_Base_manager<_Functor*> _Base; + + public: + static bool + _M_manager(_Any_data& __dest, const _Any_data& __source, + _Manager_operation __op) + { + switch (__op) + { +#ifdef __GXX_RTTI + case __get_type_info: + __dest._M_access<const type_info*>() = &typeid(_Functor); + break; +#endif + case __get_functor_ptr: + __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source); + return is_const<_Functor>::value; + break; + + default: + _Base::_M_manager(__dest, __source, __op); + } + return false; + } + + static void + _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f) + { + // TBD: Use address_of function instead. + _Base::_M_init_functor(__functor, &__f.get()); + } + }; + + _Function_base() : _M_manager(0) { } + + ~_Function_base() + { + if (_M_manager) + _M_manager(_M_functor, _M_functor, __destroy_functor); + } + + + bool _M_empty() const { return !_M_manager; } + + typedef bool (*_Manager_type)(_Any_data&, const _Any_data&, + _Manager_operation); + + _Any_data _M_functor; + _Manager_type _M_manager; + }; + + template<typename _Signature, typename _Functor> + class _Function_handler; + + template<typename _Res, typename _Functor, typename... _ArgTypes> + class _Function_handler<_Res(_ArgTypes...), _Functor> + : public _Function_base::_Base_manager<_Functor> + { + typedef _Function_base::_Base_manager<_Functor> _Base; + + public: + static _Res + _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + return (*_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Functor, typename... _ArgTypes> + class _Function_handler<void(_ArgTypes...), _Functor> + : public _Function_base::_Base_manager<_Functor> + { + typedef _Function_base::_Base_manager<_Functor> _Base; + + public: + static void + _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + (*_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Res, typename _Functor, typename... _ArgTypes> + class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> > + : public _Function_base::_Ref_manager<_Functor> + { + typedef _Function_base::_Ref_manager<_Functor> _Base; + + public: + static _Res + _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + return + __callable_functor(**_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Functor, typename... _ArgTypes> + class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> > + : public _Function_base::_Ref_manager<_Functor> + { + typedef _Function_base::_Ref_manager<_Functor> _Base; + + public: + static void + _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + __callable_functor(**_Base::_M_get_pointer(__functor))(__args...); + } + }; + + template<typename _Class, typename _Member, typename _Res, + typename... _ArgTypes> + class _Function_handler<_Res(_ArgTypes...), _Member _Class::*> + : public _Function_handler<void(_ArgTypes...), _Member _Class::*> + { + typedef _Function_handler<void(_ArgTypes...), _Member _Class::*> + _Base; + + public: + static _Res + _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + return tr1:: + mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...); + } + }; + + template<typename _Class, typename _Member, typename... _ArgTypes> + class _Function_handler<void(_ArgTypes...), _Member _Class::*> + : public _Function_base::_Base_manager< + _Simple_type_wrapper< _Member _Class::* > > + { + typedef _Member _Class::* _Functor; + typedef _Simple_type_wrapper<_Functor> _Wrapper; + typedef _Function_base::_Base_manager<_Wrapper> _Base; + + public: + static bool + _M_manager(_Any_data& __dest, const _Any_data& __source, + _Manager_operation __op) + { + switch (__op) + { +#ifdef __GXX_RTTI + case __get_type_info: + __dest._M_access<const type_info*>() = &typeid(_Functor); + break; +#endif + case __get_functor_ptr: + __dest._M_access<_Functor*>() = + &_Base::_M_get_pointer(__source)->__value; + break; + + default: + _Base::_M_manager(__dest, __source, __op); + } + return false; + } + + static void + _M_invoke(const _Any_data& __functor, _ArgTypes... __args) + { + tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...); + } + }; + + /// class function + template<typename _Res, typename... _ArgTypes> + class function<_Res(_ArgTypes...)> + : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, + private _Function_base + { +#ifndef __GXX_EXPERIMENTAL_CXX0X__ + /// This class is used to implement the safe_bool idiom. + struct _Hidden_type + { + _Hidden_type* _M_bool; + }; + + /// This typedef is used to implement the safe_bool idiom. + typedef _Hidden_type* _Hidden_type::* _Safe_bool; +#endif + + typedef _Res _Signature_type(_ArgTypes...); + + struct _Useless { }; + + public: + typedef _Res result_type; + + // [3.7.2.1] construct/copy/destroy + + /** + * @brief Default construct creates an empty function call wrapper. + * @post @c !(bool)*this + */ + function() : _Function_base() { } + + /** + * @brief Default construct creates an empty function call wrapper. + * @post @c !(bool)*this + */ + function(_M_clear_type*) : _Function_base() { } + + /** + * @brief %Function copy constructor. + * @param x A %function object with identical call signature. + * @post @c (bool)*this == (bool)x + * + * The newly-created %function contains a copy of the target of @a + * x (if it has one). + */ + function(const function& __x); + + /** + * @brief Builds a %function that targets a copy of the incoming + * function object. + * @param f A %function object that is callable with parameters of + * type @c T1, @c T2, ..., @c TN and returns a value convertible + * to @c Res. + * + * The newly-created %function object will target a copy of @a + * f. If @a f is @c reference_wrapper<F>, then this function + * object will contain a reference to the function object @c + * f.get(). If @a f is a NULL function pointer or NULL + * pointer-to-member, the newly-created object will be empty. + * + * If @a f is a non-NULL function pointer or an object of type @c + * reference_wrapper<F>, this function will not throw. + */ + template<typename _Functor> + function(_Functor __f, + typename __gnu_cxx::__enable_if< + !is_integral<_Functor>::value, _Useless>::__type + = _Useless()); + + /** + * @brief %Function assignment operator. + * @param x A %function with identical call signature. + * @post @c (bool)*this == (bool)x + * @returns @c *this + * + * The target of @a x is copied to @c *this. If @a x has no + * target, then @c *this will be empty. + * + * If @a x targets a function pointer or a reference to a function + * object, then this operation will not throw an %exception. + */ + function& + operator=(const function& __x) + { + function(__x).swap(*this); + return *this; + } + + /** + * @brief %Function assignment to zero. + * @post @c !(bool)*this + * @returns @c *this + * + * The target of @c *this is deallocated, leaving it empty. + */ + function& + operator=(_M_clear_type*) + { + if (_M_manager) + { + _M_manager(_M_functor, _M_functor, __destroy_functor); + _M_manager = 0; + _M_invoker = 0; + } + return *this; + } + + /** + * @brief %Function assignment to a new target. + * @param f A %function object that is callable with parameters of + * type @c T1, @c T2, ..., @c TN and returns a value convertible + * to @c Res. + * @return @c *this + * + * This %function object wrapper will target a copy of @a + * f. If @a f is @c reference_wrapper<F>, then this function + * object will contain a reference to the function object @c + * f.get(). If @a f is a NULL function pointer or NULL + * pointer-to-member, @c this object will be empty. + * + * If @a f is a non-NULL function pointer or an object of type @c + * reference_wrapper<F>, this function will not throw. + */ + template<typename _Functor> + typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, + function&>::__type + operator=(_Functor __f) + { + function(__f).swap(*this); + return *this; + } + + // [3.7.2.2] function modifiers + + /** + * @brief Swap the targets of two %function objects. + * @param f A %function with identical call signature. + * + * Swap the targets of @c this function object and @a f. This + * function will not throw an %exception. + */ + void swap(function& __x) + { + std::swap(_M_functor, __x._M_functor); + std::swap(_M_manager, __x._M_manager); + std::swap(_M_invoker, __x._M_invoker); + } + + // [3.7.2.3] function capacity + + /** + * @brief Determine if the %function wrapper has a target. + * + * @return @c true when this %function object contains a target, + * or @c false when it is empty. + * + * This function will not throw an %exception. + */ +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + explicit operator bool() const + { return !_M_empty(); } +#else + operator _Safe_bool() const + { + if (_M_empty()) + return 0; + else + return &_Hidden_type::_M_bool; + } +#endif + + // [3.7.2.4] function invocation + + /** + * @brief Invokes the function targeted by @c *this. + * @returns the result of the target. + * @throws bad_function_call when @c !(bool)*this + * + * The function call operator invokes the target function object + * stored by @c this. + */ + _Res operator()(_ArgTypes... __args) const; + +#ifdef __GXX_RTTI + // [3.7.2.5] function target access + /** + * @brief Determine the type of the target of this function object + * wrapper. + * + * @returns the type identifier of the target function object, or + * @c typeid(void) if @c !(bool)*this. + * + * This function will not throw an %exception. + */ + const type_info& target_type() const; + + /** + * @brief Access the stored target function object. + * + * @return Returns a pointer to the stored target function object, + * if @c typeid(Functor).equals(target_type()); otherwise, a NULL + * pointer. + * + * This function will not throw an %exception. + */ + template<typename _Functor> _Functor* target(); + + /// @overload + template<typename _Functor> const _Functor* target() const; +#endif + + private: + // [3.7.2.6] undefined operators + template<typename _Function> + void operator==(const function<_Function>&) const; + template<typename _Function> + void operator!=(const function<_Function>&) const; + + typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...); + _Invoker_type _M_invoker; + }; + + template<typename _Res, typename... _ArgTypes> + function<_Res(_ArgTypes...)>:: + function(const function& __x) + : _Function_base() + { + if (static_cast<bool>(__x)) + { + _M_invoker = __x._M_invoker; + _M_manager = __x._M_manager; + __x._M_manager(_M_functor, __x._M_functor, __clone_functor); + } + } + + template<typename _Res, typename... _ArgTypes> + template<typename _Functor> + function<_Res(_ArgTypes...)>:: + function(_Functor __f, + typename __gnu_cxx::__enable_if< + !is_integral<_Functor>::value, _Useless>::__type) + : _Function_base() + { + typedef _Function_handler<_Signature_type, _Functor> _My_handler; + + if (_My_handler::_M_not_empty_function(__f)) + { + _M_invoker = &_My_handler::_M_invoke; + _M_manager = &_My_handler::_M_manager; + _My_handler::_M_init_functor(_M_functor, __f); + } + } + + template<typename _Res, typename... _ArgTypes> + _Res + function<_Res(_ArgTypes...)>:: + operator()(_ArgTypes... __args) const + { + if (_M_empty()) + { +#if __EXCEPTIONS + throw bad_function_call(); +#else + __builtin_abort(); +#endif + } + return _M_invoker(_M_functor, __args...); + } + +#ifdef __GXX_RTTI + template<typename _Res, typename... _ArgTypes> + const type_info& + function<_Res(_ArgTypes...)>:: + target_type() const + { + if (_M_manager) + { + _Any_data __typeinfo_result; + _M_manager(__typeinfo_result, _M_functor, __get_type_info); + return *__typeinfo_result._M_access<const type_info*>(); + } + else + return typeid(void); + } + + template<typename _Res, typename... _ArgTypes> + template<typename _Functor> + _Functor* + function<_Res(_ArgTypes...)>:: + target() + { + if (typeid(_Functor) == target_type() && _M_manager) + { + _Any_data __ptr; + if (_M_manager(__ptr, _M_functor, __get_functor_ptr) + && !is_const<_Functor>::value) + return 0; + else + return __ptr._M_access<_Functor*>(); + } + else + return 0; + } + + template<typename _Res, typename... _ArgTypes> + template<typename _Functor> + const _Functor* + function<_Res(_ArgTypes...)>:: + target() const + { + if (typeid(_Functor) == target_type() && _M_manager) + { + _Any_data __ptr; + _M_manager(__ptr, _M_functor, __get_functor_ptr); + return __ptr._M_access<const _Functor*>(); + } + else + return 0; + } +#endif + + // [3.7.2.7] null pointer comparisons + + /** + * @brief Compares a polymorphic function object wrapper against 0 + * (the NULL pointer). + * @returns @c true if the wrapper has no target, @c false otherwise + * + * This function will not throw an %exception. + */ + template<typename _Signature> + inline bool + operator==(const function<_Signature>& __f, _M_clear_type*) + { return !static_cast<bool>(__f); } + + /// @overload + template<typename _Signature> + inline bool + operator==(_M_clear_type*, const function<_Signature>& __f) + { return !static_cast<bool>(__f); } + + /** + * @brief Compares a polymorphic function object wrapper against 0 + * (the NULL pointer). + * @returns @c false if the wrapper has no target, @c true otherwise + * + * This function will not throw an %exception. + */ + template<typename _Signature> + inline bool + operator!=(const function<_Signature>& __f, _M_clear_type*) + { return static_cast<bool>(__f); } + + /// @overload + template<typename _Signature> + inline bool + operator!=(_M_clear_type*, const function<_Signature>& __f) + { return static_cast<bool>(__f); } + + // [3.7.2.8] specialized algorithms + + /** + * @brief Swap the targets of two polymorphic function object wrappers. + * + * This function will not throw an %exception. + */ + template<typename _Signature> + inline void + swap(function<_Signature>& __x, function<_Signature>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_FUNCTIONAL diff --git a/libstdc++-v3/include/tr1/functional_hash.h b/libstdc++-v3/include/tr1/functional_hash.h new file mode 100644 index 000000000..1742e1527 --- /dev/null +++ b/libstdc++-v3/include/tr1/functional_hash.h @@ -0,0 +1,196 @@ +// TR1 functional_hash.h header -*- C++ -*- + +// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/functional_hash.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/functional} + */ + +#ifndef _GLIBCXX_TR1_FUNCTIONAL_HASH_H +#define _GLIBCXX_TR1_FUNCTIONAL_HASH_H 1 + +#pragma GCC system_header + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /// Class template hash. + // Declaration of default hash functor std::tr1::hash. The types for + // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR. + template<typename _Tp> + struct hash : public std::unary_function<_Tp, size_t> + { + size_t + operator()(_Tp __val) const; + }; + + /// Partial specializations for pointer types. + template<typename _Tp> + struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> + { + size_t + operator()(_Tp* __p) const + { return reinterpret_cast<size_t>(__p); } + }; + + /// Explicit specializations for integer types. +#define _TR1_hashtable_define_trivial_hash(_Tp) \ + template<> \ + inline size_t \ + hash<_Tp>::operator()(_Tp __val) const \ + { return static_cast<size_t>(__val); } + + _TR1_hashtable_define_trivial_hash(bool); + _TR1_hashtable_define_trivial_hash(char); + _TR1_hashtable_define_trivial_hash(signed char); + _TR1_hashtable_define_trivial_hash(unsigned char); + _TR1_hashtable_define_trivial_hash(wchar_t); + _TR1_hashtable_define_trivial_hash(short); + _TR1_hashtable_define_trivial_hash(int); + _TR1_hashtable_define_trivial_hash(long); + _TR1_hashtable_define_trivial_hash(long long); + _TR1_hashtable_define_trivial_hash(unsigned short); + _TR1_hashtable_define_trivial_hash(unsigned int); + _TR1_hashtable_define_trivial_hash(unsigned long); + _TR1_hashtable_define_trivial_hash(unsigned long long); + +#undef _TR1_hashtable_define_trivial_hash + + // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) + // (Used by the next specializations of std::tr1::hash.) + + /// Dummy generic implementation (for sizeof(size_t) != 4, 8). + template<size_t> + struct _Fnv_hash_base + { + template<typename _Tp> + static size_t + hash(const _Tp* __ptr, size_t __clength) + { + size_t __result = 0; + const char* __cptr = reinterpret_cast<const char*>(__ptr); + for (; __clength; --__clength) + __result = (__result * 131) + *__cptr++; + return __result; + } + }; + + template<> + struct _Fnv_hash_base<4> + { + template<typename _Tp> + static size_t + hash(const _Tp* __ptr, size_t __clength) + { + size_t __result = static_cast<size_t>(2166136261UL); + const char* __cptr = reinterpret_cast<const char*>(__ptr); + for (; __clength; --__clength) + { + __result ^= static_cast<size_t>(*__cptr++); + __result *= static_cast<size_t>(16777619UL); + } + return __result; + } + }; + + template<> + struct _Fnv_hash_base<8> + { + template<typename _Tp> + static size_t + hash(const _Tp* __ptr, size_t __clength) + { + size_t __result + = static_cast<size_t>(14695981039346656037ULL); + const char* __cptr = reinterpret_cast<const char*>(__ptr); + for (; __clength; --__clength) + { + __result ^= static_cast<size_t>(*__cptr++); + __result *= static_cast<size_t>(1099511628211ULL); + } + return __result; + } + }; + + struct _Fnv_hash + : public _Fnv_hash_base<sizeof(size_t)> + { + using _Fnv_hash_base<sizeof(size_t)>::hash; + + template<typename _Tp> + static size_t + hash(const _Tp& __val) + { return hash(&__val, sizeof(__val)); } + }; + + /// Explicit specializations for float. + template<> + inline size_t + hash<float>::operator()(float __val) const + { + // 0 and -0 both hash to zero. + return __val != 0.0f ? std::tr1::_Fnv_hash::hash(__val) : 0; + } + + /// Explicit specializations for double. + template<> + inline size_t + hash<double>::operator()(double __val) const + { + // 0 and -0 both hash to zero. + return __val != 0.0 ? std::tr1::_Fnv_hash::hash(__val) : 0; + } + + /// Explicit specializations for long double. + template<> + _GLIBCXX_PURE size_t + hash<long double>::operator()(long double __val) const; + + /// Explicit specialization of member operator for non-builtin types. + template<> + _GLIBCXX_PURE size_t + hash<string>::operator()(string) const; + + template<> + _GLIBCXX_PURE size_t + hash<const string&>::operator()(const string&) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + _GLIBCXX_PURE size_t + hash<wstring>::operator()(wstring) const; + + template<> + _GLIBCXX_PURE size_t + hash<const wstring&>::operator()(const wstring&) const; +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_FUNCTIONAL_HASH_H diff --git a/libstdc++-v3/include/tr1/gamma.tcc b/libstdc++-v3/include/tr1/gamma.tcc new file mode 100644 index 000000000..a7c399cd4 --- /dev/null +++ b/libstdc++-v3/include/tr1/gamma.tcc @@ -0,0 +1,473 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/gamma.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// (1) Handbook of Mathematical Functions, +// ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, +// Section 6, pp. 253-266 +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky, +// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992), +// 2nd ed, pp. 213-216 +// (4) Gamma, Exploring Euler's Constant, Julian Havil, +// Princeton, 2003. + +#ifndef _GLIBCXX_TR1_GAMMA_TCC +#define _GLIBCXX_TR1_GAMMA_TCC 1 + +#include "special_function_util.h" + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief This returns Bernoulli numbers from a table or by summation + * for larger values. + * + * Recursion is unstable. + * + * @param __n the order n of the Bernoulli number. + * @return The Bernoulli number of order n. + */ + template <typename _Tp> + _Tp __bernoulli_series(unsigned int __n) + { + + static const _Tp __num[28] = { + _Tp(1UL), -_Tp(1UL) / _Tp(2UL), + _Tp(1UL) / _Tp(6UL), _Tp(0UL), + -_Tp(1UL) / _Tp(30UL), _Tp(0UL), + _Tp(1UL) / _Tp(42UL), _Tp(0UL), + -_Tp(1UL) / _Tp(30UL), _Tp(0UL), + _Tp(5UL) / _Tp(66UL), _Tp(0UL), + -_Tp(691UL) / _Tp(2730UL), _Tp(0UL), + _Tp(7UL) / _Tp(6UL), _Tp(0UL), + -_Tp(3617UL) / _Tp(510UL), _Tp(0UL), + _Tp(43867UL) / _Tp(798UL), _Tp(0UL), + -_Tp(174611) / _Tp(330UL), _Tp(0UL), + _Tp(854513UL) / _Tp(138UL), _Tp(0UL), + -_Tp(236364091UL) / _Tp(2730UL), _Tp(0UL), + _Tp(8553103UL) / _Tp(6UL), _Tp(0UL) + }; + + if (__n == 0) + return _Tp(1); + + if (__n == 1) + return -_Tp(1) / _Tp(2); + + // Take care of the rest of the odd ones. + if (__n % 2 == 1) + return _Tp(0); + + // Take care of some small evens that are painful for the series. + if (__n < 28) + return __num[__n]; + + + _Tp __fact = _Tp(1); + if ((__n / 2) % 2 == 0) + __fact *= _Tp(-1); + for (unsigned int __k = 1; __k <= __n; ++__k) + __fact *= __k / (_Tp(2) * __numeric_constants<_Tp>::__pi()); + __fact *= _Tp(2); + + _Tp __sum = _Tp(0); + for (unsigned int __i = 1; __i < 1000; ++__i) + { + _Tp __term = std::pow(_Tp(__i), -_Tp(__n)); + if (__term < std::numeric_limits<_Tp>::epsilon()) + break; + __sum += __term; + } + + return __fact * __sum; + } + + + /** + * @brief This returns Bernoulli number \f$B_n\f$. + * + * @param __n the order n of the Bernoulli number. + * @return The Bernoulli number of order n. + */ + template<typename _Tp> + inline _Tp + __bernoulli(const int __n) + { + return __bernoulli_series<_Tp>(__n); + } + + + /** + * @brief Return \f$log(\Gamma(x))\f$ by asymptotic expansion + * with Bernoulli number coefficients. This is like + * Sterling's approximation. + * + * @param __x The argument of the log of the gamma function. + * @return The logarithm of the gamma function. + */ + template<typename _Tp> + _Tp + __log_gamma_bernoulli(const _Tp __x) + { + _Tp __lg = (__x - _Tp(0.5L)) * std::log(__x) - __x + + _Tp(0.5L) * std::log(_Tp(2) + * __numeric_constants<_Tp>::__pi()); + + const _Tp __xx = __x * __x; + _Tp __help = _Tp(1) / __x; + for ( unsigned int __i = 1; __i < 20; ++__i ) + { + const _Tp __2i = _Tp(2 * __i); + __help /= __2i * (__2i - _Tp(1)) * __xx; + __lg += __bernoulli<_Tp>(2 * __i) * __help; + } + + return __lg; + } + + + /** + * @brief Return \f$log(\Gamma(x))\f$ by the Lanczos method. + * This method dominates all others on the positive axis I think. + * + * @param __x The argument of the log of the gamma function. + * @return The logarithm of the gamma function. + */ + template<typename _Tp> + _Tp + __log_gamma_lanczos(const _Tp __x) + { + const _Tp __xm1 = __x - _Tp(1); + + static const _Tp __lanczos_cheb_7[9] = { + _Tp( 0.99999999999980993227684700473478L), + _Tp( 676.520368121885098567009190444019L), + _Tp(-1259.13921672240287047156078755283L), + _Tp( 771.3234287776530788486528258894L), + _Tp(-176.61502916214059906584551354L), + _Tp( 12.507343278686904814458936853L), + _Tp(-0.13857109526572011689554707L), + _Tp( 9.984369578019570859563e-6L), + _Tp( 1.50563273514931155834e-7L) + }; + + static const _Tp __LOGROOT2PI + = _Tp(0.9189385332046727417803297364056176L); + + _Tp __sum = __lanczos_cheb_7[0]; + for(unsigned int __k = 1; __k < 9; ++__k) + __sum += __lanczos_cheb_7[__k] / (__xm1 + __k); + + const _Tp __term1 = (__xm1 + _Tp(0.5L)) + * std::log((__xm1 + _Tp(7.5L)) + / __numeric_constants<_Tp>::__euler()); + const _Tp __term2 = __LOGROOT2PI + std::log(__sum); + const _Tp __result = __term1 + (__term2 - _Tp(7)); + + return __result; + } + + + /** + * @brief Return \f$ log(|\Gamma(x)|) \f$. + * This will return values even for \f$ x < 0 \f$. + * To recover the sign of \f$ \Gamma(x) \f$ for + * any argument use @a __log_gamma_sign. + * + * @param __x The argument of the log of the gamma function. + * @return The logarithm of the gamma function. + */ + template<typename _Tp> + _Tp + __log_gamma(const _Tp __x) + { + if (__x > _Tp(0.5L)) + return __log_gamma_lanczos(__x); + else + { + const _Tp __sin_fact + = std::abs(std::sin(__numeric_constants<_Tp>::__pi() * __x)); + if (__sin_fact == _Tp(0)) + std::__throw_domain_error(__N("Argument is nonpositive integer " + "in __log_gamma")); + return __numeric_constants<_Tp>::__lnpi() + - std::log(__sin_fact) + - __log_gamma_lanczos(_Tp(1) - __x); + } + } + + + /** + * @brief Return the sign of \f$ \Gamma(x) \f$. + * At nonpositive integers zero is returned. + * + * @param __x The argument of the gamma function. + * @return The sign of the gamma function. + */ + template<typename _Tp> + _Tp + __log_gamma_sign(const _Tp __x) + { + if (__x > _Tp(0)) + return _Tp(1); + else + { + const _Tp __sin_fact + = std::sin(__numeric_constants<_Tp>::__pi() * __x); + if (__sin_fact > _Tp(0)) + return (1); + else if (__sin_fact < _Tp(0)) + return -_Tp(1); + else + return _Tp(0); + } + } + + + /** + * @brief Return the logarithm of the binomial coefficient. + * The binomial coefficient is given by: + * @f[ + * \left( \right) = \frac{n!}{(n-k)! k!} + * @f] + * + * @param __n The first argument of the binomial coefficient. + * @param __k The second argument of the binomial coefficient. + * @return The binomial coefficient. + */ + template<typename _Tp> + _Tp + __log_bincoef(const unsigned int __n, const unsigned int __k) + { + // Max e exponent before overflow. + static const _Tp __max_bincoeff + = std::numeric_limits<_Tp>::max_exponent10 + * std::log(_Tp(10)) - _Tp(1); +#if _GLIBCXX_USE_C99_MATH_TR1 + _Tp __coeff = std::tr1::lgamma(_Tp(1 + __n)) + - std::tr1::lgamma(_Tp(1 + __k)) + - std::tr1::lgamma(_Tp(1 + __n - __k)); +#else + _Tp __coeff = __log_gamma(_Tp(1 + __n)) + - __log_gamma(_Tp(1 + __k)) + - __log_gamma(_Tp(1 + __n - __k)); +#endif + } + + + /** + * @brief Return the binomial coefficient. + * The binomial coefficient is given by: + * @f[ + * \left( \right) = \frac{n!}{(n-k)! k!} + * @f] + * + * @param __n The first argument of the binomial coefficient. + * @param __k The second argument of the binomial coefficient. + * @return The binomial coefficient. + */ + template<typename _Tp> + _Tp + __bincoef(const unsigned int __n, const unsigned int __k) + { + // Max e exponent before overflow. + static const _Tp __max_bincoeff + = std::numeric_limits<_Tp>::max_exponent10 + * std::log(_Tp(10)) - _Tp(1); + + const _Tp __log_coeff = __log_bincoef<_Tp>(__n, __k); + if (__log_coeff > __max_bincoeff) + return std::numeric_limits<_Tp>::quiet_NaN(); + else + return std::exp(__log_coeff); + } + + + /** + * @brief Return \f$ \Gamma(x) \f$. + * + * @param __x The argument of the gamma function. + * @return The gamma function. + */ + template<typename _Tp> + inline _Tp + __gamma(const _Tp __x) + { + return std::exp(__log_gamma(__x)); + } + + + /** + * @brief Return the digamma function by series expansion. + * The digamma or @f$ \psi(x) @f$ function is defined by + * @f[ + * \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)} + * @f] + * + * The series is given by: + * @f[ + * \psi(x) = -\gamma_E - \frac{1}{x} + * \sum_{k=1}^{\infty} \frac{x}{k(x + k)} + * @f] + */ + template<typename _Tp> + _Tp + __psi_series(const _Tp __x) + { + _Tp __sum = -__numeric_constants<_Tp>::__gamma_e() - _Tp(1) / __x; + const unsigned int __max_iter = 100000; + for (unsigned int __k = 1; __k < __max_iter; ++__k) + { + const _Tp __term = __x / (__k * (__k + __x)); + __sum += __term; + if (std::abs(__term / __sum) < std::numeric_limits<_Tp>::epsilon()) + break; + } + return __sum; + } + + + /** + * @brief Return the digamma function for large argument. + * The digamma or @f$ \psi(x) @f$ function is defined by + * @f[ + * \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)} + * @f] + * + * The asymptotic series is given by: + * @f[ + * \psi(x) = \ln(x) - \frac{1}{2x} + * - \sum_{n=1}^{\infty} \frac{B_{2n}}{2 n x^{2n}} + * @f] + */ + template<typename _Tp> + _Tp + __psi_asymp(const _Tp __x) + { + _Tp __sum = std::log(__x) - _Tp(0.5L) / __x; + const _Tp __xx = __x * __x; + _Tp __xp = __xx; + const unsigned int __max_iter = 100; + for (unsigned int __k = 1; __k < __max_iter; ++__k) + { + const _Tp __term = __bernoulli<_Tp>(2 * __k) / (2 * __k * __xp); + __sum -= __term; + if (std::abs(__term / __sum) < std::numeric_limits<_Tp>::epsilon()) + break; + __xp *= __xx; + } + return __sum; + } + + + /** + * @brief Return the digamma function. + * The digamma or @f$ \psi(x) @f$ function is defined by + * @f[ + * \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)} + * @f] + * For negative argument the reflection formula is used: + * @f[ + * \psi(x) = \psi(1-x) - \pi \cot(\pi x) + * @f] + */ + template<typename _Tp> + _Tp + __psi(const _Tp __x) + { + const int __n = static_cast<int>(__x + 0.5L); + const _Tp __eps = _Tp(4) * std::numeric_limits<_Tp>::epsilon(); + if (__n <= 0 && std::abs(__x - _Tp(__n)) < __eps) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x < _Tp(0)) + { + const _Tp __pi = __numeric_constants<_Tp>::__pi(); + return __psi(_Tp(1) - __x) + - __pi * std::cos(__pi * __x) / std::sin(__pi * __x); + } + else if (__x > _Tp(100)) + return __psi_asymp(__x); + else + return __psi_series(__x); + } + + + /** + * @brief Return the polygamma function @f$ \psi^{(n)}(x) @f$. + * + * The polygamma function is related to the Hurwitz zeta function: + * @f[ + * \psi^{(n)}(x) = (-1)^{n+1} m! \zeta(m+1,x) + * @f] + */ + template<typename _Tp> + _Tp + __psi(const unsigned int __n, const _Tp __x) + { + if (__x <= _Tp(0)) + std::__throw_domain_error(__N("Argument out of range " + "in __psi")); + else if (__n == 0) + return __psi(__x); + else + { + const _Tp __hzeta = __hurwitz_zeta(_Tp(__n + 1), __x); +#if _GLIBCXX_USE_C99_MATH_TR1 + const _Tp __ln_nfact = std::tr1::lgamma(_Tp(__n + 1)); +#else + const _Tp __ln_nfact = __log_gamma(_Tp(__n + 1)); +#endif + _Tp __result = std::exp(__ln_nfact) * __hzeta; + if (__n % 2 == 1) + __result = -__result; + return __result; + } + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_GAMMA_TCC + diff --git a/libstdc++-v3/include/tr1/hashtable.h b/libstdc++-v3/include/tr1/hashtable.h new file mode 100644 index 000000000..5d1e02c25 --- /dev/null +++ b/libstdc++-v3/include/tr1/hashtable.h @@ -0,0 +1,1181 @@ +// TR1 hashtable.h header -*- C++ -*- + +// Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/hashtable.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. + * @headername{tr1/unordered_set, tr1/unordered_map} + */ + +#ifndef _GLIBCXX_TR1_HASHTABLE_H +#define _GLIBCXX_TR1_HASHTABLE_H 1 + +#pragma GCC system_header + +#include <tr1/hashtable_policy.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Class template _Hashtable, class definition. + + // Meaning of class template _Hashtable's template parameters + + // _Key and _Value: arbitrary CopyConstructible types. + + // _Allocator: an allocator type ([lib.allocator.requirements]) whose + // value type is Value. As a conforming extension, we allow for + // value type != Value. + + // _ExtractKey: function object that takes a object of type Value + // and returns a value of type _Key. + + // _Equal: function object that takes two objects of type k and returns + // a bool-like value that is true if the two objects are considered equal. + + // _H1: the hash function. A unary function object with argument type + // Key and result type size_t. Return values should be distributed + // over the entire range [0, numeric_limits<size_t>:::max()]. + + // _H2: the range-hashing function (in the terminology of Tavori and + // Dreizin). A binary function object whose argument types and result + // type are all size_t. Given arguments r and N, the return value is + // in the range [0, N). + + // _Hash: the ranged hash function (Tavori and Dreizin). A binary function + // whose argument types are _Key and size_t and whose result type is + // size_t. Given arguments k and N, the return value is in the range + // [0, N). Default: hash(k, N) = h2(h1(k), N). If _Hash is anything other + // than the default, _H1 and _H2 are ignored. + + // _RehashPolicy: Policy class with three members, all of which govern + // the bucket count. _M_next_bkt(n) returns a bucket count no smaller + // than n. _M_bkt_for_elements(n) returns a bucket count appropriate + // for an element count of n. _M_need_rehash(n_bkt, n_elt, n_ins) + // determines whether, if the current bucket count is n_bkt and the + // current element count is n_elt, we need to increase the bucket + // count. If so, returns make_pair(true, n), where n is the new + // bucket count. If not, returns make_pair(false, <anything>). + + // ??? Right now it is hard-wired that the number of buckets never + // shrinks. Should we allow _RehashPolicy to change that? + + // __cache_hash_code: bool. true if we store the value of the hash + // function along with the value. This is a time-space tradeoff. + // Storing it may improve lookup speed by reducing the number of times + // we need to call the Equal function. + + // __constant_iterators: bool. true if iterator and const_iterator are + // both constant iterator types. This is true for unordered_set and + // unordered_multiset, false for unordered_map and unordered_multimap. + + // __unique_keys: bool. true if the return value of _Hashtable::count(k) + // is always at most one, false if it may be an arbitrary number. This + // true for unordered_set and unordered_map, false for unordered_multiset + // and unordered_multimap. + + template<typename _Key, typename _Value, typename _Allocator, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, + typename _RehashPolicy, + bool __cache_hash_code, + bool __constant_iterators, + bool __unique_keys> + class _Hashtable + : public __detail::_Rehash_base<_RehashPolicy, + _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, + __cache_hash_code, + __constant_iterators, + __unique_keys> >, + public __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __cache_hash_code>, + public __detail::_Map_base<_Key, _Value, _ExtractKey, __unique_keys, + _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, + __cache_hash_code, + __constant_iterators, + __unique_keys> > + { + public: + typedef _Allocator allocator_type; + typedef _Value value_type; + typedef _Key key_type; + typedef _Equal key_equal; + // mapped_type, if present, comes from _Map_base. + // hasher, if present, comes from _Hash_code_base. + typedef typename _Allocator::difference_type difference_type; + typedef typename _Allocator::size_type size_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __detail::_Node_iterator<value_type, __constant_iterators, + __cache_hash_code> + local_iterator; + typedef __detail::_Node_const_iterator<value_type, + __constant_iterators, + __cache_hash_code> + const_local_iterator; + + typedef __detail::_Hashtable_iterator<value_type, __constant_iterators, + __cache_hash_code> + iterator; + typedef __detail::_Hashtable_const_iterator<value_type, + __constant_iterators, + __cache_hash_code> + const_iterator; + + template<typename _Key2, typename _Value2, typename _Ex2, bool __unique2, + typename _Hashtable2> + friend struct __detail::_Map_base; + + private: + typedef __detail::_Hash_node<_Value, __cache_hash_code> _Node; + typedef typename _Allocator::template rebind<_Node>::other + _Node_allocator_type; + typedef typename _Allocator::template rebind<_Node*>::other + _Bucket_allocator_type; + + typedef typename _Allocator::template rebind<_Value>::other + _Value_allocator_type; + + _Node_allocator_type _M_node_allocator; + _Node** _M_buckets; + size_type _M_bucket_count; + size_type _M_element_count; + _RehashPolicy _M_rehash_policy; + + _Node* + _M_allocate_node(const value_type& __v); + + void + _M_deallocate_node(_Node* __n); + + void + _M_deallocate_nodes(_Node**, size_type); + + _Node** + _M_allocate_buckets(size_type __n); + + void + _M_deallocate_buckets(_Node**, size_type __n); + + public: + // Constructor, destructor, assignment, swap + _Hashtable(size_type __bucket_hint, + const _H1&, const _H2&, const _Hash&, + const _Equal&, const _ExtractKey&, + const allocator_type&); + + template<typename _InputIterator> + _Hashtable(_InputIterator __first, _InputIterator __last, + size_type __bucket_hint, + const _H1&, const _H2&, const _Hash&, + const _Equal&, const _ExtractKey&, + const allocator_type&); + + _Hashtable(const _Hashtable&); + + _Hashtable& + operator=(const _Hashtable&); + + ~_Hashtable(); + + void swap(_Hashtable&); + + // Basic container operations + iterator + begin() + { + iterator __i(_M_buckets); + if (!__i._M_cur_node) + __i._M_incr_bucket(); + return __i; + } + + const_iterator + begin() const + { + const_iterator __i(_M_buckets); + if (!__i._M_cur_node) + __i._M_incr_bucket(); + return __i; + } + + iterator + end() + { return iterator(_M_buckets + _M_bucket_count); } + + const_iterator + end() const + { return const_iterator(_M_buckets + _M_bucket_count); } + + size_type + size() const + { return _M_element_count; } + + bool + empty() const + { return size() == 0; } + + allocator_type + get_allocator() const + { return allocator_type(_M_node_allocator); } + + _Value_allocator_type + _M_get_Value_allocator() const + { return _Value_allocator_type(_M_node_allocator); } + + size_type + max_size() const + { return _M_node_allocator.max_size(); } + + // Observers + key_equal + key_eq() const + { return this->_M_eq; } + + // hash_function, if present, comes from _Hash_code_base. + + // Bucket operations + size_type + bucket_count() const + { return _M_bucket_count; } + + size_type + max_bucket_count() const + { return max_size(); } + + size_type + bucket_size(size_type __n) const + { return std::distance(begin(__n), end(__n)); } + + size_type + bucket(const key_type& __k) const + { + return this->_M_bucket_index(__k, this->_M_hash_code(__k), + bucket_count()); + } + + local_iterator + begin(size_type __n) + { return local_iterator(_M_buckets[__n]); } + + local_iterator + end(size_type) + { return local_iterator(0); } + + const_local_iterator + begin(size_type __n) const + { return const_local_iterator(_M_buckets[__n]); } + + const_local_iterator + end(size_type) const + { return const_local_iterator(0); } + + float + load_factor() const + { + return static_cast<float>(size()) / static_cast<float>(bucket_count()); + } + + // max_load_factor, if present, comes from _Rehash_base. + + // Generalization of max_load_factor. Extension, not found in TR1. Only + // useful if _RehashPolicy is something other than the default. + const _RehashPolicy& + __rehash_policy() const + { return _M_rehash_policy; } + + void + __rehash_policy(const _RehashPolicy&); + + // Lookup. + iterator + find(const key_type& __k); + + const_iterator + find(const key_type& __k) const; + + size_type + count(const key_type& __k) const; + + std::pair<iterator, iterator> + equal_range(const key_type& __k); + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __k) const; + + private: // Find, insert and erase helper functions + // ??? This dispatching is a workaround for the fact that we don't + // have partial specialization of member templates; it would be + // better to just specialize insert on __unique_keys. There may be a + // cleaner workaround. + typedef typename __gnu_cxx::__conditional_type<__unique_keys, + std::pair<iterator, bool>, iterator>::__type + _Insert_Return_Type; + + typedef typename __gnu_cxx::__conditional_type<__unique_keys, + std::_Select1st<_Insert_Return_Type>, + std::_Identity<_Insert_Return_Type> + >::__type + _Insert_Conv_Type; + + _Node* + _M_find_node(_Node*, const key_type&, + typename _Hashtable::_Hash_code_type) const; + + iterator + _M_insert_bucket(const value_type&, size_type, + typename _Hashtable::_Hash_code_type); + + std::pair<iterator, bool> + _M_insert(const value_type&, std::tr1::true_type); + + iterator + _M_insert(const value_type&, std::tr1::false_type); + + void + _M_erase_node(_Node*, _Node**); + + public: + // Insert and erase + _Insert_Return_Type + insert(const value_type& __v) + { return _M_insert(__v, std::tr1::integral_constant<bool, + __unique_keys>()); } + + iterator + insert(iterator, const value_type& __v) + { return iterator(_Insert_Conv_Type()(this->insert(__v))); } + + const_iterator + insert(const_iterator, const value_type& __v) + { return const_iterator(_Insert_Conv_Type()(this->insert(__v))); } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last); + + iterator + erase(iterator); + + const_iterator + erase(const_iterator); + + size_type + erase(const key_type&); + + iterator + erase(iterator, iterator); + + const_iterator + erase(const_iterator, const_iterator); + + void + clear(); + + // Set number of buckets to be appropriate for container of n element. + void rehash(size_type __n); + + private: + // Unconditionally change size of bucket array to n. + void _M_rehash(size_type __n); + }; + + + // Definitions of class template _Hashtable's out-of-line member functions. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::_Node* + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_allocate_node(const value_type& __v) + { + _Node* __n = _M_node_allocator.allocate(1); + __try + { + _M_get_Value_allocator().construct(&__n->_M_v, __v); + __n->_M_next = 0; + return __n; + } + __catch(...) + { + _M_node_allocator.deallocate(__n, 1); + __throw_exception_again; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_deallocate_node(_Node* __n) + { + _M_get_Value_allocator().destroy(&__n->_M_v); + _M_node_allocator.deallocate(__n, 1); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_deallocate_nodes(_Node** __array, size_type __n) + { + for (size_type __i = 0; __i < __n; ++__i) + { + _Node* __p = __array[__i]; + while (__p) + { + _Node* __tmp = __p; + __p = __p->_M_next; + _M_deallocate_node(__tmp); + } + __array[__i] = 0; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::_Node** + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_allocate_buckets(size_type __n) + { + _Bucket_allocator_type __alloc(_M_node_allocator); + + // We allocate one extra bucket to hold a sentinel, an arbitrary + // non-null pointer. Iterator increment relies on this. + _Node** __p = __alloc.allocate(__n + 1); + std::fill(__p, __p + __n, (_Node*) 0); + __p[__n] = reinterpret_cast<_Node*>(0x1000); + return __p; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_deallocate_buckets(_Node** __p, size_type __n) + { + _Bucket_allocator_type __alloc(_M_node_allocator); + __alloc.deallocate(__p, __n + 1); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _Hashtable(size_type __bucket_hint, + const _H1& __h1, const _H2& __h2, const _Hash& __h, + const _Equal& __eq, const _ExtractKey& __exk, + const allocator_type& __a) + : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(), + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>(__exk, __eq, + __h1, __h2, __h), + __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(), + _M_node_allocator(__a), + _M_bucket_count(0), + _M_element_count(0), + _M_rehash_policy() + { + _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint); + _M_buckets = _M_allocate_buckets(_M_bucket_count); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + template<typename _InputIterator> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _Hashtable(_InputIterator __f, _InputIterator __l, + size_type __bucket_hint, + const _H1& __h1, const _H2& __h2, const _Hash& __h, + const _Equal& __eq, const _ExtractKey& __exk, + const allocator_type& __a) + : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(), + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>(__exk, __eq, + __h1, __h2, __h), + __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(), + _M_node_allocator(__a), + _M_bucket_count(0), + _M_element_count(0), + _M_rehash_policy() + { + _M_bucket_count = std::max(_M_rehash_policy._M_next_bkt(__bucket_hint), + _M_rehash_policy. + _M_bkt_for_elements(__detail:: + __distance_fw(__f, + __l))); + _M_buckets = _M_allocate_buckets(_M_bucket_count); + __try + { + for (; __f != __l; ++__f) + this->insert(*__f); + } + __catch(...) + { + clear(); + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + __throw_exception_again; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _Hashtable(const _Hashtable& __ht) + : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht), + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>(__ht), + __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht), + _M_node_allocator(__ht._M_node_allocator), + _M_bucket_count(__ht._M_bucket_count), + _M_element_count(__ht._M_element_count), + _M_rehash_policy(__ht._M_rehash_policy) + { + _M_buckets = _M_allocate_buckets(_M_bucket_count); + __try + { + for (size_type __i = 0; __i < __ht._M_bucket_count; ++__i) + { + _Node* __n = __ht._M_buckets[__i]; + _Node** __tail = _M_buckets + __i; + while (__n) + { + *__tail = _M_allocate_node(__n->_M_v); + this->_M_copy_code(*__tail, __n); + __tail = &((*__tail)->_M_next); + __n = __n->_M_next; + } + } + } + __catch(...) + { + clear(); + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + __throw_exception_again; + } + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>& + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + operator=(const _Hashtable& __ht) + { + _Hashtable __tmp(__ht); + this->swap(__tmp); + return *this; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + ~_Hashtable() + { + clear(); + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + swap(_Hashtable& __x) + { + // The only base class with member variables is hash_code_base. We + // define _Hash_code_base::_M_swap because different specializations + // have different members. + __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, __chc>::_M_swap(__x); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_Node_allocator_type>::_S_do_it(_M_node_allocator, + __x._M_node_allocator); + + std::swap(_M_rehash_policy, __x._M_rehash_policy); + std::swap(_M_buckets, __x._M_buckets); + std::swap(_M_bucket_count, __x._M_bucket_count); + std::swap(_M_element_count, __x._M_element_count); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + __rehash_policy(const _RehashPolicy& __pol) + { + _M_rehash_policy = __pol; + size_type __n_bkt = __pol._M_bkt_for_elements(_M_element_count); + if (__n_bkt > _M_bucket_count) + _M_rehash(__n_bkt); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + find(const key_type& __k) + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node* __p = _M_find_node(_M_buckets[__n], __k, __code); + return __p ? iterator(__p, _M_buckets + __n) : this->end(); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + find(const key_type& __k) const + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node* __p = _M_find_node(_M_buckets[__n], __k, __code); + return __p ? const_iterator(__p, _M_buckets + __n) : this->end(); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::size_type + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + count(const key_type& __k) const + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + std::size_t __result = 0; + for (_Node* __p = _M_buckets[__n]; __p; __p = __p->_M_next) + if (this->_M_compare(__k, __code, __p)) + ++__result; + return __result; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + std::pair<typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator, + typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + equal_range(const key_type& __k) + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node** __head = _M_buckets + __n; + _Node* __p = _M_find_node(*__head, __k, __code); + + if (__p) + { + _Node* __p1 = __p->_M_next; + for (; __p1; __p1 = __p1->_M_next) + if (!this->_M_compare(__k, __code, __p1)) + break; + + iterator __first(__p, __head); + iterator __last(__p1, __head); + if (!__p1) + __last._M_incr_bucket(); + return std::make_pair(__first, __last); + } + else + return std::make_pair(this->end(), this->end()); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + std::pair<typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator, + typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + equal_range(const key_type& __k) const + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + _Node** __head = _M_buckets + __n; + _Node* __p = _M_find_node(*__head, __k, __code); + + if (__p) + { + _Node* __p1 = __p->_M_next; + for (; __p1; __p1 = __p1->_M_next) + if (!this->_M_compare(__k, __code, __p1)) + break; + + const_iterator __first(__p, __head); + const_iterator __last(__p1, __head); + if (!__p1) + __last._M_incr_bucket(); + return std::make_pair(__first, __last); + } + else + return std::make_pair(this->end(), this->end()); + } + + // Find the node whose key compares equal to k, beginning the search + // at p (usually the head of a bucket). Return nil if no node is found. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, + _Equal, _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::_Node* + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_find_node(_Node* __p, const key_type& __k, + typename _Hashtable::_Hash_code_type __code) const + { + for (; __p; __p = __p->_M_next) + if (this->_M_compare(__k, __code, __p)) + return __p; + return false; + } + + // Insert v in bucket n (assumes no element with its key already present). + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert_bucket(const value_type& __v, size_type __n, + typename _Hashtable::_Hash_code_type __code) + { + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, 1); + + // Allocate the new node before doing the rehash so that we don't + // do a rehash if the allocation throws. + _Node* __new_node = _M_allocate_node(__v); + + __try + { + if (__do_rehash.first) + { + const key_type& __k = this->_M_extract(__v); + __n = this->_M_bucket_index(__k, __code, __do_rehash.second); + _M_rehash(__do_rehash.second); + } + + __new_node->_M_next = _M_buckets[__n]; + this->_M_store_code(__new_node, __code); + _M_buckets[__n] = __new_node; + ++_M_element_count; + return iterator(__new_node, _M_buckets + __n); + } + __catch(...) + { + _M_deallocate_node(__new_node); + __throw_exception_again; + } + } + + // Insert v if no element with its key is already present. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + std::pair<typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator, bool> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert(const value_type& __v, std::tr1::true_type) + { + const key_type& __k = this->_M_extract(__v); + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + + if (_Node* __p = _M_find_node(_M_buckets[__n], __k, __code)) + return std::make_pair(iterator(__p, _M_buckets + __n), false); + return std::make_pair(_M_insert_bucket(__v, __n, __code), true); + } + + // Insert v unconditionally. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert(const value_type& __v, std::tr1::false_type) + { + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, 1); + if (__do_rehash.first) + _M_rehash(__do_rehash.second); + + const key_type& __k = this->_M_extract(__v); + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + + // First find the node, avoid leaking new_node if compare throws. + _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code); + _Node* __new_node = _M_allocate_node(__v); + + if (__prev) + { + __new_node->_M_next = __prev->_M_next; + __prev->_M_next = __new_node; + } + else + { + __new_node->_M_next = _M_buckets[__n]; + _M_buckets[__n] = __new_node; + } + this->_M_store_code(__new_node, __code); + + ++_M_element_count; + return iterator(__new_node, _M_buckets + __n); + } + + // For erase(iterator) and erase(const_iterator). + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_erase_node(_Node* __p, _Node** __b) + { + _Node* __cur = *__b; + if (__cur == __p) + *__b = __cur->_M_next; + else + { + _Node* __next = __cur->_M_next; + while (__next != __p) + { + __cur = __next; + __next = __cur->_M_next; + } + __cur->_M_next = __next->_M_next; + } + + _M_deallocate_node(__p); + --_M_element_count; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + template<typename _InputIterator> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + insert(_InputIterator __first, _InputIterator __last) + { + size_type __n_elt = __detail::__distance_fw(__first, __last); + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, __n_elt); + if (__do_rehash.first) + _M_rehash(__do_rehash.second); + + for (; __first != __last; ++__first) + this->insert(*__first); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(iterator __it) + { + iterator __result = __it; + ++__result; + _M_erase_node(__it._M_cur_node, __it._M_cur_bucket); + return __result; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(const_iterator __it) + { + const_iterator __result = __it; + ++__result; + _M_erase_node(__it._M_cur_node, __it._M_cur_bucket); + return __result; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::size_type + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(const key_type& __k) + { + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + size_type __result = 0; + + _Node** __slot = _M_buckets + __n; + while (*__slot && !this->_M_compare(__k, __code, *__slot)) + __slot = &((*__slot)->_M_next); + + _Node** __saved_slot = 0; + while (*__slot && this->_M_compare(__k, __code, *__slot)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 526. Is it undefined if a function in the standard changes + // in parameters? + if (&this->_M_extract((*__slot)->_M_v) != &__k) + { + _Node* __p = *__slot; + *__slot = __p->_M_next; + _M_deallocate_node(__p); + --_M_element_count; + ++__result; + } + else + { + __saved_slot = __slot; + __slot = &((*__slot)->_M_next); + } + } + + if (__saved_slot) + { + _Node* __p = *__saved_slot; + *__saved_slot = __p->_M_next; + _M_deallocate_node(__p); + --_M_element_count; + ++__result; + } + + return __result; + } + + // ??? This could be optimized by taking advantage of the bucket + // structure, but it's not clear that it's worth doing. It probably + // wouldn't even be an optimization unless the load factor is large. + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(iterator __first, iterator __last) + { + while (__first != __last) + __first = this->erase(__first); + return __last; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::const_iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + erase(const_iterator __first, const_iterator __last) + { + while (__first != __last) + __first = this->erase(__first); + return __last; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + clear() + { + _M_deallocate_nodes(_M_buckets, _M_bucket_count); + _M_element_count = 0; + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + rehash(size_type __n) + { + _M_rehash(std::max(_M_rehash_policy._M_next_bkt(__n), + _M_rehash_policy._M_bkt_for_elements(_M_element_count + + 1))); + } + + template<typename _Key, typename _Value, + typename _Allocator, typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, + bool __chc, bool __cit, bool __uk> + void + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_rehash(size_type __n) + { + _Node** __new_array = _M_allocate_buckets(__n); + __try + { + for (size_type __i = 0; __i < _M_bucket_count; ++__i) + while (_Node* __p = _M_buckets[__i]) + { + std::size_t __new_index = this->_M_bucket_index(__p, __n); + _M_buckets[__i] = __p->_M_next; + __p->_M_next = __new_array[__new_index]; + __new_array[__new_index] = __p; + } + _M_deallocate_buckets(_M_buckets, _M_bucket_count); + _M_bucket_count = __n; + _M_buckets = __new_array; + } + __catch(...) + { + // A failure here means that a hash function threw an exception. + // We can't restore the previous state without calling the hash + // function again, so the only sensible recovery is to delete + // everything. + _M_deallocate_nodes(__new_array, __n); + _M_deallocate_buckets(__new_array, __n); + _M_deallocate_nodes(_M_buckets, _M_bucket_count); + _M_element_count = 0; + __throw_exception_again; + } + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace tr1 +} // namespace std + +#endif // _GLIBCXX_TR1_HASHTABLE_H diff --git a/libstdc++-v3/include/tr1/hashtable_policy.h b/libstdc++-v3/include/tr1/hashtable_policy.h new file mode 100644 index 000000000..82f8fde18 --- /dev/null +++ b/libstdc++-v3/include/tr1/hashtable_policy.h @@ -0,0 +1,783 @@ +// Internal policy header for TR1 unordered_set and unordered_map -*- C++ -*- + +// Copyright (C) 2010, 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/hashtable_policy.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. + * @headername{tr1/unordered_map, tr1/unordered_set} + */ + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +namespace __detail +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Helper function: return distance(first, last) for forward + // iterators, or 0 for input iterators. + template<class _Iterator> + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last, + std::input_iterator_tag) + { return 0; } + + template<class _Iterator> + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last, + std::forward_iterator_tag) + { return std::distance(__first, __last); } + + template<class _Iterator> + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last) + { + typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag; + return __distance_fw(__first, __last, _Tag()); + } + + // Auxiliary types used for all instantiations of _Hashtable: nodes + // and iterators. + + // Nodes, used to wrap elements stored in the hash table. A policy + // template parameter of class template _Hashtable controls whether + // nodes also store a hash code. In some cases (e.g. strings) this + // may be a performance win. + template<typename _Value, bool __cache_hash_code> + struct _Hash_node; + + template<typename _Value> + struct _Hash_node<_Value, true> + { + _Value _M_v; + std::size_t _M_hash_code; + _Hash_node* _M_next; + }; + + template<typename _Value> + struct _Hash_node<_Value, false> + { + _Value _M_v; + _Hash_node* _M_next; + }; + + // Local iterators, used to iterate within a bucket but not between + // buckets. + template<typename _Value, bool __cache> + struct _Node_iterator_base + { + _Node_iterator_base(_Hash_node<_Value, __cache>* __p) + : _M_cur(__p) { } + + void + _M_incr() + { _M_cur = _M_cur->_M_next; } + + _Hash_node<_Value, __cache>* _M_cur; + }; + + template<typename _Value, bool __cache> + inline bool + operator==(const _Node_iterator_base<_Value, __cache>& __x, + const _Node_iterator_base<_Value, __cache>& __y) + { return __x._M_cur == __y._M_cur; } + + template<typename _Value, bool __cache> + inline bool + operator!=(const _Node_iterator_base<_Value, __cache>& __x, + const _Node_iterator_base<_Value, __cache>& __y) + { return __x._M_cur != __y._M_cur; } + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Node_iterator + : public _Node_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value*, _Value*>::__type + pointer; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value&, _Value&>::__type + reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Node_iterator() + : _Node_iterator_base<_Value, __cache>(0) { } + + explicit + _Node_iterator(_Hash_node<_Value, __cache>* __p) + : _Node_iterator_base<_Value, __cache>(__p) { } + + reference + operator*() const + { return this->_M_cur->_M_v; } + + pointer + operator->() const + { return std::__addressof(this->_M_cur->_M_v); } + + _Node_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Node_iterator + operator++(int) + { + _Node_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Node_const_iterator + : public _Node_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef const _Value* pointer; + typedef const _Value& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Node_const_iterator() + : _Node_iterator_base<_Value, __cache>(0) { } + + explicit + _Node_const_iterator(_Hash_node<_Value, __cache>* __p) + : _Node_iterator_base<_Value, __cache>(__p) { } + + _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators, + __cache>& __x) + : _Node_iterator_base<_Value, __cache>(__x._M_cur) { } + + reference + operator*() const + { return this->_M_cur->_M_v; } + + pointer + operator->() const + { return std::__addressof(this->_M_cur->_M_v); } + + _Node_const_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Node_const_iterator + operator++(int) + { + _Node_const_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + template<typename _Value, bool __cache> + struct _Hashtable_iterator_base + { + _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node, + _Hash_node<_Value, __cache>** __bucket) + : _M_cur_node(__node), _M_cur_bucket(__bucket) { } + + void + _M_incr() + { + _M_cur_node = _M_cur_node->_M_next; + if (!_M_cur_node) + _M_incr_bucket(); + } + + void + _M_incr_bucket(); + + _Hash_node<_Value, __cache>* _M_cur_node; + _Hash_node<_Value, __cache>** _M_cur_bucket; + }; + + // Global iterators, used for arbitrary iteration within a hash + // table. Larger and more expensive than local iterators. + template<typename _Value, bool __cache> + void + _Hashtable_iterator_base<_Value, __cache>:: + _M_incr_bucket() + { + ++_M_cur_bucket; + + // This loop requires the bucket array to have a non-null sentinel. + while (!*_M_cur_bucket) + ++_M_cur_bucket; + _M_cur_node = *_M_cur_bucket; + } + + template<typename _Value, bool __cache> + inline bool + operator==(const _Hashtable_iterator_base<_Value, __cache>& __x, + const _Hashtable_iterator_base<_Value, __cache>& __y) + { return __x._M_cur_node == __y._M_cur_node; } + + template<typename _Value, bool __cache> + inline bool + operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x, + const _Hashtable_iterator_base<_Value, __cache>& __y) + { return __x._M_cur_node != __y._M_cur_node; } + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Hashtable_iterator + : public _Hashtable_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value*, _Value*>::__type + pointer; + typedef typename + __gnu_cxx::__conditional_type<__constant_iterators, + const _Value&, _Value&>::__type + reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Hashtable_iterator() + : _Hashtable_iterator_base<_Value, __cache>(0, 0) { } + + _Hashtable_iterator(_Hash_node<_Value, __cache>* __p, + _Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { } + + explicit + _Hashtable_iterator(_Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { } + + reference + operator*() const + { return this->_M_cur_node->_M_v; } + + pointer + operator->() const + { return std::__addressof(this->_M_cur_node->_M_v); } + + _Hashtable_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Hashtable_iterator + operator++(int) + { + _Hashtable_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + template<typename _Value, bool __constant_iterators, bool __cache> + struct _Hashtable_const_iterator + : public _Hashtable_iterator_base<_Value, __cache> + { + typedef _Value value_type; + typedef const _Value* pointer; + typedef const _Value& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Hashtable_const_iterator() + : _Hashtable_iterator_base<_Value, __cache>(0, 0) { } + + _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p, + _Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { } + + explicit + _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b) + : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { } + + _Hashtable_const_iterator(const _Hashtable_iterator<_Value, + __constant_iterators, __cache>& __x) + : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node, + __x._M_cur_bucket) { } + + reference + operator*() const + { return this->_M_cur_node->_M_v; } + + pointer + operator->() const + { return std::__addressof(this->_M_cur_node->_M_v); } + + _Hashtable_const_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Hashtable_const_iterator + operator++(int) + { + _Hashtable_const_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + + // Many of class template _Hashtable's template parameters are policy + // classes. These are defaults for the policies. + + // Default range hashing function: use division to fold a large number + // into the range [0, N). + struct _Mod_range_hashing + { + typedef std::size_t first_argument_type; + typedef std::size_t second_argument_type; + typedef std::size_t result_type; + + result_type + operator()(first_argument_type __num, second_argument_type __den) const + { return __num % __den; } + }; + + // Default ranged hash function H. In principle it should be a + // function object composed from objects of type H1 and H2 such that + // h(k, N) = h2(h1(k), N), but that would mean making extra copies of + // h1 and h2. So instead we'll just use a tag to tell class template + // hashtable to do that composition. + struct _Default_ranged_hash { }; + + // Default value for rehash policy. Bucket size is (usually) the + // smallest prime that keeps the load factor small enough. + struct _Prime_rehash_policy + { + _Prime_rehash_policy(float __z = 1.0) + : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) { } + + float + max_load_factor() const + { return _M_max_load_factor; } + + // Return a bucket size no smaller than n. + std::size_t + _M_next_bkt(std::size_t __n) const; + + // Return a bucket count appropriate for n elements + std::size_t + _M_bkt_for_elements(std::size_t __n) const; + + // __n_bkt is current bucket count, __n_elt is current element count, + // and __n_ins is number of elements to be inserted. Do we need to + // increase bucket count? If so, return make_pair(true, n), where n + // is the new bucket count. If not, return make_pair(false, 0). + std::pair<bool, std::size_t> + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) const; + + enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 }; + + float _M_max_load_factor; + float _M_growth_factor; + mutable std::size_t _M_next_resize; + }; + + extern const unsigned long __prime_list[]; + + // XXX This is a hack. There's no good reason for any of + // _Prime_rehash_policy's member functions to be inline. + + // Return a prime no smaller than n. + inline std::size_t + _Prime_rehash_policy:: + _M_next_bkt(std::size_t __n) const + { + const unsigned long* __p = std::lower_bound(__prime_list, __prime_list + + _S_n_primes, __n); + _M_next_resize = + static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor)); + return *__p; + } + + // Return the smallest prime p such that alpha p >= n, where alpha + // is the load factor. + inline std::size_t + _Prime_rehash_policy:: + _M_bkt_for_elements(std::size_t __n) const + { + const float __min_bkts = __n / _M_max_load_factor; + const unsigned long* __p = std::lower_bound(__prime_list, __prime_list + + _S_n_primes, __min_bkts); + _M_next_resize = + static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor)); + return *__p; + } + + // Finds the smallest prime p such that alpha p > __n_elt + __n_ins. + // If p > __n_bkt, return make_pair(true, p); otherwise return + // make_pair(false, 0). In principle this isn't very different from + // _M_bkt_for_elements. + + // The only tricky part is that we're caching the element count at + // which we need to rehash, so we don't have to do a floating-point + // multiply for every insertion. + + inline std::pair<bool, std::size_t> + _Prime_rehash_policy:: + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) const + { + if (__n_elt + __n_ins > _M_next_resize) + { + float __min_bkts = ((float(__n_ins) + float(__n_elt)) + / _M_max_load_factor); + if (__min_bkts > __n_bkt) + { + __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt); + const unsigned long* __p = + std::lower_bound(__prime_list, __prime_list + _S_n_primes, + __min_bkts); + _M_next_resize = static_cast<std::size_t> + (__builtin_ceil(*__p * _M_max_load_factor)); + return std::make_pair(true, *__p); + } + else + { + _M_next_resize = static_cast<std::size_t> + (__builtin_ceil(__n_bkt * _M_max_load_factor)); + return std::make_pair(false, 0); + } + } + else + return std::make_pair(false, 0); + } + + // Base classes for std::tr1::_Hashtable. We define these base + // classes because in some cases we want to do different things + // depending on the value of a policy class. In some cases the + // policy class affects which member functions and nested typedefs + // are defined; we handle that by specializing base class templates. + // Several of the base class templates need to access other members + // of class template _Hashtable, so we use the "curiously recurring + // template pattern" for them. + + // class template _Map_base. If the hashtable has a value type of the + // form pair<T1, T2> and a key extraction policy that returns the + // first part of the pair, the hashtable gets a mapped_type typedef. + // If it satisfies those criteria and also has unique keys, then it + // also gets an operator[]. + template<typename _Key, typename _Value, typename _Ex, bool __unique, + typename _Hashtable> + struct _Map_base { }; + + template<typename _Key, typename _Pair, typename _Hashtable> + struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable> + { + typedef typename _Pair::second_type mapped_type; + }; + + template<typename _Key, typename _Pair, typename _Hashtable> + struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable> + { + typedef typename _Pair::second_type mapped_type; + + mapped_type& + operator[](const _Key& __k); + }; + + template<typename _Key, typename _Pair, typename _Hashtable> + typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, + true, _Hashtable>::mapped_type& + _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: + operator[](const _Key& __k) + { + _Hashtable* __h = static_cast<_Hashtable*>(this); + typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); + std::size_t __n = __h->_M_bucket_index(__k, __code, + __h->_M_bucket_count); + + typename _Hashtable::_Node* __p = + __h->_M_find_node(__h->_M_buckets[__n], __k, __code); + if (!__p) + return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()), + __n, __code)->second; + return (__p->_M_v).second; + } + + // class template _Rehash_base. Give hashtable the max_load_factor + // functions iff the rehash policy is _Prime_rehash_policy. + template<typename _RehashPolicy, typename _Hashtable> + struct _Rehash_base { }; + + template<typename _Hashtable> + struct _Rehash_base<_Prime_rehash_policy, _Hashtable> + { + float + max_load_factor() const + { + const _Hashtable* __this = static_cast<const _Hashtable*>(this); + return __this->__rehash_policy().max_load_factor(); + } + + void + max_load_factor(float __z) + { + _Hashtable* __this = static_cast<_Hashtable*>(this); + __this->__rehash_policy(_Prime_rehash_policy(__z)); + } + }; + + // Class template _Hash_code_base. Encapsulates two policy issues that + // aren't quite orthogonal. + // (1) the difference between using a ranged hash function and using + // the combination of a hash function and a range-hashing function. + // In the former case we don't have such things as hash codes, so + // we have a dummy type as placeholder. + // (2) Whether or not we cache hash codes. Caching hash codes is + // meaningless if we have a ranged hash function. + // We also put the key extraction and equality comparison function + // objects here, for convenience. + + // Primary template: unused except as a hook for specializations. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash, + bool __cache_hash_code> + struct _Hash_code_base; + + // Specialization: ranged hash function, no caching hash codes. H1 + // and H2 are provided but ignored. We define a dummy hash code type. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Hash, false> + { + protected: + _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, + const _H1&, const _H2&, const _Hash& __h) + : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { } + + typedef void* _Hash_code_type; + + _Hash_code_type + _M_hash_code(const _Key& __key) const + { return 0; } + + std::size_t + _M_bucket_index(const _Key& __k, _Hash_code_type, + std::size_t __n) const + { return _M_ranged_hash(__k, __n); } + + std::size_t + _M_bucket_index(const _Hash_node<_Value, false>* __p, + std::size_t __n) const + { return _M_ranged_hash(_M_extract(__p->_M_v), __n); } + + bool + _M_compare(const _Key& __k, _Hash_code_type, + _Hash_node<_Value, false>* __n) const + { return _M_eq(__k, _M_extract(__n->_M_v)); } + + void + _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const + { } + + void + _M_copy_code(_Hash_node<_Value, false>*, + const _Hash_node<_Value, false>*) const + { } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract, __x._M_extract); + std::swap(_M_eq, __x._M_eq); + std::swap(_M_ranged_hash, __x._M_ranged_hash); + } + + protected: + _ExtractKey _M_extract; + _Equal _M_eq; + _Hash _M_ranged_hash; + }; + + + // No specialization for ranged hash function while caching hash codes. + // That combination is meaningless, and trying to do it is an error. + + + // Specialization: ranged hash function, cache hash codes. This + // combination is meaningless, so we provide only a declaration + // and no definition. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2, typename _Hash> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Hash, true>; + + // Specialization: hash function and range-hashing function, no + // caching of hash codes. H is provided but ignored. Provides + // typedef and accessor required by TR1. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Default_ranged_hash, false> + { + typedef _H1 hasher; + + hasher + hash_function() const + { return _M_h1; } + + protected: + _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, + const _H1& __h1, const _H2& __h2, + const _Default_ranged_hash&) + : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { } + + typedef std::size_t _Hash_code_type; + + _Hash_code_type + _M_hash_code(const _Key& __k) const + { return _M_h1(__k); } + + std::size_t + _M_bucket_index(const _Key&, _Hash_code_type __c, + std::size_t __n) const + { return _M_h2(__c, __n); } + + std::size_t + _M_bucket_index(const _Hash_node<_Value, false>* __p, + std::size_t __n) const + { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); } + + bool + _M_compare(const _Key& __k, _Hash_code_type, + _Hash_node<_Value, false>* __n) const + { return _M_eq(__k, _M_extract(__n->_M_v)); } + + void + _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const + { } + + void + _M_copy_code(_Hash_node<_Value, false>*, + const _Hash_node<_Value, false>*) const + { } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract, __x._M_extract); + std::swap(_M_eq, __x._M_eq); + std::swap(_M_h1, __x._M_h1); + std::swap(_M_h2, __x._M_h2); + } + + protected: + _ExtractKey _M_extract; + _Equal _M_eq; + _H1 _M_h1; + _H2 _M_h2; + }; + + // Specialization: hash function and range-hashing function, + // caching hash codes. H is provided but ignored. Provides + // typedef and accessor required by TR1. + template<typename _Key, typename _Value, + typename _ExtractKey, typename _Equal, + typename _H1, typename _H2> + struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, + _Default_ranged_hash, true> + { + typedef _H1 hasher; + + hasher + hash_function() const + { return _M_h1; } + + protected: + _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, + const _H1& __h1, const _H2& __h2, + const _Default_ranged_hash&) + : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { } + + typedef std::size_t _Hash_code_type; + + _Hash_code_type + _M_hash_code(const _Key& __k) const + { return _M_h1(__k); } + + std::size_t + _M_bucket_index(const _Key&, _Hash_code_type __c, + std::size_t __n) const + { return _M_h2(__c, __n); } + + std::size_t + _M_bucket_index(const _Hash_node<_Value, true>* __p, + std::size_t __n) const + { return _M_h2(__p->_M_hash_code, __n); } + + bool + _M_compare(const _Key& __k, _Hash_code_type __c, + _Hash_node<_Value, true>* __n) const + { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); } + + void + _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const + { __n->_M_hash_code = __c; } + + void + _M_copy_code(_Hash_node<_Value, true>* __to, + const _Hash_node<_Value, true>* __from) const + { __to->_M_hash_code = __from->_M_hash_code; } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract, __x._M_extract); + std::swap(_M_eq, __x._M_eq); + std::swap(_M_h1, __x._M_h1); + std::swap(_M_h2, __x._M_h2); + } + + protected: + _ExtractKey _M_extract; + _Equal _M_eq; + _H1 _M_h1; + _H2 _M_h2; + }; +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace __detail +} +} diff --git a/libstdc++-v3/include/tr1/hypergeometric.tcc b/libstdc++-v3/include/tr1/hypergeometric.tcc new file mode 100644 index 000000000..b98b5b29c --- /dev/null +++ b/libstdc++-v3/include/tr1/hypergeometric.tcc @@ -0,0 +1,779 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/hypergeometric.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based: +// (1) Handbook of Mathematical Functions, +// ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, +// Section 6, pp. 555-566 +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl + +#ifndef _GLIBCXX_TR1_HYPERGEOMETRIC_TCC +#define _GLIBCXX_TR1_HYPERGEOMETRIC_TCC 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief This routine returns the confluent hypergeometric function + * by series expansion. + * + * @f[ + * _1F_1(a;c;x) = \frac{\Gamma(c)}{\Gamma(a)} + * \sum_{n=0}^{\infty} + * \frac{\Gamma(a+n)}{\Gamma(c+n)} + * \frac{x^n}{n!} + * @f] + * + * If a and b are integers and a < 0 and either b > 0 or b < a + * then the series is a polynomial with a finite number of + * terms. If b is an integer and b <= 0 the confluent + * hypergeometric function is undefined. + * + * @param __a The "numerator" parameter. + * @param __c The "denominator" parameter. + * @param __x The argument of the confluent hypergeometric function. + * @return The confluent hypergeometric function. + */ + template<typename _Tp> + _Tp + __conf_hyperg_series(const _Tp __a, const _Tp __c, const _Tp __x) + { + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + + _Tp __term = _Tp(1); + _Tp __Fac = _Tp(1); + const unsigned int __max_iter = 100000; + unsigned int __i; + for (__i = 0; __i < __max_iter; ++__i) + { + __term *= (__a + _Tp(__i)) * __x + / ((__c + _Tp(__i)) * _Tp(1 + __i)); + if (std::abs(__term) < __eps) + { + break; + } + __Fac += __term; + } + if (__i == __max_iter) + std::__throw_runtime_error(__N("Series failed to converge " + "in __conf_hyperg_series.")); + + return __Fac; + } + + + /** + * @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$ + * by an iterative procedure described in + * Luke, Algorithms for the Computation of Mathematical Functions. + * + * Like the case of the 2F1 rational approximations, these are + * probably guaranteed to converge for x < 0, barring gross + * numerical instability in the pre-asymptotic regime. + */ + template<typename _Tp> + _Tp + __conf_hyperg_luke(const _Tp __a, const _Tp __c, const _Tp __xin) + { + const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L)); + const int __nmax = 20000; + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __x = -__xin; + const _Tp __x3 = __x * __x * __x; + const _Tp __t0 = __a / __c; + const _Tp __t1 = (__a + _Tp(1)) / (_Tp(2) * __c); + const _Tp __t2 = (__a + _Tp(2)) / (_Tp(2) * (__c + _Tp(1))); + _Tp __F = _Tp(1); + _Tp __prec; + + _Tp __Bnm3 = _Tp(1); + _Tp __Bnm2 = _Tp(1) + __t1 * __x; + _Tp __Bnm1 = _Tp(1) + __t2 * __x * (_Tp(1) + __t1 / _Tp(3) * __x); + + _Tp __Anm3 = _Tp(1); + _Tp __Anm2 = __Bnm2 - __t0 * __x; + _Tp __Anm1 = __Bnm1 - __t0 * (_Tp(1) + __t2 * __x) * __x + + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x; + + int __n = 3; + while(1) + { + _Tp __npam1 = _Tp(__n - 1) + __a; + _Tp __npcm1 = _Tp(__n - 1) + __c; + _Tp __npam2 = _Tp(__n - 2) + __a; + _Tp __npcm2 = _Tp(__n - 2) + __c; + _Tp __tnm1 = _Tp(2 * __n - 1); + _Tp __tnm3 = _Tp(2 * __n - 3); + _Tp __tnm5 = _Tp(2 * __n - 5); + _Tp __F1 = (_Tp(__n - 2) - __a) / (_Tp(2) * __tnm3 * __npcm1); + _Tp __F2 = (_Tp(__n) + __a) * __npam1 + / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1); + _Tp __F3 = -__npam2 * __npam1 * (_Tp(__n - 2) - __a) + / (_Tp(8) * __tnm3 * __tnm3 * __tnm5 + * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1); + _Tp __E = -__npam1 * (_Tp(__n - 1) - __c) + / (_Tp(2) * __tnm3 * __npcm2 * __npcm1); + + _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1 + + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3; + _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1 + + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3; + _Tp __r = __An / __Bn; + + __prec = std::abs((__F - __r) / __F); + __F = __r; + + if (__prec < __eps || __n > __nmax) + break; + + if (std::abs(__An) > __big || std::abs(__Bn) > __big) + { + __An /= __big; + __Bn /= __big; + __Anm1 /= __big; + __Bnm1 /= __big; + __Anm2 /= __big; + __Bnm2 /= __big; + __Anm3 /= __big; + __Bnm3 /= __big; + } + else if (std::abs(__An) < _Tp(1) / __big + || std::abs(__Bn) < _Tp(1) / __big) + { + __An *= __big; + __Bn *= __big; + __Anm1 *= __big; + __Bnm1 *= __big; + __Anm2 *= __big; + __Bnm2 *= __big; + __Anm3 *= __big; + __Bnm3 *= __big; + } + + ++__n; + __Bnm3 = __Bnm2; + __Bnm2 = __Bnm1; + __Bnm1 = __Bn; + __Anm3 = __Anm2; + __Anm2 = __Anm1; + __Anm1 = __An; + } + + if (__n >= __nmax) + std::__throw_runtime_error(__N("Iteration failed to converge " + "in __conf_hyperg_luke.")); + + return __F; + } + + + /** + * @brief Return the confluent hypogeometric function + * @f$ _1F_1(a;c;x) @f$. + * + * @todo Handle b == nonpositive integer blowup - return NaN. + * + * @param __a The @a numerator parameter. + * @param __c The @a denominator parameter. + * @param __x The argument of the confluent hypergeometric function. + * @return The confluent hypergeometric function. + */ + template<typename _Tp> + inline _Tp + __conf_hyperg(const _Tp __a, const _Tp __c, const _Tp __x) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + const _Tp __c_nint = std::tr1::nearbyint(__c); +#else + const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L)); +#endif + if (__isnan(__a) || __isnan(__c) || __isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__c_nint == __c && __c_nint <= 0) + return std::numeric_limits<_Tp>::infinity(); + else if (__a == _Tp(0)) + return _Tp(1); + else if (__c == __a) + return std::exp(__x); + else if (__x < _Tp(0)) + return __conf_hyperg_luke(__a, __c, __x); + else + return __conf_hyperg_series(__a, __c, __x); + } + + + /** + * @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$ + * by series expansion. + * + * The hypogeometric function is defined by + * @f[ + * _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)} + * \sum_{n=0}^{\infty} + * \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)} + * \frac{x^n}{n!} + * @f] + * + * This works and it's pretty fast. + * + * @param __a The first @a numerator parameter. + * @param __a The second @a numerator parameter. + * @param __c The @a denominator parameter. + * @param __x The argument of the confluent hypergeometric function. + * @return The confluent hypergeometric function. + */ + template<typename _Tp> + _Tp + __hyperg_series(const _Tp __a, const _Tp __b, + const _Tp __c, const _Tp __x) + { + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + + _Tp __term = _Tp(1); + _Tp __Fabc = _Tp(1); + const unsigned int __max_iter = 100000; + unsigned int __i; + for (__i = 0; __i < __max_iter; ++__i) + { + __term *= (__a + _Tp(__i)) * (__b + _Tp(__i)) * __x + / ((__c + _Tp(__i)) * _Tp(1 + __i)); + if (std::abs(__term) < __eps) + { + break; + } + __Fabc += __term; + } + if (__i == __max_iter) + std::__throw_runtime_error(__N("Series failed to converge " + "in __hyperg_series.")); + + return __Fabc; + } + + + /** + * @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$ + * by an iterative procedure described in + * Luke, Algorithms for the Computation of Mathematical Functions. + */ + template<typename _Tp> + _Tp + __hyperg_luke(const _Tp __a, const _Tp __b, const _Tp __c, + const _Tp __xin) + { + const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L)); + const int __nmax = 20000; + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __x = -__xin; + const _Tp __x3 = __x * __x * __x; + const _Tp __t0 = __a * __b / __c; + const _Tp __t1 = (__a + _Tp(1)) * (__b + _Tp(1)) / (_Tp(2) * __c); + const _Tp __t2 = (__a + _Tp(2)) * (__b + _Tp(2)) + / (_Tp(2) * (__c + _Tp(1))); + + _Tp __F = _Tp(1); + + _Tp __Bnm3 = _Tp(1); + _Tp __Bnm2 = _Tp(1) + __t1 * __x; + _Tp __Bnm1 = _Tp(1) + __t2 * __x * (_Tp(1) + __t1 / _Tp(3) * __x); + + _Tp __Anm3 = _Tp(1); + _Tp __Anm2 = __Bnm2 - __t0 * __x; + _Tp __Anm1 = __Bnm1 - __t0 * (_Tp(1) + __t2 * __x) * __x + + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x; + + int __n = 3; + while (1) + { + const _Tp __npam1 = _Tp(__n - 1) + __a; + const _Tp __npbm1 = _Tp(__n - 1) + __b; + const _Tp __npcm1 = _Tp(__n - 1) + __c; + const _Tp __npam2 = _Tp(__n - 2) + __a; + const _Tp __npbm2 = _Tp(__n - 2) + __b; + const _Tp __npcm2 = _Tp(__n - 2) + __c; + const _Tp __tnm1 = _Tp(2 * __n - 1); + const _Tp __tnm3 = _Tp(2 * __n - 3); + const _Tp __tnm5 = _Tp(2 * __n - 5); + const _Tp __n2 = __n * __n; + const _Tp __F1 = (_Tp(3) * __n2 + (__a + __b - _Tp(6)) * __n + + _Tp(2) - __a * __b - _Tp(2) * (__a + __b)) + / (_Tp(2) * __tnm3 * __npcm1); + const _Tp __F2 = -(_Tp(3) * __n2 - (__a + __b + _Tp(6)) * __n + + _Tp(2) - __a * __b) * __npam1 * __npbm1 + / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1); + const _Tp __F3 = (__npam2 * __npam1 * __npbm2 * __npbm1 + * (_Tp(__n - 2) - __a) * (_Tp(__n - 2) - __b)) + / (_Tp(8) * __tnm3 * __tnm3 * __tnm5 + * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1); + const _Tp __E = -__npam1 * __npbm1 * (_Tp(__n - 1) - __c) + / (_Tp(2) * __tnm3 * __npcm2 * __npcm1); + + _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1 + + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3; + _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1 + + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3; + const _Tp __r = __An / __Bn; + + const _Tp __prec = std::abs((__F - __r) / __F); + __F = __r; + + if (__prec < __eps || __n > __nmax) + break; + + if (std::abs(__An) > __big || std::abs(__Bn) > __big) + { + __An /= __big; + __Bn /= __big; + __Anm1 /= __big; + __Bnm1 /= __big; + __Anm2 /= __big; + __Bnm2 /= __big; + __Anm3 /= __big; + __Bnm3 /= __big; + } + else if (std::abs(__An) < _Tp(1) / __big + || std::abs(__Bn) < _Tp(1) / __big) + { + __An *= __big; + __Bn *= __big; + __Anm1 *= __big; + __Bnm1 *= __big; + __Anm2 *= __big; + __Bnm2 *= __big; + __Anm3 *= __big; + __Bnm3 *= __big; + } + + ++__n; + __Bnm3 = __Bnm2; + __Bnm2 = __Bnm1; + __Bnm1 = __Bn; + __Anm3 = __Anm2; + __Anm2 = __Anm1; + __Anm1 = __An; + } + + if (__n >= __nmax) + std::__throw_runtime_error(__N("Iteration failed to converge " + "in __hyperg_luke.")); + + return __F; + } + + + /** + * @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$ + * by the reflection formulae in Abramowitz & Stegun formula + * 15.3.6 for d = c - a - b not integral and formula 15.3.11 for + * d = c - a - b integral. This assumes a, b, c != negative + * integer. + * + * The hypogeometric function is defined by + * @f[ + * _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)} + * \sum_{n=0}^{\infty} + * \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)} + * \frac{x^n}{n!} + * @f] + * + * The reflection formula for nonintegral @f$ d = c - a - b @f$ is: + * @f[ + * _2F_1(a,b;c;x) = \frac{\Gamma(c)\Gamma(d)}{\Gamma(c-a)\Gamma(c-b)} + * _2F_1(a,b;1-d;1-x) + * + \frac{\Gamma(c)\Gamma(-d)}{\Gamma(a)\Gamma(b)} + * _2F_1(c-a,c-b;1+d;1-x) + * @f] + * + * The reflection formula for integral @f$ m = c - a - b @f$ is: + * @f[ + * _2F_1(a,b;a+b+m;x) = \frac{\Gamma(m)\Gamma(a+b+m)}{\Gamma(a+m)\Gamma(b+m)} + * \sum_{k=0}^{m-1} \frac{(m+a)_k(m+b)_k}{k!(1-m)_k} + * - + * @f] + */ + template<typename _Tp> + _Tp + __hyperg_reflect(const _Tp __a, const _Tp __b, const _Tp __c, + const _Tp __x) + { + const _Tp __d = __c - __a - __b; + const int __intd = std::floor(__d + _Tp(0.5L)); + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __toler = _Tp(1000) * __eps; + const _Tp __log_max = std::log(std::numeric_limits<_Tp>::max()); + const bool __d_integer = (std::abs(__d - __intd) < __toler); + + if (__d_integer) + { + const _Tp __ln_omx = std::log(_Tp(1) - __x); + const _Tp __ad = std::abs(__d); + _Tp __F1, __F2; + + _Tp __d1, __d2; + if (__d >= _Tp(0)) + { + __d1 = __d; + __d2 = _Tp(0); + } + else + { + __d1 = _Tp(0); + __d2 = __d; + } + + const _Tp __lng_c = __log_gamma(__c); + + // Evaluate F1. + if (__ad < __eps) + { + // d = c - a - b = 0. + __F1 = _Tp(0); + } + else + { + + bool __ok_d1 = true; + _Tp __lng_ad, __lng_ad1, __lng_bd1; + __try + { + __lng_ad = __log_gamma(__ad); + __lng_ad1 = __log_gamma(__a + __d1); + __lng_bd1 = __log_gamma(__b + __d1); + } + __catch(...) + { + __ok_d1 = false; + } + + if (__ok_d1) + { + /* Gamma functions in the denominator are ok. + * Proceed with evaluation. + */ + _Tp __sum1 = _Tp(1); + _Tp __term = _Tp(1); + _Tp __ln_pre1 = __lng_ad + __lng_c + __d2 * __ln_omx + - __lng_ad1 - __lng_bd1; + + /* Do F1 sum. + */ + for (int __i = 1; __i < __ad; ++__i) + { + const int __j = __i - 1; + __term *= (__a + __d2 + __j) * (__b + __d2 + __j) + / (_Tp(1) + __d2 + __j) / __i * (_Tp(1) - __x); + __sum1 += __term; + } + + if (__ln_pre1 > __log_max) + std::__throw_runtime_error(__N("Overflow of gamma functions" + " in __hyperg_luke.")); + else + __F1 = std::exp(__ln_pre1) * __sum1; + } + else + { + // Gamma functions in the denominator were not ok. + // So the F1 term is zero. + __F1 = _Tp(0); + } + } // end F1 evaluation + + // Evaluate F2. + bool __ok_d2 = true; + _Tp __lng_ad2, __lng_bd2; + __try + { + __lng_ad2 = __log_gamma(__a + __d2); + __lng_bd2 = __log_gamma(__b + __d2); + } + __catch(...) + { + __ok_d2 = false; + } + + if (__ok_d2) + { + // Gamma functions in the denominator are ok. + // Proceed with evaluation. + const int __maxiter = 2000; + const _Tp __psi_1 = -__numeric_constants<_Tp>::__gamma_e(); + const _Tp __psi_1pd = __psi(_Tp(1) + __ad); + const _Tp __psi_apd1 = __psi(__a + __d1); + const _Tp __psi_bpd1 = __psi(__b + __d1); + + _Tp __psi_term = __psi_1 + __psi_1pd - __psi_apd1 + - __psi_bpd1 - __ln_omx; + _Tp __fact = _Tp(1); + _Tp __sum2 = __psi_term; + _Tp __ln_pre2 = __lng_c + __d1 * __ln_omx + - __lng_ad2 - __lng_bd2; + + // Do F2 sum. + int __j; + for (__j = 1; __j < __maxiter; ++__j) + { + // Values for psi functions use recurrence; + // Abramowitz & Stegun 6.3.5 + const _Tp __term1 = _Tp(1) / _Tp(__j) + + _Tp(1) / (__ad + __j); + const _Tp __term2 = _Tp(1) / (__a + __d1 + _Tp(__j - 1)) + + _Tp(1) / (__b + __d1 + _Tp(__j - 1)); + __psi_term += __term1 - __term2; + __fact *= (__a + __d1 + _Tp(__j - 1)) + * (__b + __d1 + _Tp(__j - 1)) + / ((__ad + __j) * __j) * (_Tp(1) - __x); + const _Tp __delta = __fact * __psi_term; + __sum2 += __delta; + if (std::abs(__delta) < __eps * std::abs(__sum2)) + break; + } + if (__j == __maxiter) + std::__throw_runtime_error(__N("Sum F2 failed to converge " + "in __hyperg_reflect")); + + if (__sum2 == _Tp(0)) + __F2 = _Tp(0); + else + __F2 = std::exp(__ln_pre2) * __sum2; + } + else + { + // Gamma functions in the denominator not ok. + // So the F2 term is zero. + __F2 = _Tp(0); + } // end F2 evaluation + + const _Tp __sgn_2 = (__intd % 2 == 1 ? -_Tp(1) : _Tp(1)); + const _Tp __F = __F1 + __sgn_2 * __F2; + + return __F; + } + else + { + // d = c - a - b not an integer. + + // These gamma functions appear in the denominator, so we + // catch their harmless domain errors and set the terms to zero. + bool __ok1 = true; + _Tp __sgn_g1ca = _Tp(0), __ln_g1ca = _Tp(0); + _Tp __sgn_g1cb = _Tp(0), __ln_g1cb = _Tp(0); + __try + { + __sgn_g1ca = __log_gamma_sign(__c - __a); + __ln_g1ca = __log_gamma(__c - __a); + __sgn_g1cb = __log_gamma_sign(__c - __b); + __ln_g1cb = __log_gamma(__c - __b); + } + __catch(...) + { + __ok1 = false; + } + + bool __ok2 = true; + _Tp __sgn_g2a = _Tp(0), __ln_g2a = _Tp(0); + _Tp __sgn_g2b = _Tp(0), __ln_g2b = _Tp(0); + __try + { + __sgn_g2a = __log_gamma_sign(__a); + __ln_g2a = __log_gamma(__a); + __sgn_g2b = __log_gamma_sign(__b); + __ln_g2b = __log_gamma(__b); + } + __catch(...) + { + __ok2 = false; + } + + const _Tp __sgn_gc = __log_gamma_sign(__c); + const _Tp __ln_gc = __log_gamma(__c); + const _Tp __sgn_gd = __log_gamma_sign(__d); + const _Tp __ln_gd = __log_gamma(__d); + const _Tp __sgn_gmd = __log_gamma_sign(-__d); + const _Tp __ln_gmd = __log_gamma(-__d); + + const _Tp __sgn1 = __sgn_gc * __sgn_gd * __sgn_g1ca * __sgn_g1cb; + const _Tp __sgn2 = __sgn_gc * __sgn_gmd * __sgn_g2a * __sgn_g2b; + + _Tp __pre1, __pre2; + if (__ok1 && __ok2) + { + _Tp __ln_pre1 = __ln_gc + __ln_gd - __ln_g1ca - __ln_g1cb; + _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a - __ln_g2b + + __d * std::log(_Tp(1) - __x); + if (__ln_pre1 < __log_max && __ln_pre2 < __log_max) + { + __pre1 = std::exp(__ln_pre1); + __pre2 = std::exp(__ln_pre2); + __pre1 *= __sgn1; + __pre2 *= __sgn2; + } + else + { + std::__throw_runtime_error(__N("Overflow of gamma functions " + "in __hyperg_reflect")); + } + } + else if (__ok1 && !__ok2) + { + _Tp __ln_pre1 = __ln_gc + __ln_gd - __ln_g1ca - __ln_g1cb; + if (__ln_pre1 < __log_max) + { + __pre1 = std::exp(__ln_pre1); + __pre1 *= __sgn1; + __pre2 = _Tp(0); + } + else + { + std::__throw_runtime_error(__N("Overflow of gamma functions " + "in __hyperg_reflect")); + } + } + else if (!__ok1 && __ok2) + { + _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a - __ln_g2b + + __d * std::log(_Tp(1) - __x); + if (__ln_pre2 < __log_max) + { + __pre1 = _Tp(0); + __pre2 = std::exp(__ln_pre2); + __pre2 *= __sgn2; + } + else + { + std::__throw_runtime_error(__N("Overflow of gamma functions " + "in __hyperg_reflect")); + } + } + else + { + __pre1 = _Tp(0); + __pre2 = _Tp(0); + std::__throw_runtime_error(__N("Underflow of gamma functions " + "in __hyperg_reflect")); + } + + const _Tp __F1 = __hyperg_series(__a, __b, _Tp(1) - __d, + _Tp(1) - __x); + const _Tp __F2 = __hyperg_series(__c - __a, __c - __b, _Tp(1) + __d, + _Tp(1) - __x); + + const _Tp __F = __pre1 * __F1 + __pre2 * __F2; + + return __F; + } + } + + + /** + * @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$. + * + * The hypogeometric function is defined by + * @f[ + * _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)} + * \sum_{n=0}^{\infty} + * \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)} + * \frac{x^n}{n!} + * @f] + * + * @param __a The first @a numerator parameter. + * @param __a The second @a numerator parameter. + * @param __c The @a denominator parameter. + * @param __x The argument of the confluent hypergeometric function. + * @return The confluent hypergeometric function. + */ + template<typename _Tp> + inline _Tp + __hyperg(const _Tp __a, const _Tp __b, const _Tp __c, const _Tp __x) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + const _Tp __a_nint = std::tr1::nearbyint(__a); + const _Tp __b_nint = std::tr1::nearbyint(__b); + const _Tp __c_nint = std::tr1::nearbyint(__c); +#else + const _Tp __a_nint = static_cast<int>(__a + _Tp(0.5L)); + const _Tp __b_nint = static_cast<int>(__b + _Tp(0.5L)); + const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L)); +#endif + const _Tp __toler = _Tp(1000) * std::numeric_limits<_Tp>::epsilon(); + if (std::abs(__x) >= _Tp(1)) + std::__throw_domain_error(__N("Argument outside unit circle " + "in __hyperg.")); + else if (__isnan(__a) || __isnan(__b) + || __isnan(__c) || __isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__c_nint == __c && __c_nint <= _Tp(0)) + return std::numeric_limits<_Tp>::infinity(); + else if (std::abs(__c - __b) < __toler || std::abs(__c - __a) < __toler) + return std::pow(_Tp(1) - __x, __c - __a - __b); + else if (__a >= _Tp(0) && __b >= _Tp(0) && __c >= _Tp(0) + && __x >= _Tp(0) && __x < _Tp(0.995L)) + return __hyperg_series(__a, __b, __c, __x); + else if (std::abs(__a) < _Tp(10) && std::abs(__b) < _Tp(10)) + { + // For integer a and b the hypergeometric function is a + // finite polynomial. + if (__a < _Tp(0) && std::abs(__a - __a_nint) < __toler) + return __hyperg_series(__a_nint, __b, __c, __x); + else if (__b < _Tp(0) && std::abs(__b - __b_nint) < __toler) + return __hyperg_series(__a, __b_nint, __c, __x); + else if (__x < -_Tp(0.25L)) + return __hyperg_luke(__a, __b, __c, __x); + else if (__x < _Tp(0.5L)) + return __hyperg_series(__a, __b, __c, __x); + else + if (std::abs(__c) > _Tp(10)) + return __hyperg_series(__a, __b, __c, __x); + else + return __hyperg_reflect(__a, __b, __c, __x); + } + else + return __hyperg_luke(__a, __b, __c, __x); + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_HYPERGEOMETRIC_TCC diff --git a/libstdc++-v3/include/tr1/inttypes.h b/libstdc++-v3/include/tr1/inttypes.h new file mode 100644 index 000000000..4c8fd45d8 --- /dev/null +++ b/libstdc++-v3/include/tr1/inttypes.h @@ -0,0 +1,34 @@ +// TR1 inttypes.h -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/inttypes.h + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_INTTYPES_H +#define _GLIBCXX_TR1_INTTYPES_H 1 + +#include <tr1/cinttypes> + +#endif // _GLIBCXX_TR1_INTTYPES_H diff --git a/libstdc++-v3/include/tr1/legendre_function.tcc b/libstdc++-v3/include/tr1/legendre_function.tcc new file mode 100644 index 000000000..db41d4e0a --- /dev/null +++ b/libstdc++-v3/include/tr1/legendre_function.tcc @@ -0,0 +1,306 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/legendre_function.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// (1) Handbook of Mathematical Functions, +// ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, +// Section 8, pp. 331-341 +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky, +// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992), +// 2nd ed, pp. 252-254 + +#ifndef _GLIBCXX_TR1_LEGENDRE_FUNCTION_TCC +#define _GLIBCXX_TR1_LEGENDRE_FUNCTION_TCC 1 + +#include "special_function_util.h" + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Return the Legendre polynomial by recursion on order + * @f$ l @f$. + * + * The Legendre function of @f$ l @f$ and @f$ x @f$, + * @f$ P_l(x) @f$, is defined by: + * @f[ + * P_l(x) = \frac{1}{2^l l!}\frac{d^l}{dx^l}(x^2 - 1)^{l} + * @f] + * + * @param l The order of the Legendre polynomial. @f$l >= 0@f$. + * @param x The argument of the Legendre polynomial. @f$|x| <= 1@f$. + */ + template<typename _Tp> + _Tp + __poly_legendre_p(const unsigned int __l, const _Tp __x) + { + + if ((__x < _Tp(-1)) || (__x > _Tp(+1))) + std::__throw_domain_error(__N("Argument out of range" + " in __poly_legendre_p.")); + else if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x == +_Tp(1)) + return +_Tp(1); + else if (__x == -_Tp(1)) + return (__l % 2 == 1 ? -_Tp(1) : +_Tp(1)); + else + { + _Tp __p_lm2 = _Tp(1); + if (__l == 0) + return __p_lm2; + + _Tp __p_lm1 = __x; + if (__l == 1) + return __p_lm1; + + _Tp __p_l = 0; + for (unsigned int __ll = 2; __ll <= __l; ++__ll) + { + // This arrangement is supposed to be better for roundoff + // protection, Arfken, 2nd Ed, Eq 12.17a. + __p_l = _Tp(2) * __x * __p_lm1 - __p_lm2 + - (__x * __p_lm1 - __p_lm2) / _Tp(__ll); + __p_lm2 = __p_lm1; + __p_lm1 = __p_l; + } + + return __p_l; + } + } + + + /** + * @brief Return the associated Legendre function by recursion + * on @f$ l @f$. + * + * The associated Legendre function is derived from the Legendre function + * @f$ P_l(x) @f$ by the Rodrigues formula: + * @f[ + * P_l^m(x) = (1 - x^2)^{m/2}\frac{d^m}{dx^m}P_l(x) + * @f] + * + * @param l The order of the associated Legendre function. + * @f$ l >= 0 @f$. + * @param m The order of the associated Legendre function. + * @f$ m <= l @f$. + * @param x The argument of the associated Legendre function. + * @f$ |x| <= 1 @f$. + */ + template<typename _Tp> + _Tp + __assoc_legendre_p(const unsigned int __l, const unsigned int __m, + const _Tp __x) + { + + if (__x < _Tp(-1) || __x > _Tp(+1)) + std::__throw_domain_error(__N("Argument out of range" + " in __assoc_legendre_p.")); + else if (__m > __l) + std::__throw_domain_error(__N("Degree out of range" + " in __assoc_legendre_p.")); + else if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__m == 0) + return __poly_legendre_p(__l, __x); + else + { + _Tp __p_mm = _Tp(1); + if (__m > 0) + { + // Two square roots seem more accurate more of the time + // than just one. + _Tp __root = std::sqrt(_Tp(1) - __x) * std::sqrt(_Tp(1) + __x); + _Tp __fact = _Tp(1); + for (unsigned int __i = 1; __i <= __m; ++__i) + { + __p_mm *= -__fact * __root; + __fact += _Tp(2); + } + } + if (__l == __m) + return __p_mm; + + _Tp __p_mp1m = _Tp(2 * __m + 1) * __x * __p_mm; + if (__l == __m + 1) + return __p_mp1m; + + _Tp __p_lm2m = __p_mm; + _Tp __P_lm1m = __p_mp1m; + _Tp __p_lm = _Tp(0); + for (unsigned int __j = __m + 2; __j <= __l; ++__j) + { + __p_lm = (_Tp(2 * __j - 1) * __x * __P_lm1m + - _Tp(__j + __m - 1) * __p_lm2m) / _Tp(__j - __m); + __p_lm2m = __P_lm1m; + __P_lm1m = __p_lm; + } + + return __p_lm; + } + } + + + /** + * @brief Return the spherical associated Legendre function. + * + * The spherical associated Legendre function of @f$ l @f$, @f$ m @f$, + * and @f$ \theta @f$ is defined as @f$ Y_l^m(\theta,0) @f$ where + * @f[ + * Y_l^m(\theta,\phi) = (-1)^m[\frac{(2l+1)}{4\pi} + * \frac{(l-m)!}{(l+m)!}] + * P_l^m(\cos\theta) \exp^{im\phi} + * @f] + * is the spherical harmonic function and @f$ P_l^m(x) @f$ is the + * associated Legendre function. + * + * This function differs from the associated Legendre function by + * argument (@f$x = \cos(\theta)@f$) and by a normalization factor + * but this factor is rather large for large @f$ l @f$ and @f$ m @f$ + * and so this function is stable for larger differences of @f$ l @f$ + * and @f$ m @f$. + * + * @param l The order of the spherical associated Legendre function. + * @f$ l >= 0 @f$. + * @param m The order of the spherical associated Legendre function. + * @f$ m <= l @f$. + * @param theta The radian angle argument of the spherical associated + * Legendre function. + */ + template <typename _Tp> + _Tp + __sph_legendre(const unsigned int __l, const unsigned int __m, + const _Tp __theta) + { + if (__isnan(__theta)) + return std::numeric_limits<_Tp>::quiet_NaN(); + + const _Tp __x = std::cos(__theta); + + if (__l < __m) + { + std::__throw_domain_error(__N("Bad argument " + "in __sph_legendre.")); + } + else if (__m == 0) + { + _Tp __P = __poly_legendre_p(__l, __x); + _Tp __fact = std::sqrt(_Tp(2 * __l + 1) + / (_Tp(4) * __numeric_constants<_Tp>::__pi())); + __P *= __fact; + return __P; + } + else if (__x == _Tp(1) || __x == -_Tp(1)) + { + // m > 0 here + return _Tp(0); + } + else + { + // m > 0 and |x| < 1 here + + // Starting value for recursion. + // Y_m^m(x) = sqrt( (2m+1)/(4pi m) gamma(m+1/2)/gamma(m) ) + // (-1)^m (1-x^2)^(m/2) / pi^(1/4) + const _Tp __sgn = ( __m % 2 == 1 ? -_Tp(1) : _Tp(1)); + const _Tp __y_mp1m_factor = __x * std::sqrt(_Tp(2 * __m + 3)); +#if _GLIBCXX_USE_C99_MATH_TR1 + const _Tp __lncirc = std::tr1::log1p(-__x * __x); +#else + const _Tp __lncirc = std::log(_Tp(1) - __x * __x); +#endif + // Gamma(m+1/2) / Gamma(m) +#if _GLIBCXX_USE_C99_MATH_TR1 + const _Tp __lnpoch = std::tr1::lgamma(_Tp(__m + _Tp(0.5L))) + - std::tr1::lgamma(_Tp(__m)); +#else + const _Tp __lnpoch = __log_gamma(_Tp(__m + _Tp(0.5L))) + - __log_gamma(_Tp(__m)); +#endif + const _Tp __lnpre_val = + -_Tp(0.25L) * __numeric_constants<_Tp>::__lnpi() + + _Tp(0.5L) * (__lnpoch + __m * __lncirc); + _Tp __sr = std::sqrt((_Tp(2) + _Tp(1) / __m) + / (_Tp(4) * __numeric_constants<_Tp>::__pi())); + _Tp __y_mm = __sgn * __sr * std::exp(__lnpre_val); + _Tp __y_mp1m = __y_mp1m_factor * __y_mm; + + if (__l == __m) + { + return __y_mm; + } + else if (__l == __m + 1) + { + return __y_mp1m; + } + else + { + _Tp __y_lm = _Tp(0); + + // Compute Y_l^m, l > m+1, upward recursion on l. + for ( int __ll = __m + 2; __ll <= __l; ++__ll) + { + const _Tp __rat1 = _Tp(__ll - __m) / _Tp(__ll + __m); + const _Tp __rat2 = _Tp(__ll - __m - 1) / _Tp(__ll + __m - 1); + const _Tp __fact1 = std::sqrt(__rat1 * _Tp(2 * __ll + 1) + * _Tp(2 * __ll - 1)); + const _Tp __fact2 = std::sqrt(__rat1 * __rat2 * _Tp(2 * __ll + 1) + / _Tp(2 * __ll - 3)); + __y_lm = (__x * __y_mp1m * __fact1 + - (__ll + __m - 1) * __y_mm * __fact2) / _Tp(__ll - __m); + __y_mm = __y_mp1m; + __y_mp1m = __y_lm; + } + + return __y_lm; + } + } + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_LEGENDRE_FUNCTION_TCC diff --git a/libstdc++-v3/include/tr1/limits.h b/libstdc++-v3/include/tr1/limits.h new file mode 100644 index 000000000..d95d360fd --- /dev/null +++ b/libstdc++-v3/include/tr1/limits.h @@ -0,0 +1,34 @@ +// TR1 limits.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/limits.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_LIMITS_H +#define _TR1_LIMITS_H 1 + +#include <tr1/climits> + +#endif diff --git a/libstdc++-v3/include/tr1/math.h b/libstdc++-v3/include/tr1/math.h new file mode 100644 index 000000000..15d6d6419 --- /dev/null +++ b/libstdc++-v3/include/tr1/math.h @@ -0,0 +1,186 @@ +// TR1 math.h -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/math.h + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_MATH_H +#define _GLIBCXX_TR1_MATH_H 1 + +#include <tr1/cmath> + +#if _GLIBCXX_USE_C99_MATH_TR1 + +using std::tr1::acos; +using std::tr1::acosh; +using std::tr1::asin; +using std::tr1::asinh; +using std::tr1::atan; +using std::tr1::atan2; +using std::tr1::atanh; +using std::tr1::cbrt; +using std::tr1::ceil; +using std::tr1::copysign; +using std::tr1::cos; +using std::tr1::cosh; +using std::tr1::erf; +using std::tr1::erfc; +using std::tr1::exp; +using std::tr1::exp2; +using std::tr1::expm1; +using std::tr1::fabs; +using std::tr1::fdim; +using std::tr1::floor; +using std::tr1::fma; +using std::tr1::fmax; +using std::tr1::fmin; +using std::tr1::fmod; +using std::tr1::frexp; +using std::tr1::hypot; +using std::tr1::ilogb; +using std::tr1::ldexp; +using std::tr1::lgamma; +using std::tr1::llrint; +using std::tr1::llround; +using std::tr1::log; +using std::tr1::log10; +using std::tr1::log1p; +using std::tr1::log2; +using std::tr1::logb; +using std::tr1::lrint; +using std::tr1::lround; +using std::tr1::nearbyint; +using std::tr1::nextafter; +using std::tr1::nexttoward; +using std::tr1::pow; +using std::tr1::remainder; +using std::tr1::remquo; +using std::tr1::rint; +using std::tr1::round; +using std::tr1::scalbln; +using std::tr1::scalbn; +using std::tr1::sin; +using std::tr1::sinh; +using std::tr1::sqrt; +using std::tr1::tan; +using std::tr1::tanh; +using std::tr1::tgamma; +using std::tr1::trunc; + +#endif + +using std::tr1::assoc_laguerref; +using std::tr1::assoc_laguerre; +using std::tr1::assoc_laguerrel; + +using std::tr1::assoc_legendref; +using std::tr1::assoc_legendre; +using std::tr1::assoc_legendrel; + +using std::tr1::betaf; +using std::tr1::beta; +using std::tr1::betal; + +using std::tr1::comp_ellint_1f; +using std::tr1::comp_ellint_1; +using std::tr1::comp_ellint_1l; + +using std::tr1::comp_ellint_2f; +using std::tr1::comp_ellint_2; +using std::tr1::comp_ellint_2l; + +using std::tr1::comp_ellint_3f; +using std::tr1::comp_ellint_3; +using std::tr1::comp_ellint_3l; + +using std::tr1::conf_hypergf; +using std::tr1::conf_hyperg; +using std::tr1::conf_hypergl; + +using std::tr1::cyl_bessel_if; +using std::tr1::cyl_bessel_i; +using std::tr1::cyl_bessel_il; + +using std::tr1::cyl_bessel_jf; +using std::tr1::cyl_bessel_j; +using std::tr1::cyl_bessel_jl; + +using std::tr1::cyl_bessel_kf; +using std::tr1::cyl_bessel_k; +using std::tr1::cyl_bessel_kl; + +using std::tr1::cyl_neumannf; +using std::tr1::cyl_neumann; +using std::tr1::cyl_neumannl; + +using std::tr1::ellint_1f; +using std::tr1::ellint_1; +using std::tr1::ellint_1l; + +using std::tr1::ellint_2f; +using std::tr1::ellint_2; +using std::tr1::ellint_2l; + +using std::tr1::ellint_3f; +using std::tr1::ellint_3; +using std::tr1::ellint_3l; + +using std::tr1::expintf; +using std::tr1::expint; +using std::tr1::expintl; + +using std::tr1::hermitef; +using std::tr1::hermite; +using std::tr1::hermitel; + +using std::tr1::hypergf; +using std::tr1::hyperg; +using std::tr1::hypergl; + +using std::tr1::laguerref; +using std::tr1::laguerre; +using std::tr1::laguerrel; + +using std::tr1::legendref; +using std::tr1::legendre; +using std::tr1::legendrel; + +using std::tr1::riemann_zetaf; +using std::tr1::riemann_zeta; +using std::tr1::riemann_zetal; + +using std::tr1::sph_besself; +using std::tr1::sph_bessel; +using std::tr1::sph_bessell; + +using std::tr1::sph_legendref; +using std::tr1::sph_legendre; +using std::tr1::sph_legendrel; + +using std::tr1::sph_neumannf; +using std::tr1::sph_neumann; +using std::tr1::sph_neumannl; + +#endif // _GLIBCXX_TR1_MATH_H diff --git a/libstdc++-v3/include/tr1/memory b/libstdc++-v3/include/tr1/memory new file mode 100644 index 000000000..eaf4932e5 --- /dev/null +++ b/libstdc++-v3/include/tr1/memory @@ -0,0 +1,53 @@ +// <tr1/memory> -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** + * @file tr1/memory + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_MEMORY +#define _GLIBCXX_TR1_MEMORY 1 + +#pragma GCC system_header + +#if defined(_GLIBCXX_INCLUDE_AS_CXX0X) +# error TR1 header cannot be included from C++0x header +#endif + +#include <memory> +#include <exception> // std::exception +#include <typeinfo> // std::type_info in get_deleter +#include <bits/stl_algobase.h> // std::swap +#include <iosfwd> // std::basic_ostream +#include <ext/atomicity.h> +#include <ext/concurrence.h> +#include <bits/functexcept.h> +#include <bits/stl_function.h> // std::less +#include <debug/debug.h> +#include <tr1/type_traits> +#include <tr1/shared_ptr.h> + +#endif // _GLIBCXX_TR1_MEMORY diff --git a/libstdc++-v3/include/tr1/modified_bessel_func.tcc b/libstdc++-v3/include/tr1/modified_bessel_func.tcc new file mode 100644 index 000000000..ec134d576 --- /dev/null +++ b/libstdc++-v3/include/tr1/modified_bessel_func.tcc @@ -0,0 +1,437 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/modified_bessel_func.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland. +// +// References: +// (1) Handbook of Mathematical Functions, +// Ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, +// Section 9, pp. 355-434, Section 10 pp. 435-478 +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky, +// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992), +// 2nd ed, pp. 246-249. + +#ifndef _GLIBCXX_TR1_MODIFIED_BESSEL_FUNC_TCC +#define _GLIBCXX_TR1_MODIFIED_BESSEL_FUNC_TCC 1 + +#include "special_function_util.h" + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Compute the modified Bessel functions @f$ I_\nu(x) @f$ and + * @f$ K_\nu(x) @f$ and their first derivatives + * @f$ I'_\nu(x) @f$ and @f$ K'_\nu(x) @f$ respectively. + * These four functions are computed together for numerical + * stability. + * + * @param __nu The order of the Bessel functions. + * @param __x The argument of the Bessel functions. + * @param __Inu The output regular modified Bessel function. + * @param __Knu The output irregular modified Bessel function. + * @param __Ipnu The output derivative of the regular + * modified Bessel function. + * @param __Kpnu The output derivative of the irregular + * modified Bessel function. + */ + template <typename _Tp> + void + __bessel_ik(const _Tp __nu, const _Tp __x, + _Tp & __Inu, _Tp & __Knu, _Tp & __Ipnu, _Tp & __Kpnu) + { + if (__x == _Tp(0)) + { + if (__nu == _Tp(0)) + { + __Inu = _Tp(1); + __Ipnu = _Tp(0); + } + else if (__nu == _Tp(1)) + { + __Inu = _Tp(0); + __Ipnu = _Tp(0.5L); + } + else + { + __Inu = _Tp(0); + __Ipnu = _Tp(0); + } + __Knu = std::numeric_limits<_Tp>::infinity(); + __Kpnu = -std::numeric_limits<_Tp>::infinity(); + return; + } + + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + const _Tp __fp_min = _Tp(10) * std::numeric_limits<_Tp>::epsilon(); + const int __max_iter = 15000; + const _Tp __x_min = _Tp(2); + + const int __nl = static_cast<int>(__nu + _Tp(0.5L)); + + const _Tp __mu = __nu - __nl; + const _Tp __mu2 = __mu * __mu; + const _Tp __xi = _Tp(1) / __x; + const _Tp __xi2 = _Tp(2) * __xi; + _Tp __h = __nu * __xi; + if ( __h < __fp_min ) + __h = __fp_min; + _Tp __b = __xi2 * __nu; + _Tp __d = _Tp(0); + _Tp __c = __h; + int __i; + for ( __i = 1; __i <= __max_iter; ++__i ) + { + __b += __xi2; + __d = _Tp(1) / (__b + __d); + __c = __b + _Tp(1) / __c; + const _Tp __del = __c * __d; + __h *= __del; + if (std::abs(__del - _Tp(1)) < __eps) + break; + } + if (__i > __max_iter) + std::__throw_runtime_error(__N("Argument x too large " + "in __bessel_jn; " + "try asymptotic expansion.")); + _Tp __Inul = __fp_min; + _Tp __Ipnul = __h * __Inul; + _Tp __Inul1 = __Inul; + _Tp __Ipnu1 = __Ipnul; + _Tp __fact = __nu * __xi; + for (int __l = __nl; __l >= 1; --__l) + { + const _Tp __Inutemp = __fact * __Inul + __Ipnul; + __fact -= __xi; + __Ipnul = __fact * __Inutemp + __Inul; + __Inul = __Inutemp; + } + _Tp __f = __Ipnul / __Inul; + _Tp __Kmu, __Knu1; + if (__x < __x_min) + { + const _Tp __x2 = __x / _Tp(2); + const _Tp __pimu = __numeric_constants<_Tp>::__pi() * __mu; + const _Tp __fact = (std::abs(__pimu) < __eps + ? _Tp(1) : __pimu / std::sin(__pimu)); + _Tp __d = -std::log(__x2); + _Tp __e = __mu * __d; + const _Tp __fact2 = (std::abs(__e) < __eps + ? _Tp(1) : std::sinh(__e) / __e); + _Tp __gam1, __gam2, __gampl, __gammi; + __gamma_temme(__mu, __gam1, __gam2, __gampl, __gammi); + _Tp __ff = __fact + * (__gam1 * std::cosh(__e) + __gam2 * __fact2 * __d); + _Tp __sum = __ff; + __e = std::exp(__e); + _Tp __p = __e / (_Tp(2) * __gampl); + _Tp __q = _Tp(1) / (_Tp(2) * __e * __gammi); + _Tp __c = _Tp(1); + __d = __x2 * __x2; + _Tp __sum1 = __p; + int __i; + for (__i = 1; __i <= __max_iter; ++__i) + { + __ff = (__i * __ff + __p + __q) / (__i * __i - __mu2); + __c *= __d / __i; + __p /= __i - __mu; + __q /= __i + __mu; + const _Tp __del = __c * __ff; + __sum += __del; + const _Tp __del1 = __c * (__p - __i * __ff); + __sum1 += __del1; + if (std::abs(__del) < __eps * std::abs(__sum)) + break; + } + if (__i > __max_iter) + std::__throw_runtime_error(__N("Bessel k series failed to converge " + "in __bessel_jn.")); + __Kmu = __sum; + __Knu1 = __sum1 * __xi2; + } + else + { + _Tp __b = _Tp(2) * (_Tp(1) + __x); + _Tp __d = _Tp(1) / __b; + _Tp __delh = __d; + _Tp __h = __delh; + _Tp __q1 = _Tp(0); + _Tp __q2 = _Tp(1); + _Tp __a1 = _Tp(0.25L) - __mu2; + _Tp __q = __c = __a1; + _Tp __a = -__a1; + _Tp __s = _Tp(1) + __q * __delh; + int __i; + for (__i = 2; __i <= __max_iter; ++__i) + { + __a -= 2 * (__i - 1); + __c = -__a * __c / __i; + const _Tp __qnew = (__q1 - __b * __q2) / __a; + __q1 = __q2; + __q2 = __qnew; + __q += __c * __qnew; + __b += _Tp(2); + __d = _Tp(1) / (__b + __a * __d); + __delh = (__b * __d - _Tp(1)) * __delh; + __h += __delh; + const _Tp __dels = __q * __delh; + __s += __dels; + if ( std::abs(__dels / __s) < __eps ) + break; + } + if (__i > __max_iter) + std::__throw_runtime_error(__N("Steed's method failed " + "in __bessel_jn.")); + __h = __a1 * __h; + __Kmu = std::sqrt(__numeric_constants<_Tp>::__pi() / (_Tp(2) * __x)) + * std::exp(-__x) / __s; + __Knu1 = __Kmu * (__mu + __x + _Tp(0.5L) - __h) * __xi; + } + + _Tp __Kpmu = __mu * __xi * __Kmu - __Knu1; + _Tp __Inumu = __xi / (__f * __Kmu - __Kpmu); + __Inu = __Inumu * __Inul1 / __Inul; + __Ipnu = __Inumu * __Ipnu1 / __Inul; + for ( __i = 1; __i <= __nl; ++__i ) + { + const _Tp __Knutemp = (__mu + __i) * __xi2 * __Knu1 + __Kmu; + __Kmu = __Knu1; + __Knu1 = __Knutemp; + } + __Knu = __Kmu; + __Kpnu = __nu * __xi * __Kmu - __Knu1; + + return; + } + + + /** + * @brief Return the regular modified Bessel function of order + * \f$ \nu \f$: \f$ I_{\nu}(x) \f$. + * + * The regular modified cylindrical Bessel function is: + * @f[ + * I_{\nu}(x) = \sum_{k=0}^{\infty} + * \frac{(x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)} + * @f] + * + * @param __nu The order of the regular modified Bessel function. + * @param __x The argument of the regular modified Bessel function. + * @return The output regular modified Bessel function. + */ + template<typename _Tp> + _Tp + __cyl_bessel_i(const _Tp __nu, const _Tp __x) + { + if (__nu < _Tp(0) || __x < _Tp(0)) + std::__throw_domain_error(__N("Bad argument " + "in __cyl_bessel_i.")); + else if (__isnan(__nu) || __isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x * __x < _Tp(10) * (__nu + _Tp(1))) + return __cyl_bessel_ij_series(__nu, __x, +_Tp(1), 200); + else + { + _Tp __I_nu, __K_nu, __Ip_nu, __Kp_nu; + __bessel_ik(__nu, __x, __I_nu, __K_nu, __Ip_nu, __Kp_nu); + return __I_nu; + } + } + + + /** + * @brief Return the irregular modified Bessel function + * \f$ K_{\nu}(x) \f$ of order \f$ \nu \f$. + * + * The irregular modified Bessel function is defined by: + * @f[ + * K_{\nu}(x) = \frac{\pi}{2} + * \frac{I_{-\nu}(x) - I_{\nu}(x)}{\sin \nu\pi} + * @f] + * where for integral \f$ \nu = n \f$ a limit is taken: + * \f$ lim_{\nu \to n} \f$. + * + * @param __nu The order of the irregular modified Bessel function. + * @param __x The argument of the irregular modified Bessel function. + * @return The output irregular modified Bessel function. + */ + template<typename _Tp> + _Tp + __cyl_bessel_k(const _Tp __nu, const _Tp __x) + { + if (__nu < _Tp(0) || __x < _Tp(0)) + std::__throw_domain_error(__N("Bad argument " + "in __cyl_bessel_k.")); + else if (__isnan(__nu) || __isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else + { + _Tp __I_nu, __K_nu, __Ip_nu, __Kp_nu; + __bessel_ik(__nu, __x, __I_nu, __K_nu, __Ip_nu, __Kp_nu); + return __K_nu; + } + } + + + /** + * @brief Compute the spherical modified Bessel functions + * @f$ i_n(x) @f$ and @f$ k_n(x) @f$ and their first + * derivatives @f$ i'_n(x) @f$ and @f$ k'_n(x) @f$ + * respectively. + * + * @param __n The order of the modified spherical Bessel function. + * @param __x The argument of the modified spherical Bessel function. + * @param __i_n The output regular modified spherical Bessel function. + * @param __k_n The output irregular modified spherical + * Bessel function. + * @param __ip_n The output derivative of the regular modified + * spherical Bessel function. + * @param __kp_n The output derivative of the irregular modified + * spherical Bessel function. + */ + template <typename _Tp> + void + __sph_bessel_ik(const unsigned int __n, const _Tp __x, + _Tp & __i_n, _Tp & __k_n, _Tp & __ip_n, _Tp & __kp_n) + { + const _Tp __nu = _Tp(__n) + _Tp(0.5L); + + _Tp __I_nu, __Ip_nu, __K_nu, __Kp_nu; + __bessel_ik(__nu, __x, __I_nu, __K_nu, __Ip_nu, __Kp_nu); + + const _Tp __factor = __numeric_constants<_Tp>::__sqrtpio2() + / std::sqrt(__x); + + __i_n = __factor * __I_nu; + __k_n = __factor * __K_nu; + __ip_n = __factor * __Ip_nu - __i_n / (_Tp(2) * __x); + __kp_n = __factor * __Kp_nu - __k_n / (_Tp(2) * __x); + + return; + } + + + /** + * @brief Compute the Airy functions + * @f$ Ai(x) @f$ and @f$ Bi(x) @f$ and their first + * derivatives @f$ Ai'(x) @f$ and @f$ Bi(x) @f$ + * respectively. + * + * @param __n The order of the Airy functions. + * @param __x The argument of the Airy functions. + * @param __i_n The output Airy function. + * @param __k_n The output Airy function. + * @param __ip_n The output derivative of the Airy function. + * @param __kp_n The output derivative of the Airy function. + */ + template <typename _Tp> + void + __airy(const _Tp __x, + _Tp & __Ai, _Tp & __Bi, _Tp & __Aip, _Tp & __Bip) + { + const _Tp __absx = std::abs(__x); + const _Tp __rootx = std::sqrt(__absx); + const _Tp __z = _Tp(2) * __absx * __rootx / _Tp(3); + + if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__x > _Tp(0)) + { + _Tp __I_nu, __Ip_nu, __K_nu, __Kp_nu; + + __bessel_ik(_Tp(1) / _Tp(3), __z, __I_nu, __K_nu, __Ip_nu, __Kp_nu); + __Ai = __rootx * __K_nu + / (__numeric_constants<_Tp>::__sqrt3() + * __numeric_constants<_Tp>::__pi()); + __Bi = __rootx * (__K_nu / __numeric_constants<_Tp>::__pi() + + _Tp(2) * __I_nu / __numeric_constants<_Tp>::__sqrt3()); + + __bessel_ik(_Tp(2) / _Tp(3), __z, __I_nu, __K_nu, __Ip_nu, __Kp_nu); + __Aip = -__x * __K_nu + / (__numeric_constants<_Tp>::__sqrt3() + * __numeric_constants<_Tp>::__pi()); + __Bip = __x * (__K_nu / __numeric_constants<_Tp>::__pi() + + _Tp(2) * __I_nu + / __numeric_constants<_Tp>::__sqrt3()); + } + else if (__x < _Tp(0)) + { + _Tp __J_nu, __Jp_nu, __N_nu, __Np_nu; + + __bessel_jn(_Tp(1) / _Tp(3), __z, __J_nu, __N_nu, __Jp_nu, __Np_nu); + __Ai = __rootx * (__J_nu + - __N_nu / __numeric_constants<_Tp>::__sqrt3()) / _Tp(2); + __Bi = -__rootx * (__N_nu + + __J_nu / __numeric_constants<_Tp>::__sqrt3()) / _Tp(2); + + __bessel_jn(_Tp(2) / _Tp(3), __z, __J_nu, __N_nu, __Jp_nu, __Np_nu); + __Aip = __absx * (__N_nu / __numeric_constants<_Tp>::__sqrt3() + + __J_nu) / _Tp(2); + __Bip = __absx * (__J_nu / __numeric_constants<_Tp>::__sqrt3() + - __N_nu) / _Tp(2); + } + else + { + // Reference: + // Abramowitz & Stegun, page 446 section 10.4.4 on Airy functions. + // The number is Ai(0) = 3^{-2/3}/\Gamma(2/3). + __Ai = _Tp(0.35502805388781723926L); + __Bi = __Ai * __numeric_constants<_Tp>::__sqrt3(); + + // Reference: + // Abramowitz & Stegun, page 446 section 10.4.5 on Airy functions. + // The number is Ai'(0) = -3^{-1/3}/\Gamma(1/3). + __Aip = -_Tp(0.25881940379280679840L); + __Bip = -__Aip * __numeric_constants<_Tp>::__sqrt3(); + } + + return; + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_MODIFIED_BESSEL_FUNC_TCC diff --git a/libstdc++-v3/include/tr1/poly_hermite.tcc b/libstdc++-v3/include/tr1/poly_hermite.tcc new file mode 100644 index 000000000..95e8079d5 --- /dev/null +++ b/libstdc++-v3/include/tr1/poly_hermite.tcc @@ -0,0 +1,125 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/poly_hermite.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// (1) Handbook of Mathematical Functions, +// Ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, Section 22 pp. 773-802 + +#ifndef _GLIBCXX_TR1_POLY_HERMITE_TCC +#define _GLIBCXX_TR1_POLY_HERMITE_TCC 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief This routine returns the Hermite polynomial + * of order n: \f$ H_n(x) \f$ by recursion on n. + * + * The Hermite polynomial is defined by: + * @f[ + * H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2} + * @f] + * + * @param __n The order of the Hermite polynomial. + * @param __x The argument of the Hermite polynomial. + * @return The value of the Hermite polynomial of order n + * and argument x. + */ + template<typename _Tp> + _Tp + __poly_hermite_recursion(const unsigned int __n, const _Tp __x) + { + // Compute H_0. + _Tp __H_0 = 1; + if (__n == 0) + return __H_0; + + // Compute H_1. + _Tp __H_1 = 2 * __x; + if (__n == 1) + return __H_1; + + // Compute H_n. + _Tp __H_n, __H_nm1, __H_nm2; + unsigned int __i; + for (__H_nm2 = __H_0, __H_nm1 = __H_1, __i = 2; __i <= __n; ++__i) + { + __H_n = 2 * (__x * __H_nm1 - (__i - 1) * __H_nm2); + __H_nm2 = __H_nm1; + __H_nm1 = __H_n; + } + + return __H_n; + } + + + /** + * @brief This routine returns the Hermite polynomial + * of order n: \f$ H_n(x) \f$. + * + * The Hermite polynomial is defined by: + * @f[ + * H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2} + * @f] + * + * @param __n The order of the Hermite polynomial. + * @param __x The argument of the Hermite polynomial. + * @return The value of the Hermite polynomial of order n + * and argument x. + */ + template<typename _Tp> + inline _Tp + __poly_hermite(const unsigned int __n, const _Tp __x) + { + if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else + return __poly_hermite_recursion(__n, __x); + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_POLY_HERMITE_TCC diff --git a/libstdc++-v3/include/tr1/poly_laguerre.tcc b/libstdc++-v3/include/tr1/poly_laguerre.tcc new file mode 100644 index 000000000..769923d34 --- /dev/null +++ b/libstdc++-v3/include/tr1/poly_laguerre.tcc @@ -0,0 +1,329 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/poly_laguerre.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// (1) Handbook of Mathematical Functions, +// Ed. Milton Abramowitz and Irene A. Stegun, +// Dover Publications, +// Section 13, pp. 509-510, Section 22 pp. 773-802 +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl + +#ifndef _GLIBCXX_TR1_POLY_LAGUERRE_TCC +#define _GLIBCXX_TR1_POLY_LAGUERRE_TCC 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief This routine returns the associated Laguerre polynomial + * of order @f$ n @f$, degree @f$ \alpha @f$ for large n. + * Abramowitz & Stegun, 13.5.21 + * + * @param __n The order of the Laguerre function. + * @param __alpha The degree of the Laguerre function. + * @param __x The argument of the Laguerre function. + * @return The value of the Laguerre function of order n, + * degree @f$ \alpha @f$, and argument x. + * + * This is from the GNU Scientific Library. + */ + template<typename _Tpa, typename _Tp> + _Tp + __poly_laguerre_large_n(const unsigned __n, const _Tpa __alpha1, + const _Tp __x) + { + const _Tp __a = -_Tp(__n); + const _Tp __b = _Tp(__alpha1) + _Tp(1); + const _Tp __eta = _Tp(2) * __b - _Tp(4) * __a; + const _Tp __cos2th = __x / __eta; + const _Tp __sin2th = _Tp(1) - __cos2th; + const _Tp __th = std::acos(std::sqrt(__cos2th)); + const _Tp __pre_h = __numeric_constants<_Tp>::__pi_2() + * __numeric_constants<_Tp>::__pi_2() + * __eta * __eta * __cos2th * __sin2th; + +#if _GLIBCXX_USE_C99_MATH_TR1 + const _Tp __lg_b = std::tr1::lgamma(_Tp(__n) + __b); + const _Tp __lnfact = std::tr1::lgamma(_Tp(__n + 1)); +#else + const _Tp __lg_b = __log_gamma(_Tp(__n) + __b); + const _Tp __lnfact = __log_gamma(_Tp(__n + 1)); +#endif + + _Tp __pre_term1 = _Tp(0.5L) * (_Tp(1) - __b) + * std::log(_Tp(0.25L) * __x * __eta); + _Tp __pre_term2 = _Tp(0.25L) * std::log(__pre_h); + _Tp __lnpre = __lg_b - __lnfact + _Tp(0.5L) * __x + + __pre_term1 - __pre_term2; + _Tp __ser_term1 = std::sin(__a * __numeric_constants<_Tp>::__pi()); + _Tp __ser_term2 = std::sin(_Tp(0.25L) * __eta + * (_Tp(2) * __th + - std::sin(_Tp(2) * __th)) + + __numeric_constants<_Tp>::__pi_4()); + _Tp __ser = __ser_term1 + __ser_term2; + + return std::exp(__lnpre) * __ser; + } + + + /** + * @brief Evaluate the polynomial based on the confluent hypergeometric + * function in a safe way, with no restriction on the arguments. + * + * The associated Laguerre function is defined by + * @f[ + * L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!} + * _1F_1(-n; \alpha + 1; x) + * @f] + * where @f$ (\alpha)_n @f$ is the Pochhammer symbol and + * @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function. + * + * This function assumes x != 0. + * + * This is from the GNU Scientific Library. + */ + template<typename _Tpa, typename _Tp> + _Tp + __poly_laguerre_hyperg(const unsigned int __n, const _Tpa __alpha1, + const _Tp __x) + { + const _Tp __b = _Tp(__alpha1) + _Tp(1); + const _Tp __mx = -__x; + const _Tp __tc_sgn = (__x < _Tp(0) ? _Tp(1) + : ((__n % 2 == 1) ? -_Tp(1) : _Tp(1))); + // Get |x|^n/n! + _Tp __tc = _Tp(1); + const _Tp __ax = std::abs(__x); + for (unsigned int __k = 1; __k <= __n; ++__k) + __tc *= (__ax / __k); + + _Tp __term = __tc * __tc_sgn; + _Tp __sum = __term; + for (int __k = int(__n) - 1; __k >= 0; --__k) + { + __term *= ((__b + _Tp(__k)) / _Tp(int(__n) - __k)) + * _Tp(__k + 1) / __mx; + __sum += __term; + } + + return __sum; + } + + + /** + * @brief This routine returns the associated Laguerre polynomial + * of order @f$ n @f$, degree @f$ \alpha @f$: @f$ L_n^\alpha(x) @f$ + * by recursion. + * + * The associated Laguerre function is defined by + * @f[ + * L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!} + * _1F_1(-n; \alpha + 1; x) + * @f] + * where @f$ (\alpha)_n @f$ is the Pochhammer symbol and + * @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function. + * + * The associated Laguerre polynomial is defined for integral + * @f$ \alpha = m @f$ by: + * @f[ + * L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x) + * @f] + * where the Laguerre polynomial is defined by: + * @f[ + * L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x}) + * @f] + * + * @param __n The order of the Laguerre function. + * @param __alpha The degree of the Laguerre function. + * @param __x The argument of the Laguerre function. + * @return The value of the Laguerre function of order n, + * degree @f$ \alpha @f$, and argument x. + */ + template<typename _Tpa, typename _Tp> + _Tp + __poly_laguerre_recursion(const unsigned int __n, + const _Tpa __alpha1, const _Tp __x) + { + // Compute l_0. + _Tp __l_0 = _Tp(1); + if (__n == 0) + return __l_0; + + // Compute l_1^alpha. + _Tp __l_1 = -__x + _Tp(1) + _Tp(__alpha1); + if (__n == 1) + return __l_1; + + // Compute l_n^alpha by recursion on n. + _Tp __l_n2 = __l_0; + _Tp __l_n1 = __l_1; + _Tp __l_n = _Tp(0); + for (unsigned int __nn = 2; __nn <= __n; ++__nn) + { + __l_n = (_Tp(2 * __nn - 1) + _Tp(__alpha1) - __x) + * __l_n1 / _Tp(__nn) + - (_Tp(__nn - 1) + _Tp(__alpha1)) * __l_n2 / _Tp(__nn); + __l_n2 = __l_n1; + __l_n1 = __l_n; + } + + return __l_n; + } + + + /** + * @brief This routine returns the associated Laguerre polynomial + * of order n, degree @f$ \alpha @f$: @f$ L_n^alpha(x) @f$. + * + * The associated Laguerre function is defined by + * @f[ + * L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!} + * _1F_1(-n; \alpha + 1; x) + * @f] + * where @f$ (\alpha)_n @f$ is the Pochhammer symbol and + * @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function. + * + * The associated Laguerre polynomial is defined for integral + * @f$ \alpha = m @f$ by: + * @f[ + * L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x) + * @f] + * where the Laguerre polynomial is defined by: + * @f[ + * L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x}) + * @f] + * + * @param __n The order of the Laguerre function. + * @param __alpha The degree of the Laguerre function. + * @param __x The argument of the Laguerre function. + * @return The value of the Laguerre function of order n, + * degree @f$ \alpha @f$, and argument x. + */ + template<typename _Tpa, typename _Tp> + inline _Tp + __poly_laguerre(const unsigned int __n, const _Tpa __alpha1, + const _Tp __x) + { + if (__x < _Tp(0)) + std::__throw_domain_error(__N("Negative argument " + "in __poly_laguerre.")); + // Return NaN on NaN input. + else if (__isnan(__x)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__n == 0) + return _Tp(1); + else if (__n == 1) + return _Tp(1) + _Tp(__alpha1) - __x; + else if (__x == _Tp(0)) + { + _Tp __prod = _Tp(__alpha1) + _Tp(1); + for (unsigned int __k = 2; __k <= __n; ++__k) + __prod *= (_Tp(__alpha1) + _Tp(__k)) / _Tp(__k); + return __prod; + } + else if (__n > 10000000 && _Tp(__alpha1) > -_Tp(1) + && __x < _Tp(2) * (_Tp(__alpha1) + _Tp(1)) + _Tp(4 * __n)) + return __poly_laguerre_large_n(__n, __alpha1, __x); + else if (_Tp(__alpha1) >= _Tp(0) + || (__x > _Tp(0) && _Tp(__alpha1) < -_Tp(__n + 1))) + return __poly_laguerre_recursion(__n, __alpha1, __x); + else + return __poly_laguerre_hyperg(__n, __alpha1, __x); + } + + + /** + * @brief This routine returns the associated Laguerre polynomial + * of order n, degree m: @f$ L_n^m(x) @f$. + * + * The associated Laguerre polynomial is defined for integral + * @f$ \alpha = m @f$ by: + * @f[ + * L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x) + * @f] + * where the Laguerre polynomial is defined by: + * @f[ + * L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x}) + * @f] + * + * @param __n The order of the Laguerre polynomial. + * @param __m The degree of the Laguerre polynomial. + * @param __x The argument of the Laguerre polynomial. + * @return The value of the associated Laguerre polynomial of order n, + * degree m, and argument x. + */ + template<typename _Tp> + inline _Tp + __assoc_laguerre(const unsigned int __n, const unsigned int __m, + const _Tp __x) + { + return __poly_laguerre<unsigned int, _Tp>(__n, __m, __x); + } + + + /** + * @brief This routine returns the Laguerre polynomial + * of order n: @f$ L_n(x) @f$. + * + * The Laguerre polynomial is defined by: + * @f[ + * L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x}) + * @f] + * + * @param __n The order of the Laguerre polynomial. + * @param __x The argument of the Laguerre polynomial. + * @return The value of the Laguerre polynomial of order n + * and argument x. + */ + template<typename _Tp> + inline _Tp + __laguerre(const unsigned int __n, const _Tp __x) + { + return __poly_laguerre<unsigned int, _Tp>(__n, 0, __x); + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_POLY_LAGUERRE_TCC diff --git a/libstdc++-v3/include/tr1/random b/libstdc++-v3/include/tr1/random new file mode 100644 index 000000000..55926479a --- /dev/null +++ b/libstdc++-v3/include/tr1/random @@ -0,0 +1,50 @@ +// random number generation -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** + * @file tr1/random + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_RANDOM +#define _GLIBCXX_TR1_RANDOM 1 + +#pragma GCC system_header + +#include <cmath> +#include <cstdio> +#include <cstdlib> +#include <string> +#include <iosfwd> +#include <limits> +#include <ext/type_traits.h> +#include <ext/numeric_traits.h> +#include <bits/concept_check.h> +#include <debug/debug.h> +#include <tr1/type_traits> +#include <tr1/cmath> +#include <tr1/random.h> +#include <tr1/random.tcc> + +#endif // _GLIBCXX_TR1_RANDOM diff --git a/libstdc++-v3/include/tr1/random.h b/libstdc++-v3/include/tr1/random.h new file mode 100644 index 000000000..ace37929a --- /dev/null +++ b/libstdc++-v3/include/tr1/random.h @@ -0,0 +1,2417 @@ +// random number generation -*- C++ -*- + +// Copyright (C) 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** + * @file tr1/random.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/random} + */ + +#ifndef _GLIBCXX_TR1_RANDOM_H +#define _GLIBCXX_TR1_RANDOM_H 1 + +#pragma GCC system_header + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.1] Random number generation + + /** + * @addtogroup tr1_random Random Number Generation + * A facility for generating random numbers on selected distributions. + * @{ + */ + + /* + * Implementation-space details. + */ + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<typename _UIntType, int __w, + bool = __w < std::numeric_limits<_UIntType>::digits> + struct _Shift + { static const _UIntType __value = 0; }; + + template<typename _UIntType, int __w> + struct _Shift<_UIntType, __w, true> + { static const _UIntType __value = _UIntType(1) << __w; }; + + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool> + struct _Mod; + + // Dispatch based on modulus value to prevent divide-by-zero compile-time + // errors when m == 0. + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m> + inline _Tp + __mod(_Tp __x) + { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); } + + typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4), + unsigned, unsigned long>::__type _UInt32Type; + + /* + * An adaptor class for converting the output of any Generator into + * the input for a specific Distribution. + */ + template<typename _Engine, typename _Distribution> + struct _Adaptor + { + typedef typename remove_reference<_Engine>::type _BEngine; + typedef typename _BEngine::result_type _Engine_result_type; + typedef typename _Distribution::input_type result_type; + + public: + _Adaptor(const _Engine& __g) + : _M_g(__g) { } + + result_type + min() const + { + result_type __return_value; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g.min(); + else + __return_value = result_type(0); + return __return_value; + } + + result_type + max() const + { + result_type __return_value; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g.max(); + else if (!is_integral<result_type>::value) + __return_value = result_type(1); + else + __return_value = std::numeric_limits<result_type>::max() - 1; + return __return_value; + } + + /* + * Converts a value generated by the adapted random number generator + * into a value in the input domain for the dependent random number + * distribution. + * + * Because the type traits are compile time constants only the + * appropriate clause of the if statements will actually be emitted + * by the compiler. + */ + result_type + operator()() + { + result_type __return_value; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g(); + else if (!is_integral<_Engine_result_type>::value + && !is_integral<result_type>::value) + __return_value = result_type(_M_g() - _M_g.min()) + / result_type(_M_g.max() - _M_g.min()); + else if (is_integral<_Engine_result_type>::value + && !is_integral<result_type>::value) + __return_value = result_type(_M_g() - _M_g.min()) + / result_type(_M_g.max() - _M_g.min() + result_type(1)); + else + __return_value = (((_M_g() - _M_g.min()) + / (_M_g.max() - _M_g.min())) + * std::numeric_limits<result_type>::max()); + return __return_value; + } + + private: + _Engine _M_g; + }; + + // Specialization for _Engine*. + template<typename _Engine, typename _Distribution> + struct _Adaptor<_Engine*, _Distribution> + { + typedef typename _Engine::result_type _Engine_result_type; + typedef typename _Distribution::input_type result_type; + + public: + _Adaptor(_Engine* __g) + : _M_g(__g) { } + + result_type + min() const + { + result_type __return_value; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g->min(); + else + __return_value = result_type(0); + return __return_value; + } + + result_type + max() const + { + result_type __return_value; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = _M_g->max(); + else if (!is_integral<result_type>::value) + __return_value = result_type(1); + else + __return_value = std::numeric_limits<result_type>::max() - 1; + return __return_value; + } + + result_type + operator()() + { + result_type __return_value; + if (is_integral<_Engine_result_type>::value + && is_integral<result_type>::value) + __return_value = (*_M_g)(); + else if (!is_integral<_Engine_result_type>::value + && !is_integral<result_type>::value) + __return_value = result_type((*_M_g)() - _M_g->min()) + / result_type(_M_g->max() - _M_g->min()); + else if (is_integral<_Engine_result_type>::value + && !is_integral<result_type>::value) + __return_value = result_type((*_M_g)() - _M_g->min()) + / result_type(_M_g->max() - _M_g->min() + result_type(1)); + else + __return_value = ((((*_M_g)() - _M_g->min()) + / (_M_g->max() - _M_g->min())) + * std::numeric_limits<result_type>::max()); + return __return_value; + } + + private: + _Engine* _M_g; + }; + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace __detail + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * Produces random numbers on a given distribution function using a + * non-uniform random number generation engine. + * + * @todo the engine_value_type needs to be studied more carefully. + */ + template<typename _Engine, typename _Dist> + class variate_generator + { + // Concept requirements. + __glibcxx_class_requires(_Engine, _CopyConstructibleConcept) + // __glibcxx_class_requires(_Engine, _EngineConcept) + // __glibcxx_class_requires(_Dist, _EngineConcept) + + public: + typedef _Engine engine_type; + typedef __detail::_Adaptor<_Engine, _Dist> engine_value_type; + typedef _Dist distribution_type; + typedef typename _Dist::result_type result_type; + + // tr1:5.1.1 table 5.1 requirement + typedef typename __gnu_cxx::__enable_if< + is_arithmetic<result_type>::value, result_type>::__type _IsValidType; + + /** + * Constructs a variate generator with the uniform random number + * generator @p __eng for the random distribution @p __dist. + * + * @throws Any exceptions which may thrown by the copy constructors of + * the @p _Engine or @p _Dist objects. + */ + variate_generator(engine_type __eng, distribution_type __dist) + : _M_engine(__eng), _M_dist(__dist) { } + + /** + * Gets the next generated value on the distribution. + */ + result_type + operator()() + { return _M_dist(_M_engine); } + + /** + * WTF? + */ + template<typename _Tp> + result_type + operator()(_Tp __value) + { return _M_dist(_M_engine, __value); } + + /** + * Gets a reference to the underlying uniform random number generator + * object. + */ + engine_value_type& + engine() + { return _M_engine; } + + /** + * Gets a const reference to the underlying uniform random number + * generator object. + */ + const engine_value_type& + engine() const + { return _M_engine; } + + /** + * Gets a reference to the underlying random distribution. + */ + distribution_type& + distribution() + { return _M_dist; } + + /** + * Gets a const reference to the underlying random distribution. + */ + const distribution_type& + distribution() const + { return _M_dist; } + + /** + * Gets the closed lower bound of the distribution interval. + */ + result_type + min() const + { return this->distribution().min(); } + + /** + * Gets the closed upper bound of the distribution interval. + */ + result_type + max() const + { return this->distribution().max(); } + + private: + engine_value_type _M_engine; + distribution_type _M_dist; + }; + + + /** + * @addtogroup tr1_random_generators Random Number Generators + * @ingroup tr1_random + * + * These classes define objects which provide random or pseudorandom + * numbers, either from a discrete or a continuous interval. The + * random number generator supplied as a part of this library are + * all uniform random number generators which provide a sequence of + * random number uniformly distributed over their range. + * + * A number generator is a function object with an operator() that + * takes zero arguments and returns a number. + * + * A compliant random number generator must satisfy the following + * requirements. <table border=1 cellpadding=10 cellspacing=0> + * <caption align=top>Random Number Generator Requirements</caption> + * <tr><td>To be documented.</td></tr> </table> + * + * @{ + */ + + /** + * @brief A model of a linear congruential random number generator. + * + * A random number generator that produces pseudorandom numbers using the + * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$. + * + * The template parameter @p _UIntType must be an unsigned integral type + * large enough to store values up to (__m-1). If the template parameter + * @p __m is 0, the modulus @p __m used is + * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template + * parameters @p __a and @p __c must be less than @p __m. + * + * The size of the state is @f$ 1 @f$. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + class linear_congruential + { + __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept) + // __glibcpp_class_requires(__a < __m && __c < __m) + + public: + /** The type of the generated random value. */ + typedef _UIntType result_type; + + /** The multiplier. */ + static const _UIntType multiplier = __a; + /** An increment. */ + static const _UIntType increment = __c; + /** The modulus. */ + static const _UIntType modulus = __m; + + /** + * Constructs a %linear_congruential random number generator engine with + * seed @p __s. The default seed value is 1. + * + * @param __s The initial seed value. + */ + explicit + linear_congruential(unsigned long __x0 = 1) + { this->seed(__x0); } + + /** + * Constructs a %linear_congruential random number generator engine + * seeded from the generator function @p __g. + * + * @param __g The seed generator function. + */ + template<class _Gen> + linear_congruential(_Gen& __g) + { this->seed(__g); } + + /** + * Reseeds the %linear_congruential random number generator engine + * sequence to the seed @g __s. + * + * @param __s The new seed. + */ + void + seed(unsigned long __s = 1); + + /** + * Reseeds the %linear_congruential random number generator engine + * sequence using values from the generator function @p __g. + * + * @param __g the seed generator function. + */ + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + /** + * Gets the smallest possible value in the output range. + * + * The minimum depends on the @p __c parameter: if it is zero, the + * minimum generated must be > 0, otherwise 0 is allowed. + */ + result_type + min() const + { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; } + + /** + * Gets the largest possible value in the output range. + */ + result_type + max() const + { return __m - 1; } + + /** + * Gets the next random number in the sequence. + */ + result_type + operator()(); + + /** + * Compares two linear congruential random number generator + * objects of the same type for equality. + * + * @param __lhs A linear congruential random number generator object. + * @param __rhs Another linear congruential random number generator obj. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const linear_congruential& __lhs, + const linear_congruential& __rhs) + { return __lhs._M_x == __rhs._M_x; } + + /** + * Compares two linear congruential random number generator + * objects of the same type for inequality. + * + * @param __lhs A linear congruential random number generator object. + * @param __rhs Another linear congruential random number generator obj. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const linear_congruential& __lhs, + const linear_congruential& __rhs) + { return !(__lhs == __rhs); } + + /** + * Writes the textual representation of the state x(i) of x to @p __os. + * + * @param __os The output stream. + * @param __lcr A % linear_congruential random number generator. + * @returns __os. + */ + template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1, + _UIntType1 __m1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const linear_congruential<_UIntType1, __a1, __c1, + __m1>& __lcr); + + /** + * Sets the state of the engine by reading its textual + * representation from @p __is. + * + * The textual representation must have been previously written using an + * output stream whose imbued locale and whose type's template + * specialization arguments _CharT and _Traits were the same as those of + * @p __is. + * + * @param __is The input stream. + * @param __lcr A % linear_congruential random number generator. + * @returns __is. + */ + template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1, + _UIntType1 __m1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + _UIntType _M_x; + }; + + /** + * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller. + */ + typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0; + + /** + * An alternative LCR (Lehmer Generator function) . + */ + typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand; + + + /** + * A generalized feedback shift register discrete random number generator. + * + * This algorithm avoids multiplication and division and is designed to be + * friendly to a pipelined architecture. If the parameters are chosen + * correctly, this generator will produce numbers with a very long period and + * fairly good apparent entropy, although still not cryptographically strong. + * + * The best way to use this generator is with the predefined mt19937 class. + * + * This algorithm was originally invented by Makoto Matsumoto and + * Takuji Nishimura. + * + * @var word_size The number of bits in each element of the state vector. + * @var state_size The degree of recursion. + * @var shift_size The period parameter. + * @var mask_bits The separation point bit index. + * @var parameter_a The last row of the twist matrix. + * @var output_u The first right-shift tempering matrix parameter. + * @var output_s The first left-shift tempering matrix parameter. + * @var output_b The first left-shift tempering matrix mask. + * @var output_t The second left-shift tempering matrix parameter. + * @var output_c The second left-shift tempering matrix mask. + * @var output_l The second right-shift tempering matrix parameter. + */ + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, _UIntType __b, int __t, + _UIntType __c, int __l> + class mersenne_twister + { + __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept) + + public: + // types + typedef _UIntType result_type; + + // parameter values + static const int word_size = __w; + static const int state_size = __n; + static const int shift_size = __m; + static const int mask_bits = __r; + static const _UIntType parameter_a = __a; + static const int output_u = __u; + static const int output_s = __s; + static const _UIntType output_b = __b; + static const int output_t = __t; + static const _UIntType output_c = __c; + static const int output_l = __l; + + // constructors and member function + mersenne_twister() + { seed(); } + + explicit + mersenne_twister(unsigned long __value) + { seed(__value); } + + template<class _Gen> + mersenne_twister(_Gen& __g) + { seed(__g); } + + void + seed() + { seed(5489UL); } + + void + seed(unsigned long __value); + + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + result_type + min() const + { return 0; }; + + result_type + max() const + { return __detail::_Shift<_UIntType, __w>::__value - 1; } + + result_type + operator()(); + + /** + * Compares two % mersenne_twister random number generator objects of + * the same type for equality. + * + * @param __lhs A % mersenne_twister random number generator object. + * @param __rhs Another % mersenne_twister random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const mersenne_twister& __lhs, + const mersenne_twister& __rhs) + { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); } + + /** + * Compares two % mersenne_twister random number generator objects of + * the same type for inequality. + * + * @param __lhs A % mersenne_twister random number generator object. + * @param __rhs Another % mersenne_twister random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const mersenne_twister& __lhs, + const mersenne_twister& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a % mersenne_twister random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A % mersenne_twister random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<class _UIntType1, int __w1, int __n1, int __m1, int __r1, + _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1, + _UIntType1 __c1, int __l1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1, + __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x); + + /** + * Extracts the current state of a % mersenne_twister random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A % mersenne_twister random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<class _UIntType1, int __w1, int __n1, int __m1, int __r1, + _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1, + _UIntType1 __c1, int __l1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1, + __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + _UIntType _M_x[state_size]; + int _M_p; + }; + + /** + * The classic Mersenne Twister. + * + * Reference: + * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally + * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions + * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. + */ + typedef mersenne_twister< + unsigned long, 32, 624, 397, 31, + 0x9908b0dful, 11, 7, + 0x9d2c5680ul, 15, + 0xefc60000ul, 18 + > mt19937; + + + /** + * @brief The Marsaglia-Zaman generator. + * + * This is a model of a Generalized Fibonacci discrete random number + * generator, sometimes referred to as the SWC generator. + * + * A discrete random number generator that produces pseudorandom + * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} - + * carry_{i-1}) \bmod m @f$. + * + * The size of the state is @f$ r @f$ + * and the maximum period of the generator is @f$ m^r - m^s -1 @f$. + * + * N1688[4.13] says <em>the template parameter _IntType shall denote + * an integral type large enough to store values up to m</em>. + * + * @var _M_x The state of the generator. This is a ring buffer. + * @var _M_carry The carry. + * @var _M_p Current index of x(i - r). + */ + template<typename _IntType, _IntType __m, int __s, int __r> + class subtract_with_carry + { + __glibcxx_class_requires(_IntType, _IntegerConcept) + + public: + /** The type of the generated random value. */ + typedef _IntType result_type; + + // parameter values + static const _IntType modulus = __m; + static const int long_lag = __r; + static const int short_lag = __s; + + /** + * Constructs a default-initialized % subtract_with_carry random number + * generator. + */ + subtract_with_carry() + { this->seed(); } + + /** + * Constructs an explicitly seeded % subtract_with_carry random number + * generator. + */ + explicit + subtract_with_carry(unsigned long __value) + { this->seed(__value); } + + /** + * Constructs a %subtract_with_carry random number generator engine + * seeded from the generator function @p __g. + * + * @param __g The seed generator function. + */ + template<class _Gen> + subtract_with_carry(_Gen& __g) + { this->seed(__g); } + + /** + * Seeds the initial state @f$ x_0 @f$ of the random number generator. + * + * N1688[4.19] modifies this as follows. If @p __value == 0, + * sets value to 19780503. In any case, with a linear + * congruential generator lcg(i) having parameters @f$ m_{lcg} = + * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value + * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m + * \dots lcg(r) \bmod m @f$ respectively. If @f$ x_{-1} = 0 @f$ + * set carry to 1, otherwise sets carry to 0. + */ + void + seed(unsigned long __value = 19780503); + + /** + * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry + * random number generator. + */ + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + /** + * Gets the inclusive minimum value of the range of random integers + * returned by this generator. + */ + result_type + min() const + { return 0; } + + /** + * Gets the inclusive maximum value of the range of random integers + * returned by this generator. + */ + result_type + max() const + { return this->modulus - 1; } + + /** + * Gets the next random number in the sequence. + */ + result_type + operator()(); + + /** + * Compares two % subtract_with_carry random number generator objects of + * the same type for equality. + * + * @param __lhs A % subtract_with_carry random number generator object. + * @param __rhs Another % subtract_with_carry random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const subtract_with_carry& __lhs, + const subtract_with_carry& __rhs) + { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); } + + /** + * Compares two % subtract_with_carry random number generator objects of + * the same type for inequality. + * + * @param __lhs A % subtract_with_carry random number generator object. + * @param __rhs Another % subtract_with_carry random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const subtract_with_carry& __lhs, + const subtract_with_carry& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a % subtract_with_carry random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A % subtract_with_carry random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, _IntType1 __m1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry<_IntType1, __m1, __s1, + __r1>& __x); + + /** + * Extracts the current state of a % subtract_with_carry random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A % subtract_with_carry random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<typename _IntType1, _IntType1 __m1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType; + + _UIntType _M_x[long_lag]; + _UIntType _M_carry; + int _M_p; + }; + + + /** + * @brief The Marsaglia-Zaman generator (floats version). + * + * @var _M_x The state of the generator. This is a ring buffer. + * @var _M_carry The carry. + * @var _M_p Current index of x(i - r). + * @var _M_npows Precomputed negative powers of 2. + */ + template<typename _RealType, int __w, int __s, int __r> + class subtract_with_carry_01 + { + public: + /** The type of the generated random value. */ + typedef _RealType result_type; + + // parameter values + static const int word_size = __w; + static const int long_lag = __r; + static const int short_lag = __s; + + /** + * Constructs a default-initialized % subtract_with_carry_01 random + * number generator. + */ + subtract_with_carry_01() + { + this->seed(); + _M_initialize_npows(); + } + + /** + * Constructs an explicitly seeded % subtract_with_carry_01 random number + * generator. + */ + explicit + subtract_with_carry_01(unsigned long __value) + { + this->seed(__value); + _M_initialize_npows(); + } + + /** + * Constructs a % subtract_with_carry_01 random number generator engine + * seeded from the generator function @p __g. + * + * @param __g The seed generator function. + */ + template<class _Gen> + subtract_with_carry_01(_Gen& __g) + { + this->seed(__g); + _M_initialize_npows(); + } + + /** + * Seeds the initial state @f$ x_0 @f$ of the random number generator. + */ + void + seed(unsigned long __value = 19780503); + + /** + * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01 + * random number generator. + */ + template<class _Gen> + void + seed(_Gen& __g) + { seed(__g, typename is_fundamental<_Gen>::type()); } + + /** + * Gets the minimum value of the range of random floats + * returned by this generator. + */ + result_type + min() const + { return 0.0; } + + /** + * Gets the maximum value of the range of random floats + * returned by this generator. + */ + result_type + max() const + { return 1.0; } + + /** + * Gets the next random number in the sequence. + */ + result_type + operator()(); + + /** + * Compares two % subtract_with_carry_01 random number generator objects + * of the same type for equality. + * + * @param __lhs A % subtract_with_carry_01 random number + * generator object. + * @param __rhs Another % subtract_with_carry_01 random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const subtract_with_carry_01& __lhs, + const subtract_with_carry_01& __rhs) + { + for (int __i = 0; __i < long_lag; ++__i) + if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n, + __rhs._M_x[__i])) + return false; + return true; + } + + /** + * Compares two % subtract_with_carry_01 random number generator objects + * of the same type for inequality. + * + * @param __lhs A % subtract_with_carry_01 random number + * generator object. + * + * @param __rhs Another % subtract_with_carry_01 random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const subtract_with_carry_01& __lhs, + const subtract_with_carry_01& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a % subtract_with_carry_01 random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A % subtract_with_carry_01 random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, int __w1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry_01<_RealType1, __w1, __s1, + __r1>& __x); + + /** + * Extracts the current state of a % subtract_with_carry_01 random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A % subtract_with_carry_01 random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<typename _RealType1, int __w1, int __s1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x); + + private: + template<class _Gen> + void + seed(_Gen& __g, true_type) + { return seed(static_cast<unsigned long>(__g)); } + + template<class _Gen> + void + seed(_Gen& __g, false_type); + + void + _M_initialize_npows(); + + static const int __n = (__w + 31) / 32; + + typedef __detail::_UInt32Type _UInt32Type; + _UInt32Type _M_x[long_lag][__n]; + _RealType _M_npows[__n]; + _UInt32Type _M_carry; + int _M_p; + }; + + typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 508. Bad parameters for ranlux64_base_01. + typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01; + + + /** + * Produces random numbers from some base engine by discarding blocks of + * data. + * + * 0 <= @p __r <= @p __p + */ + template<class _UniformRandomNumberGenerator, int __p, int __r> + class discard_block + { + // __glibcxx_class_requires(typename base_type::result_type, + // ArithmeticTypeConcept) + + public: + /** The type of the underlying generator engine. */ + typedef _UniformRandomNumberGenerator base_type; + /** The type of the generated random value. */ + typedef typename base_type::result_type result_type; + + // parameter values + static const int block_size = __p; + static const int used_block = __r; + + /** + * Constructs a default %discard_block engine. + * + * The underlying engine is default constructed as well. + */ + discard_block() + : _M_n(0) { } + + /** + * Copy constructs a %discard_block engine. + * + * Copies an existing base class random number generator. + * @param rng An existing (base class) engine object. + */ + explicit + discard_block(const base_type& __rng) + : _M_b(__rng), _M_n(0) { } + + /** + * Seed constructs a %discard_block engine. + * + * Constructs the underlying generator engine seeded with @p __s. + * @param __s A seed value for the base class engine. + */ + explicit + discard_block(unsigned long __s) + : _M_b(__s), _M_n(0) { } + + /** + * Generator construct a %discard_block engine. + * + * @param __g A seed generator function. + */ + template<class _Gen> + discard_block(_Gen& __g) + : _M_b(__g), _M_n(0) { } + + /** + * Reseeds the %discard_block object with the default seed for the + * underlying base class generator engine. + */ + void seed() + { + _M_b.seed(); + _M_n = 0; + } + + /** + * Reseeds the %discard_block object with the given seed generator + * function. + * @param __g A seed generator function. + */ + template<class _Gen> + void seed(_Gen& __g) + { + _M_b.seed(__g); + _M_n = 0; + } + + /** + * Gets a const reference to the underlying generator engine object. + */ + const base_type& + base() const + { return _M_b; } + + /** + * Gets the minimum value in the generated random number range. + */ + result_type + min() const + { return _M_b.min(); } + + /** + * Gets the maximum value in the generated random number range. + */ + result_type + max() const + { return _M_b.max(); } + + /** + * Gets the next value in the generated random number sequence. + */ + result_type + operator()(); + + /** + * Compares two %discard_block random number generator objects of + * the same type for equality. + * + * @param __lhs A %discard_block random number generator object. + * @param __rhs Another %discard_block random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const discard_block& __lhs, const discard_block& __rhs) + { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); } + + /** + * Compares two %discard_block random number generator objects of + * the same type for inequality. + * + * @param __lhs A %discard_block random number generator object. + * @param __rhs Another %discard_block random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const discard_block& __lhs, const discard_block& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a %discard_block random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %discard_block random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator1, int __p1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const discard_block<_UniformRandomNumberGenerator1, + __p1, __r1>& __x); + + /** + * Extracts the current state of a % subtract_with_carry random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %discard_block random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator1, int __p1, int __r1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + discard_block<_UniformRandomNumberGenerator1, + __p1, __r1>& __x); + + private: + base_type _M_b; + int _M_n; + }; + + + /** + * James's luxury-level-3 integer adaptation of Luescher's generator. + */ + typedef discard_block< + subtract_with_carry<unsigned long, (1UL << 24), 10, 24>, + 223, + 24 + > ranlux3; + + /** + * James's luxury-level-4 integer adaptation of Luescher's generator. + */ + typedef discard_block< + subtract_with_carry<unsigned long, (1UL << 24), 10, 24>, + 389, + 24 + > ranlux4; + + typedef discard_block< + subtract_with_carry_01<float, 24, 10, 24>, + 223, + 24 + > ranlux3_01; + + typedef discard_block< + subtract_with_carry_01<float, 24, 10, 24>, + 389, + 24 + > ranlux4_01; + + + /** + * A random number generator adaptor class that combines two random number + * generator engines into a single output sequence. + */ + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + class xor_combine + { + // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1:: + // result_type, ArithmeticTypeConcept) + // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2:: + // result_type, ArithmeticTypeConcept) + + public: + /** The type of the first underlying generator engine. */ + typedef _UniformRandomNumberGenerator1 base1_type; + /** The type of the second underlying generator engine. */ + typedef _UniformRandomNumberGenerator2 base2_type; + + private: + typedef typename base1_type::result_type _Result_type1; + typedef typename base2_type::result_type _Result_type2; + + public: + /** The type of the generated random value. */ + typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1) + > sizeof(_Result_type2)), + _Result_type1, _Result_type2>::__type result_type; + + // parameter values + static const int shift1 = __s1; + static const int shift2 = __s2; + + // constructors and member function + xor_combine() + : _M_b1(), _M_b2() + { _M_initialize_max(); } + + xor_combine(const base1_type& __rng1, const base2_type& __rng2) + : _M_b1(__rng1), _M_b2(__rng2) + { _M_initialize_max(); } + + xor_combine(unsigned long __s) + : _M_b1(__s), _M_b2(__s + 1) + { _M_initialize_max(); } + + template<class _Gen> + xor_combine(_Gen& __g) + : _M_b1(__g), _M_b2(__g) + { _M_initialize_max(); } + + void + seed() + { + _M_b1.seed(); + _M_b2.seed(); + } + + template<class _Gen> + void + seed(_Gen& __g) + { + _M_b1.seed(__g); + _M_b2.seed(__g); + } + + const base1_type& + base1() const + { return _M_b1; } + + const base2_type& + base2() const + { return _M_b2; } + + result_type + min() const + { return 0; } + + result_type + max() const + { return _M_max; } + + /** + * Gets the next random number in the sequence. + */ + // NB: Not exactly the TR1 formula, per N2079 instead. + result_type + operator()() + { + return ((result_type(_M_b1() - _M_b1.min()) << shift1) + ^ (result_type(_M_b2() - _M_b2.min()) << shift2)); + } + + /** + * Compares two %xor_combine random number generator objects of + * the same type for equality. + * + * @param __lhs A %xor_combine random number generator object. + * @param __rhs Another %xor_combine random number generator + * object. + * + * @returns true if the two objects are equal, false otherwise. + */ + friend bool + operator==(const xor_combine& __lhs, const xor_combine& __rhs) + { + return (__lhs.base1() == __rhs.base1()) + && (__lhs.base2() == __rhs.base2()); + } + + /** + * Compares two %xor_combine random number generator objects of + * the same type for inequality. + * + * @param __lhs A %xor_combine random number generator object. + * @param __rhs Another %xor_combine random number generator + * object. + * + * @returns true if the two objects are not equal, false otherwise. + */ + friend bool + operator!=(const xor_combine& __lhs, const xor_combine& __rhs) + { return !(__lhs == __rhs); } + + /** + * Inserts the current state of a %xor_combine random number + * generator engine @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %xor_combine random number generator engine. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator11, int __s11, + class _UniformRandomNumberGenerator21, int __s21, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const xor_combine<_UniformRandomNumberGenerator11, __s11, + _UniformRandomNumberGenerator21, __s21>& __x); + + /** + * Extracts the current state of a %xor_combine random number + * generator engine @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %xor_combine random number generator engine. + * + * @returns The input stream with the state of @p __x extracted or in + * an error state. + */ + template<class _UniformRandomNumberGenerator11, int __s11, + class _UniformRandomNumberGenerator21, int __s21, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + xor_combine<_UniformRandomNumberGenerator11, __s11, + _UniformRandomNumberGenerator21, __s21>& __x); + + private: + void + _M_initialize_max(); + + result_type + _M_initialize_max_aux(result_type, result_type, int); + + base1_type _M_b1; + base2_type _M_b2; + result_type _M_max; + }; + + + /** + * A standard interface to a platform-specific non-deterministic + * random number generator (if any are available). + */ + class random_device + { + public: + // types + typedef unsigned int result_type; + + // constructors, destructors and member functions + +#ifdef _GLIBCXX_USE_RANDOM_TR1 + + explicit + random_device(const std::string& __token = "/dev/urandom") + { + if ((__token != "/dev/urandom" && __token != "/dev/random") + || !(_M_file = std::fopen(__token.c_str(), "rb"))) + std::__throw_runtime_error(__N("random_device::" + "random_device(const std::string&)")); + } + + ~random_device() + { std::fclose(_M_file); } + +#else + + explicit + random_device(const std::string& __token = "mt19937") + : _M_mt(_M_strtoul(__token)) { } + + private: + static unsigned long + _M_strtoul(const std::string& __str) + { + unsigned long __ret = 5489UL; + if (__str != "mt19937") + { + const char* __nptr = __str.c_str(); + char* __endptr; + __ret = std::strtoul(__nptr, &__endptr, 0); + if (*__nptr == '\0' || *__endptr != '\0') + std::__throw_runtime_error(__N("random_device::_M_strtoul" + "(const std::string&)")); + } + return __ret; + } + + public: + +#endif + + result_type + min() const + { return std::numeric_limits<result_type>::min(); } + + result_type + max() const + { return std::numeric_limits<result_type>::max(); } + + double + entropy() const + { return 0.0; } + + result_type + operator()() + { +#ifdef _GLIBCXX_USE_RANDOM_TR1 + result_type __ret; + std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type), + 1, _M_file); + return __ret; +#else + return _M_mt(); +#endif + } + + private: + random_device(const random_device&); + void operator=(const random_device&); + +#ifdef _GLIBCXX_USE_RANDOM_TR1 + FILE* _M_file; +#else + mt19937 _M_mt; +#endif + }; + + /* @} */ // group tr1_random_generators + + /** + * @addtogroup tr1_random_distributions Random Number Distributions + * @ingroup tr1_random + * @{ + */ + + /** + * @addtogroup tr1_random_distributions_discrete Discrete Distributions + * @ingroup tr1_random_distributions + * @{ + */ + + /** + * @brief Uniform discrete distribution for random numbers. + * A discrete random distribution on the range @f$[min, max]@f$ with equal + * probability throughout the range. + */ + template<typename _IntType = int> + class uniform_int + { + __glibcxx_class_requires(_IntType, _IntegerConcept) + + public: + /** The type of the parameters of the distribution. */ + typedef _IntType input_type; + /** The type of the range of the distribution. */ + typedef _IntType result_type; + + public: + /** + * Constructs a uniform distribution object. + */ + explicit + uniform_int(_IntType __min = 0, _IntType __max = 9) + : _M_min(__min), _M_max(__max) + { + _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max); + } + + /** + * Gets the inclusive lower bound of the distribution range. + */ + result_type + min() const + { return _M_min; } + + /** + * Gets the inclusive upper bound of the distribution range. + */ + result_type + max() const + { return _M_max; } + + /** + * Resets the distribution state. + * + * Does nothing for the uniform integer distribution. + */ + void + reset() { } + + /** + * Gets a uniformly distributed random number in the range + * @f$(min, max)@f$. + */ + template<typename _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { + typedef typename _UniformRandomNumberGenerator::result_type + _UResult_type; + return _M_call(__urng, _M_min, _M_max, + typename is_integral<_UResult_type>::type()); + } + + /** + * Gets a uniform random number in the range @f$[0, n)@f$. + * + * This function is aimed at use with std::random_shuffle. + */ + template<typename _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng, result_type __n) + { + typedef typename _UniformRandomNumberGenerator::result_type + _UResult_type; + return _M_call(__urng, 0, __n - 1, + typename is_integral<_UResult_type>::type()); + } + + /** + * Inserts a %uniform_int random number distribution @p __x into the + * output stream @p os. + * + * @param __os An output stream. + * @param __x A %uniform_int random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_int<_IntType1>& __x); + + /** + * Extracts a %uniform_int random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %uniform_int random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _IntType1, typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_int<_IntType1>& __x); + + private: + template<typename _UniformRandomNumberGenerator> + result_type + _M_call(_UniformRandomNumberGenerator& __urng, + result_type __min, result_type __max, true_type); + + template<typename _UniformRandomNumberGenerator> + result_type + _M_call(_UniformRandomNumberGenerator& __urng, + result_type __min, result_type __max, false_type) + { + return result_type((__urng() - __urng.min()) + / (__urng.max() - __urng.min()) + * (__max - __min + 1)) + __min; + } + + _IntType _M_min; + _IntType _M_max; + }; + + + /** + * @brief A Bernoulli random number distribution. + * + * Generates a sequence of true and false values with likelihood @f$ p @f$ + * that true will come up and @f$ (1 - p) @f$ that false will appear. + */ + class bernoulli_distribution + { + public: + typedef int input_type; + typedef bool result_type; + + public: + /** + * Constructs a Bernoulli distribution with likelihood @p p. + * + * @param __p [IN] The likelihood of a true result being returned. Must + * be in the interval @f$ [0, 1] @f$. + */ + explicit + bernoulli_distribution(double __p = 0.5) + : _M_p(__p) + { + _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0)); + } + + /** + * Gets the @p p parameter of the distribution. + */ + double + p() const + { return _M_p; } + + /** + * Resets the distribution state. + * + * Does nothing for a Bernoulli distribution. + */ + void + reset() { } + + /** + * Gets the next value in the Bernoullian sequence. + */ + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { + if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min())) + return true; + return false; + } + + /** + * Inserts a %bernoulli_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %bernoulli_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bernoulli_distribution& __x); + + /** + * Extracts a %bernoulli_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %bernoulli_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + bernoulli_distribution& __x) + { return __is >> __x._M_p; } + + private: + double _M_p; + }; + + + /** + * @brief A discrete geometric random number distribution. + * + * The formula for the geometric probability mass function is + * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the + * distribution. + */ + template<typename _IntType = int, typename _RealType = double> + class geometric_distribution + { + public: + // types + typedef _RealType input_type; + typedef _IntType result_type; + + // constructors and member function + explicit + geometric_distribution(const _RealType& __p = _RealType(0.5)) + : _M_p(__p) + { + _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0)); + _M_initialize(); + } + + /** + * Gets the distribution parameter @p p. + */ + _RealType + p() const + { return _M_p; } + + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %geometric_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %geometric_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const geometric_distribution<_IntType1, _RealType1>& __x); + + /** + * Extracts a %geometric_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %geometric_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + geometric_distribution& __x) + { + __is >> __x._M_p; + __x._M_initialize(); + return __is; + } + + private: + void + _M_initialize() + { _M_log_p = std::log(_M_p); } + + _RealType _M_p; + _RealType _M_log_p; + }; + + + template<typename _RealType> + class normal_distribution; + + /** + * @brief A discrete Poisson random number distribution. + * + * The formula for the Poisson probability mass function is + * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the + * parameter of the distribution. + */ + template<typename _IntType = int, typename _RealType = double> + class poisson_distribution + { + public: + // types + typedef _RealType input_type; + typedef _IntType result_type; + + // constructors and member function + explicit + poisson_distribution(const _RealType& __mean = _RealType(1)) + : _M_mean(__mean), _M_nd() + { + _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0); + _M_initialize(); + } + + /** + * Gets the distribution parameter @p mean. + */ + _RealType + mean() const + { return _M_mean; } + + void + reset() + { _M_nd.reset(); } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %poisson_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %poisson_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const poisson_distribution<_IntType1, _RealType1>& __x); + + /** + * Extracts a %poisson_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %poisson_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + poisson_distribution<_IntType1, _RealType1>& __x); + + private: + void + _M_initialize(); + + // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. + normal_distribution<_RealType> _M_nd; + + _RealType _M_mean; + + // Hosts either log(mean) or the threshold of the simple method. + _RealType _M_lm_thr; +#if _GLIBCXX_USE_C99_MATH_TR1 + _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb; +#endif + }; + + + /** + * @brief A discrete binomial random number distribution. + * + * The formula for the binomial probability mass function is + * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$ + * and @f$ p @f$ are the parameters of the distribution. + */ + template<typename _IntType = int, typename _RealType = double> + class binomial_distribution + { + public: + // types + typedef _RealType input_type; + typedef _IntType result_type; + + // constructors and member function + explicit + binomial_distribution(_IntType __t = 1, + const _RealType& __p = _RealType(0.5)) + : _M_t(__t), _M_p(__p), _M_nd() + { + _GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0)); + _M_initialize(); + } + + /** + * Gets the distribution @p t parameter. + */ + _IntType + t() const + { return _M_t; } + + /** + * Gets the distribution @p p parameter. + */ + _RealType + p() const + { return _M_p; } + + void + reset() + { _M_nd.reset(); } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %binomial_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %binomial_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const binomial_distribution<_IntType1, _RealType1>& __x); + + /** + * Extracts a %binomial_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %binomial_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _IntType1, typename _RealType1, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + binomial_distribution<_IntType1, _RealType1>& __x); + + private: + void + _M_initialize(); + + template<class _UniformRandomNumberGenerator> + result_type + _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t); + + // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. + normal_distribution<_RealType> _M_nd; + + _RealType _M_q; +#if _GLIBCXX_USE_C99_MATH_TR1 + _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c, + _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p; +#endif + _RealType _M_p; + _IntType _M_t; + + bool _M_easy; + }; + + /* @} */ // group tr1_random_distributions_discrete + + /** + * @addtogroup tr1_random_distributions_continuous Continuous Distributions + * @ingroup tr1_random_distributions + * @{ + */ + + /** + * @brief Uniform continuous distribution for random numbers. + * + * A continuous random distribution on the range [min, max) with equal + * probability throughout the range. The URNG should be real-valued and + * deliver number in the range [0, 1). + */ + template<typename _RealType = double> + class uniform_real + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs a uniform_real object. + * + * @param __min [IN] The lower bound of the distribution. + * @param __max [IN] The upper bound of the distribution. + */ + explicit + uniform_real(_RealType __min = _RealType(0), + _RealType __max = _RealType(1)) + : _M_min(__min), _M_max(__max) + { + _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max); + } + + result_type + min() const + { return _M_min; } + + result_type + max() const + { return _M_max; } + + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { return (__urng() * (_M_max - _M_min)) + _M_min; } + + /** + * Inserts a %uniform_real random number distribution @p __x into the + * output stream @p __os. + * + * @param __os An output stream. + * @param __x A %uniform_real random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_real<_RealType1>& __x); + + /** + * Extracts a %uniform_real random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %uniform_real random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_real<_RealType1>& __x); + + private: + _RealType _M_min; + _RealType _M_max; + }; + + + /** + * @brief An exponential continuous distribution for random numbers. + * + * The formula for the exponential probability mass function is + * @f$ p(x) = \lambda e^{-\lambda x} @f$. + * + * <table border=1 cellpadding=10 cellspacing=0> + * <caption align=top>Distribution Statistics</caption> + * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr> + * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr> + * <tr><td>Mode</td><td>@f$ zero @f$</td></tr> + * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr> + * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr> + * </table> + */ + template<typename _RealType = double> + class exponential_distribution + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs an exponential distribution with inverse scale parameter + * @f$ \lambda @f$. + */ + explicit + exponential_distribution(const result_type& __lambda = result_type(1)) + : _M_lambda(__lambda) + { + _GLIBCXX_DEBUG_ASSERT(_M_lambda > 0); + } + + /** + * Gets the inverse scale parameter of the distribution. + */ + _RealType + lambda() const + { return _M_lambda; } + + /** + * Resets the distribution. + * + * Has no effect on exponential distributions. + */ + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { return -std::log(__urng()) / _M_lambda; } + + /** + * Inserts a %exponential_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %exponential_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const exponential_distribution<_RealType1>& __x); + + /** + * Extracts a %exponential_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %exponential_distribution random number + * generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + exponential_distribution& __x) + { return __is >> __x._M_lambda; } + + private: + result_type _M_lambda; + }; + + + /** + * @brief A normal continuous distribution for random numbers. + * + * The formula for the normal probability mass function is + * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}} + * e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$. + */ + template<typename _RealType = double> + class normal_distribution + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs a normal distribution with parameters @f$ mean @f$ and + * @f$ \sigma @f$. + */ + explicit + normal_distribution(const result_type& __mean = result_type(0), + const result_type& __sigma = result_type(1)) + : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false) + { + _GLIBCXX_DEBUG_ASSERT(_M_sigma > 0); + } + + /** + * Gets the mean of the distribution. + */ + _RealType + mean() const + { return _M_mean; } + + /** + * Gets the @f$ \sigma @f$ of the distribution. + */ + _RealType + sigma() const + { return _M_sigma; } + + /** + * Resets the distribution. + */ + void + reset() + { _M_saved_available = false; } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %normal_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %normal_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const normal_distribution<_RealType1>& __x); + + /** + * Extracts a %normal_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %normal_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + normal_distribution<_RealType1>& __x); + + private: + result_type _M_mean; + result_type _M_sigma; + result_type _M_saved; + bool _M_saved_available; + }; + + + /** + * @brief A gamma continuous distribution for random numbers. + * + * The formula for the gamma probability mass function is + * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$. + */ + template<typename _RealType = double> + class gamma_distribution + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs a gamma distribution with parameters @f$ \alpha @f$. + */ + explicit + gamma_distribution(const result_type& __alpha_val = result_type(1)) + : _M_alpha(__alpha_val) + { + _GLIBCXX_DEBUG_ASSERT(_M_alpha > 0); + _M_initialize(); + } + + /** + * Gets the @f$ \alpha @f$ of the distribution. + */ + _RealType + alpha() const + { return _M_alpha; } + + /** + * Resets the distribution. + */ + void + reset() { } + + template<class _UniformRandomNumberGenerator> + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %gamma_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %gamma_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template<typename _RealType1, typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const gamma_distribution<_RealType1>& __x); + + /** + * Extracts a %gamma_distribution random number distribution + * @p __x from the input stream @p __is. + * + * @param __is An input stream. + * @param __x A %gamma_distribution random number generator engine. + * + * @returns The input stream with @p __x extracted or in an error state. + */ + template<typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + gamma_distribution& __x) + { + __is >> __x._M_alpha; + __x._M_initialize(); + return __is; + } + + private: + void + _M_initialize(); + + result_type _M_alpha; + + // Hosts either lambda of GB or d of modified Vaduva's. + result_type _M_l_d; + }; + + /* @} */ // group tr1_random_distributions_continuous + /* @} */ // group tr1_random_distributions + /* @} */ // group tr1_random +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_RANDOM_H diff --git a/libstdc++-v3/include/tr1/random.tcc b/libstdc++-v3/include/tr1/random.tcc new file mode 100644 index 000000000..3d8c4fe1c --- /dev/null +++ b/libstdc++-v3/include/tr1/random.tcc @@ -0,0 +1,1721 @@ +// random number generation (out of line) -*- C++ -*- + +// Copyright (C) 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + + +/** @file tr1/random.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/random} + */ + +#ifndef _GLIBCXX_TR1_RANDOM_TCC +#define _GLIBCXX_TR1_RANDOM_TCC 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + /* + * (Further) implementation-space details. + */ + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid + // integer overflow. + // + // Because a and c are compile-time integral constants the compiler kindly + // elides any unreachable paths. + // + // Preconditions: a > 0, m > 0. + // + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool> + struct _Mod + { + static _Tp + __calc(_Tp __x) + { + if (__a == 1) + __x %= __m; + else + { + static const _Tp __q = __m / __a; + static const _Tp __r = __m % __a; + + _Tp __t1 = __a * (__x % __q); + _Tp __t2 = __r * (__x / __q); + if (__t1 >= __t2) + __x = __t1 - __t2; + else + __x = __m - __t2 + __t1; + } + + if (__c != 0) + { + const _Tp __d = __m - __x; + if (__d > __c) + __x += __c; + else + __x = __c - __d; + } + return __x; + } + }; + + // Special case for m == 0 -- use unsigned integer overflow as modulo + // operator. + template<typename _Tp, _Tp __a, _Tp __c, _Tp __m> + struct _Mod<_Tp, __a, __c, __m, true> + { + static _Tp + __calc(_Tp __x) + { return __a * __x + __c; } + }; + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace __detail + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + const _UIntType + linear_congruential<_UIntType, __a, __c, __m>::multiplier; + + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + const _UIntType + linear_congruential<_UIntType, __a, __c, __m>::increment; + + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + const _UIntType + linear_congruential<_UIntType, __a, __c, __m>::modulus; + + /** + * Seeds the LCR with integral value @p __x0, adjusted so that the + * ring identity is never a member of the convergence set. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + void + linear_congruential<_UIntType, __a, __c, __m>:: + seed(unsigned long __x0) + { + if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) + && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0)) + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1); + else + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0); + } + + /** + * Seeds the LCR engine with a value generated by @p __g. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + template<class _Gen> + void + linear_congruential<_UIntType, __a, __c, __m>:: + seed(_Gen& __g, false_type) + { + _UIntType __x0 = __g(); + if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) + && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0)) + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1); + else + _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0); + } + + /** + * Gets the next generated value in sequence. + */ + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> + typename linear_congruential<_UIntType, __a, __c, __m>::result_type + linear_congruential<_UIntType, __a, __c, __m>:: + operator()() + { + _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x); + return _M_x; + } + + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const linear_congruential<_UIntType, __a, __c, __m>& __lcr) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__os.widen(' ')); + + __os << __lcr._M_x; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + linear_congruential<_UIntType, __a, __c, __m>& __lcr) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec); + + __is >> __lcr._M_x; + + __is.flags(__flags); + return __is; + } + + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::word_size; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::state_size; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::shift_size; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::mask_bits; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const _UIntType + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::parameter_a; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::output_u; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::output_s; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const _UIntType + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::output_b; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::output_t; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const _UIntType + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::output_c; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + const int + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::output_l; + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + void + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>:: + seed(unsigned long __value) + { + _M_x[0] = __detail::__mod<_UIntType, 1, 0, + __detail::_Shift<_UIntType, __w>::__value>(__value); + + for (int __i = 1; __i < state_size; ++__i) + { + _UIntType __x = _M_x[__i - 1]; + __x ^= __x >> (__w - 2); + __x *= 1812433253ul; + __x += __i; + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, + __detail::_Shift<_UIntType, __w>::__value>(__x); + } + _M_p = state_size; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + template<class _Gen> + void + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>:: + seed(_Gen& __gen, false_type) + { + for (int __i = 0; __i < state_size; ++__i) + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, + __detail::_Shift<_UIntType, __w>::__value>(__gen()); + _M_p = state_size; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, + _UIntType __b, int __t, _UIntType __c, int __l> + typename + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>::result_type + mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, + __b, __t, __c, __l>:: + operator()() + { + // Reload the vector - cost is O(n) amortized over n calls. + if (_M_p >= state_size) + { + const _UIntType __upper_mask = (~_UIntType()) << __r; + const _UIntType __lower_mask = ~__upper_mask; + + for (int __k = 0; __k < (__n - __m); ++__k) + { + _UIntType __y = ((_M_x[__k] & __upper_mask) + | (_M_x[__k + 1] & __lower_mask)); + _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1) + ^ ((__y & 0x01) ? __a : 0)); + } + + for (int __k = (__n - __m); __k < (__n - 1); ++__k) + { + _UIntType __y = ((_M_x[__k] & __upper_mask) + | (_M_x[__k + 1] & __lower_mask)); + _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1) + ^ ((__y & 0x01) ? __a : 0)); + } + + _UIntType __y = ((_M_x[__n - 1] & __upper_mask) + | (_M_x[0] & __lower_mask)); + _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1) + ^ ((__y & 0x01) ? __a : 0)); + _M_p = 0; + } + + // Calculate o(x(i)). + result_type __z = _M_x[_M_p++]; + __z ^= (__z >> __u); + __z ^= (__z << __s) & __b; + __z ^= (__z << __t) & __c; + __z ^= (__z >> __l); + + return __z; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, _UIntType __b, int __t, + _UIntType __c, int __l, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const mersenne_twister<_UIntType, __w, __n, __m, + __r, __a, __u, __s, __b, __t, __c, __l>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + for (int __i = 0; __i < __n - 1; ++__i) + __os << __x._M_x[__i] << __space; + __os << __x._M_x[__n - 1]; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UIntType, int __w, int __n, int __m, int __r, + _UIntType __a, int __u, int __s, _UIntType __b, int __t, + _UIntType __c, int __l, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + mersenne_twister<_UIntType, __w, __n, __m, + __r, __a, __u, __s, __b, __t, __c, __l>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + for (int __i = 0; __i < __n; ++__i) + __is >> __x._M_x[__i]; + + __is.flags(__flags); + return __is; + } + + + template<typename _IntType, _IntType __m, int __s, int __r> + const _IntType + subtract_with_carry<_IntType, __m, __s, __r>::modulus; + + template<typename _IntType, _IntType __m, int __s, int __r> + const int + subtract_with_carry<_IntType, __m, __s, __r>::long_lag; + + template<typename _IntType, _IntType __m, int __s, int __r> + const int + subtract_with_carry<_IntType, __m, __s, __r>::short_lag; + + template<typename _IntType, _IntType __m, int __s, int __r> + void + subtract_with_carry<_IntType, __m, __s, __r>:: + seed(unsigned long __value) + { + if (__value == 0) + __value = 19780503; + + std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563> + __lcg(__value); + + for (int __i = 0; __i < long_lag; ++__i) + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__lcg()); + + _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; + _M_p = 0; + } + + template<typename _IntType, _IntType __m, int __s, int __r> + template<class _Gen> + void + subtract_with_carry<_IntType, __m, __s, __r>:: + seed(_Gen& __gen, false_type) + { + const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32; + + for (int __i = 0; __i < long_lag; ++__i) + { + _UIntType __tmp = 0; + _UIntType __factor = 1; + for (int __j = 0; __j < __n; ++__j) + { + __tmp += __detail::__mod<__detail::_UInt32Type, 1, 0, 0> + (__gen()) * __factor; + __factor *= __detail::_Shift<_UIntType, 32>::__value; + } + _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__tmp); + } + _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; + _M_p = 0; + } + + template<typename _IntType, _IntType __m, int __s, int __r> + typename subtract_with_carry<_IntType, __m, __s, __r>::result_type + subtract_with_carry<_IntType, __m, __s, __r>:: + operator()() + { + // Derive short lag index from current index. + int __ps = _M_p - short_lag; + if (__ps < 0) + __ps += long_lag; + + // Calculate new x(i) without overflow or division. + // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry + // cannot overflow. + _UIntType __xi; + if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) + { + __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; + _M_carry = 0; + } + else + { + __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps]; + _M_carry = 1; + } + _M_x[_M_p] = __xi; + + // Adjust current index to loop around in ring buffer. + if (++_M_p >= long_lag) + _M_p = 0; + + return __xi; + } + + template<typename _IntType, _IntType __m, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry<_IntType, __m, __s, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + for (int __i = 0; __i < __r; ++__i) + __os << __x._M_x[__i] << __space; + __os << __x._M_carry; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<typename _IntType, _IntType __m, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry<_IntType, __m, __s, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + for (int __i = 0; __i < __r; ++__i) + __is >> __x._M_x[__i]; + __is >> __x._M_carry; + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType, int __w, int __s, int __r> + const int + subtract_with_carry_01<_RealType, __w, __s, __r>::word_size; + + template<typename _RealType, int __w, int __s, int __r> + const int + subtract_with_carry_01<_RealType, __w, __s, __r>::long_lag; + + template<typename _RealType, int __w, int __s, int __r> + const int + subtract_with_carry_01<_RealType, __w, __s, __r>::short_lag; + + template<typename _RealType, int __w, int __s, int __r> + void + subtract_with_carry_01<_RealType, __w, __s, __r>:: + _M_initialize_npows() + { + for (int __j = 0; __j < __n; ++__j) +#if _GLIBCXX_USE_C99_MATH_TR1 + _M_npows[__j] = std::tr1::ldexp(_RealType(1), -__w + __j * 32); +#else + _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32); +#endif + } + + template<typename _RealType, int __w, int __s, int __r> + void + subtract_with_carry_01<_RealType, __w, __s, __r>:: + seed(unsigned long __value) + { + if (__value == 0) + __value = 19780503; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 512. Seeding subtract_with_carry_01 from a single unsigned long. + std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563> + __lcg(__value); + + this->seed(__lcg); + } + + template<typename _RealType, int __w, int __s, int __r> + template<class _Gen> + void + subtract_with_carry_01<_RealType, __w, __s, __r>:: + seed(_Gen& __gen, false_type) + { + for (int __i = 0; __i < long_lag; ++__i) + { + for (int __j = 0; __j < __n - 1; ++__j) + _M_x[__i][__j] = __detail::__mod<_UInt32Type, 1, 0, 0>(__gen()); + _M_x[__i][__n - 1] = __detail::__mod<_UInt32Type, 1, 0, + __detail::_Shift<_UInt32Type, __w % 32>::__value>(__gen()); + } + + _M_carry = 1; + for (int __j = 0; __j < __n; ++__j) + if (_M_x[long_lag - 1][__j] != 0) + { + _M_carry = 0; + break; + } + + _M_p = 0; + } + + template<typename _RealType, int __w, int __s, int __r> + typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type + subtract_with_carry_01<_RealType, __w, __s, __r>:: + operator()() + { + // Derive short lag index from current index. + int __ps = _M_p - short_lag; + if (__ps < 0) + __ps += long_lag; + + _UInt32Type __new_carry; + for (int __j = 0; __j < __n - 1; ++__j) + { + if (_M_x[__ps][__j] > _M_x[_M_p][__j] + || (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0)) + __new_carry = 0; + else + __new_carry = 1; + + _M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry; + _M_carry = __new_carry; + } + + if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1] + || (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0)) + __new_carry = 0; + else + __new_carry = 1; + + _M_x[_M_p][__n - 1] = __detail::__mod<_UInt32Type, 1, 0, + __detail::_Shift<_UInt32Type, __w % 32>::__value> + (_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry); + _M_carry = __new_carry; + + result_type __ret = 0.0; + for (int __j = 0; __j < __n; ++__j) + __ret += _M_x[_M_p][__j] * _M_npows[__j]; + + // Adjust current index to loop around in ring buffer. + if (++_M_p >= long_lag) + _M_p = 0; + + return __ret; + } + + template<typename _RealType, int __w, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const subtract_with_carry_01<_RealType, __w, __s, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + for (int __i = 0; __i < __r; ++__i) + for (int __j = 0; __j < __x.__n; ++__j) + __os << __x._M_x[__i][__j] << __space; + __os << __x._M_carry; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<typename _RealType, int __w, int __s, int __r, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + subtract_with_carry_01<_RealType, __w, __s, __r>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + for (int __i = 0; __i < __r; ++__i) + for (int __j = 0; __j < __x.__n; ++__j) + __is >> __x._M_x[__i][__j]; + __is >> __x._M_carry; + + __is.flags(__flags); + return __is; + } + + template<class _UniformRandomNumberGenerator, int __p, int __r> + const int + discard_block<_UniformRandomNumberGenerator, __p, __r>::block_size; + + template<class _UniformRandomNumberGenerator, int __p, int __r> + const int + discard_block<_UniformRandomNumberGenerator, __p, __r>::used_block; + + template<class _UniformRandomNumberGenerator, int __p, int __r> + typename discard_block<_UniformRandomNumberGenerator, + __p, __r>::result_type + discard_block<_UniformRandomNumberGenerator, __p, __r>:: + operator()() + { + if (_M_n >= used_block) + { + while (_M_n < block_size) + { + _M_b(); + ++_M_n; + } + _M_n = 0; + } + ++_M_n; + return _M_b(); + } + + template<class _UniformRandomNumberGenerator, int __p, int __r, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const discard_block<_UniformRandomNumberGenerator, + __p, __r>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed + | __ios_base::left); + __os.fill(__space); + + __os << __x._M_b << __space << __x._M_n; + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UniformRandomNumberGenerator, int __p, int __r, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + discard_block<_UniformRandomNumberGenerator, __p, __r>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_b >> __x._M_n; + + __is.flags(__flags); + return __is; + } + + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + const int + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>::shift1; + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + const int + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>::shift2; + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + void + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>:: + _M_initialize_max() + { + const int __w = std::numeric_limits<result_type>::digits; + + const result_type __m1 = + std::min(result_type(_M_b1.max() - _M_b1.min()), + __detail::_Shift<result_type, __w - __s1>::__value - 1); + + const result_type __m2 = + std::min(result_type(_M_b2.max() - _M_b2.min()), + __detail::_Shift<result_type, __w - __s2>::__value - 1); + + // NB: In TR1 s1 is not required to be >= s2. + if (__s1 < __s2) + _M_max = _M_initialize_max_aux(__m2, __m1, __s2 - __s1) << __s1; + else + _M_max = _M_initialize_max_aux(__m1, __m2, __s1 - __s2) << __s2; + } + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2> + typename xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>::result_type + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>:: + _M_initialize_max_aux(result_type __a, result_type __b, int __d) + { + const result_type __two2d = result_type(1) << __d; + const result_type __c = __a * __two2d; + + if (__a == 0 || __b < __two2d) + return __c + __b; + + const result_type __t = std::max(__c, __b); + const result_type __u = std::min(__c, __b); + + result_type __ub = __u; + result_type __p; + for (__p = 0; __ub != 1; __ub >>= 1) + ++__p; + + const result_type __two2p = result_type(1) << __p; + const result_type __k = __t / __two2p; + + if (__k & 1) + return (__k + 1) * __two2p - 1; + + if (__c >= __b) + return (__k + 1) * __two2p + _M_initialize_max_aux((__t % __two2p) + / __two2d, + __u % __two2p, __d); + else + return (__k + 1) * __two2p + _M_initialize_max_aux((__u % __two2p) + / __two2d, + __t % __two2p, __d); + } + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); + __os.fill(__space); + + __os << __x.base1() << __space << __x.base2(); + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<class _UniformRandomNumberGenerator1, int __s1, + class _UniformRandomNumberGenerator2, int __s2, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::skipws); + + __is >> __x._M_b1 >> __x._M_b2; + + __is.flags(__flags); + return __is; + } + + + template<typename _IntType> + template<typename _UniformRandomNumberGenerator> + typename uniform_int<_IntType>::result_type + uniform_int<_IntType>:: + _M_call(_UniformRandomNumberGenerator& __urng, + result_type __min, result_type __max, true_type) + { + // XXX Must be fixed to work well for *arbitrary* __urng.max(), + // __urng.min(), __max, __min. Currently works fine only in the + // most common case __urng.max() - __urng.min() >= __max - __min, + // with __urng.max() > __urng.min() >= 0. + typedef typename __gnu_cxx::__add_unsigned<typename + _UniformRandomNumberGenerator::result_type>::__type __urntype; + typedef typename __gnu_cxx::__add_unsigned<result_type>::__type + __utype; + typedef typename __gnu_cxx::__conditional_type<(sizeof(__urntype) + > sizeof(__utype)), + __urntype, __utype>::__type __uctype; + + result_type __ret; + + const __urntype __urnmin = __urng.min(); + const __urntype __urnmax = __urng.max(); + const __urntype __urnrange = __urnmax - __urnmin; + const __uctype __urange = __max - __min; + const __uctype __udenom = (__urnrange <= __urange + ? 1 : __urnrange / (__urange + 1)); + do + __ret = (__urntype(__urng()) - __urnmin) / __udenom; + while (__ret > __max - __min); + + return __ret + __min; + } + + template<typename _IntType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_int<_IntType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + + __os << __x.min() << __space << __x.max(); + + __os.flags(__flags); + __os.fill(__fill); + return __os; + } + + template<typename _IntType, typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_int<_IntType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_min >> __x._M_max; + + __is.flags(__flags); + return __is; + } + + + template<typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bernoulli_distribution& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<double>::__max_digits10); + + __os << __x.p(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename geometric_distribution<_IntType, _RealType>::result_type + geometric_distribution<_IntType, _RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + // About the epsilon thing see this thread: + // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html + const _RealType __naf = + (1 - std::numeric_limits<_RealType>::epsilon()) / 2; + // The largest _RealType convertible to _IntType. + const _RealType __thr = + std::numeric_limits<_IntType>::max() + __naf; + + _RealType __cand; + do + __cand = std::ceil(std::log(__urng()) / _M_log_p); + while (__cand >= __thr); + + return result_type(__cand + __naf); + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const geometric_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.p(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + + template<typename _IntType, typename _RealType> + void + poisson_distribution<_IntType, _RealType>:: + _M_initialize() + { +#if _GLIBCXX_USE_C99_MATH_TR1 + if (_M_mean >= 12) + { + const _RealType __m = std::floor(_M_mean); + _M_lm_thr = std::log(_M_mean); + _M_lfm = std::tr1::lgamma(__m + 1); + _M_sm = std::sqrt(__m); + + const _RealType __pi_4 = 0.7853981633974483096156608458198757L; + const _RealType __dx = std::sqrt(2 * __m * std::log(32 * __m + / __pi_4)); + _M_d = std::tr1::round(std::max(_RealType(6), + std::min(__m, __dx))); + const _RealType __cx = 2 * __m + _M_d; + _M_scx = std::sqrt(__cx / 2); + _M_1cx = 1 / __cx; + + _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx); + _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d; + } + else +#endif + _M_lm_thr = std::exp(-_M_mean); + } + + /** + * A rejection algorithm when mean >= 12 and a simple method based + * upon the multiplication of uniform random variates otherwise. + * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 + * is defined. + * + * Reference: + * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, + * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!). + */ + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename poisson_distribution<_IntType, _RealType>::result_type + poisson_distribution<_IntType, _RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + if (_M_mean >= 12) + { + _RealType __x; + + // See comments above... + const _RealType __naf = + (1 - std::numeric_limits<_RealType>::epsilon()) / 2; + const _RealType __thr = + std::numeric_limits<_IntType>::max() + __naf; + + const _RealType __m = std::floor(_M_mean); + // sqrt(pi / 2) + const _RealType __spi_2 = 1.2533141373155002512078826424055226L; + const _RealType __c1 = _M_sm * __spi_2; + const _RealType __c2 = _M_c2b + __c1; + const _RealType __c3 = __c2 + 1; + const _RealType __c4 = __c3 + 1; + // e^(1 / 78) + const _RealType __e178 = 1.0129030479320018583185514777512983L; + const _RealType __c5 = __c4 + __e178; + const _RealType __c = _M_cb + __c5; + const _RealType __2cx = 2 * (2 * __m + _M_d); + + bool __reject = true; + do + { + const _RealType __u = __c * __urng(); + const _RealType __e = -std::log(__urng()); + + _RealType __w = 0.0; + + if (__u <= __c1) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = -std::abs(__n) * _M_sm - 1; + __x = std::floor(__y); + __w = -__n * __n / 2; + if (__x < -__m) + continue; + } + else if (__u <= __c2) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = 1 + std::abs(__n) * _M_scx; + __x = std::ceil(__y); + __w = __y * (2 - __y) * _M_1cx; + if (__x > _M_d) + continue; + } + else if (__u <= __c3) + // NB: This case not in the book, nor in the Errata, + // but should be ok... + __x = -1; + else if (__u <= __c4) + __x = 0; + else if (__u <= __c5) + __x = 1; + else + { + const _RealType __v = -std::log(__urng()); + const _RealType __y = _M_d + __v * __2cx / _M_d; + __x = std::ceil(__y); + __w = -_M_d * _M_1cx * (1 + __y / 2); + } + + __reject = (__w - __e - __x * _M_lm_thr + > _M_lfm - std::tr1::lgamma(__x + __m + 1)); + + __reject |= __x + __m >= __thr; + + } while (__reject); + + return result_type(__x + __m + __naf); + } + else +#endif + { + _IntType __x = 0; + _RealType __prod = 1.0; + + do + { + __prod *= __urng(); + __x += 1; + } + while (__prod > _M_lm_thr); + + return __x - 1; + } + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const poisson_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.mean() << __space << __x._M_nd; + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + poisson_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::skipws); + + __is >> __x._M_mean >> __x._M_nd; + __x._M_initialize(); + + __is.flags(__flags); + return __is; + } + + + template<typename _IntType, typename _RealType> + void + binomial_distribution<_IntType, _RealType>:: + _M_initialize() + { + const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; + + _M_easy = true; + +#if _GLIBCXX_USE_C99_MATH_TR1 + if (_M_t * __p12 >= 8) + { + _M_easy = false; + const _RealType __np = std::floor(_M_t * __p12); + const _RealType __pa = __np / _M_t; + const _RealType __1p = 1 - __pa; + + const _RealType __pi_4 = 0.7853981633974483096156608458198757L; + const _RealType __d1x = + std::sqrt(__np * __1p * std::log(32 * __np + / (81 * __pi_4 * __1p))); + _M_d1 = std::tr1::round(std::max(_RealType(1), __d1x)); + const _RealType __d2x = + std::sqrt(__np * __1p * std::log(32 * _M_t * __1p + / (__pi_4 * __pa))); + _M_d2 = std::tr1::round(std::max(_RealType(1), __d2x)); + + // sqrt(pi / 2) + const _RealType __spi_2 = 1.2533141373155002512078826424055226L; + _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np)); + _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p)); + _M_c = 2 * _M_d1 / __np; + _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2; + const _RealType __a12 = _M_a1 + _M_s2 * __spi_2; + const _RealType __s1s = _M_s1 * _M_s1; + _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p)) + * 2 * __s1s / _M_d1 + * std::exp(-_M_d1 * _M_d1 / (2 * __s1s))); + const _RealType __s2s = _M_s2 * _M_s2; + _M_s = (_M_a123 + 2 * __s2s / _M_d2 + * std::exp(-_M_d2 * _M_d2 / (2 * __s2s))); + _M_lf = (std::tr1::lgamma(__np + 1) + + std::tr1::lgamma(_M_t - __np + 1)); + _M_lp1p = std::log(__pa / __1p); + + _M_q = -std::log(1 - (__p12 - __pa) / __1p); + } + else +#endif + _M_q = -std::log(1 - __p12); + } + + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename binomial_distribution<_IntType, _RealType>::result_type + binomial_distribution<_IntType, _RealType>:: + _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t) + { + _IntType __x = 0; + _RealType __sum = 0; + + do + { + const _RealType __e = -std::log(__urng()); + __sum += __e / (__t - __x); + __x += 1; + } + while (__sum <= _M_q); + + return __x - 1; + } + + /** + * A rejection algorithm when t * p >= 8 and a simple waiting time + * method - the second in the referenced book - otherwise. + * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 + * is defined. + * + * Reference: + * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, + * New York, 1986, Ch. X, Sect. 4 (+ Errata!). + */ + template<typename _IntType, typename _RealType> + template<class _UniformRandomNumberGenerator> + typename binomial_distribution<_IntType, _RealType>::result_type + binomial_distribution<_IntType, _RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + result_type __ret; + const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; + +#if _GLIBCXX_USE_C99_MATH_TR1 + if (!_M_easy) + { + _RealType __x; + + // See comments above... + const _RealType __naf = + (1 - std::numeric_limits<_RealType>::epsilon()) / 2; + const _RealType __thr = + std::numeric_limits<_IntType>::max() + __naf; + + const _RealType __np = std::floor(_M_t * __p12); + const _RealType __pa = __np / _M_t; + + // sqrt(pi / 2) + const _RealType __spi_2 = 1.2533141373155002512078826424055226L; + const _RealType __a1 = _M_a1; + const _RealType __a12 = __a1 + _M_s2 * __spi_2; + const _RealType __a123 = _M_a123; + const _RealType __s1s = _M_s1 * _M_s1; + const _RealType __s2s = _M_s2 * _M_s2; + + bool __reject; + do + { + const _RealType __u = _M_s * __urng(); + + _RealType __v; + + if (__u <= __a1) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = _M_s1 * std::abs(__n); + __reject = __y >= _M_d1; + if (!__reject) + { + const _RealType __e = -std::log(__urng()); + __x = std::floor(__y); + __v = -__e - __n * __n / 2 + _M_c; + } + } + else if (__u <= __a12) + { + const _RealType __n = _M_nd(__urng); + const _RealType __y = _M_s2 * std::abs(__n); + __reject = __y >= _M_d2; + if (!__reject) + { + const _RealType __e = -std::log(__urng()); + __x = std::floor(-__y); + __v = -__e - __n * __n / 2; + } + } + else if (__u <= __a123) + { + const _RealType __e1 = -std::log(__urng()); + const _RealType __e2 = -std::log(__urng()); + + const _RealType __y = _M_d1 + 2 * __s1s * __e1 / _M_d1; + __x = std::floor(__y); + __v = (-__e2 + _M_d1 * (1 / (_M_t - __np) + -__y / (2 * __s1s))); + __reject = false; + } + else + { + const _RealType __e1 = -std::log(__urng()); + const _RealType __e2 = -std::log(__urng()); + + const _RealType __y = _M_d2 + 2 * __s2s * __e1 / _M_d2; + __x = std::floor(-__y); + __v = -__e2 - _M_d2 * __y / (2 * __s2s); + __reject = false; + } + + __reject = __reject || __x < -__np || __x > _M_t - __np; + if (!__reject) + { + const _RealType __lfx = + std::tr1::lgamma(__np + __x + 1) + + std::tr1::lgamma(_M_t - (__np + __x) + 1); + __reject = __v > _M_lf - __lfx + __x * _M_lp1p; + } + + __reject |= __x + __np >= __thr; + } + while (__reject); + + __x += __np + __naf; + + const _IntType __z = _M_waiting(__urng, _M_t - _IntType(__x)); + __ret = _IntType(__x) + __z; + } + else +#endif + __ret = _M_waiting(__urng, _M_t); + + if (__p12 != _M_p) + __ret = _M_t - __ret; + return __ret; + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const binomial_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.t() << __space << __x.p() + << __space << __x._M_nd; + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _IntType, typename _RealType, + typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + binomial_distribution<_IntType, _RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_t >> __x._M_p >> __x._M_nd; + __x._M_initialize(); + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const uniform_real<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.min() << __space << __x.max(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + uniform_real<_RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::skipws); + + __is >> __x._M_min >> __x._M_max; + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const exponential_distribution<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.lambda(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + + /** + * Polar method due to Marsaglia. + * + * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, + * New York, 1986, Ch. V, Sect. 4.4. + */ + template<typename _RealType> + template<class _UniformRandomNumberGenerator> + typename normal_distribution<_RealType>::result_type + normal_distribution<_RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + result_type __ret; + + if (_M_saved_available) + { + _M_saved_available = false; + __ret = _M_saved; + } + else + { + result_type __x, __y, __r2; + do + { + __x = result_type(2.0) * __urng() - 1.0; + __y = result_type(2.0) * __urng() - 1.0; + __r2 = __x * __x + __y * __y; + } + while (__r2 > 1.0 || __r2 == 0.0); + + const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); + _M_saved = __x * __mult; + _M_saved_available = true; + __ret = __y * __mult; + } + + __ret = __ret * _M_sigma + _M_mean; + return __ret; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const normal_distribution<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x._M_saved_available << __space + << __x.mean() << __space + << __x.sigma(); + if (__x._M_saved_available) + __os << __space << __x._M_saved; + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + normal_distribution<_RealType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + __is >> __x._M_saved_available >> __x._M_mean + >> __x._M_sigma; + if (__x._M_saved_available) + __is >> __x._M_saved; + + __is.flags(__flags); + return __is; + } + + + template<typename _RealType> + void + gamma_distribution<_RealType>:: + _M_initialize() + { + if (_M_alpha >= 1) + _M_l_d = std::sqrt(2 * _M_alpha - 1); + else + _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha)) + * (1 - _M_alpha)); + } + + /** + * Cheng's rejection algorithm GB for alpha >= 1 and a modification + * of Vaduva's rejection from Weibull algorithm due to Devroye for + * alpha < 1. + * + * References: + * Cheng, R. C. The Generation of Gamma Random Variables with Non-integral + * Shape Parameter. Applied Statistics, 26, 71-75, 1977. + * + * Vaduva, I. Computer Generation of Gamma Gandom Variables by Rejection + * and Composition Procedures. Math. Operationsforschung and Statistik, + * Series in Statistics, 8, 545-576, 1977. + * + * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, + * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!). + */ + template<typename _RealType> + template<class _UniformRandomNumberGenerator> + typename gamma_distribution<_RealType>::result_type + gamma_distribution<_RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + result_type __x; + + bool __reject; + if (_M_alpha >= 1) + { + // alpha - log(4) + const result_type __b = _M_alpha + - result_type(1.3862943611198906188344642429163531L); + const result_type __c = _M_alpha + _M_l_d; + const result_type __1l = 1 / _M_l_d; + + // 1 + log(9 / 2) + const result_type __k = 2.5040773967762740733732583523868748L; + + do + { + const result_type __u = __urng(); + const result_type __v = __urng(); + + const result_type __y = __1l * std::log(__v / (1 - __v)); + __x = _M_alpha * std::exp(__y); + + const result_type __z = __u * __v * __v; + const result_type __r = __b + __c * __y - __x; + + __reject = __r < result_type(4.5) * __z - __k; + if (__reject) + __reject = __r < std::log(__z); + } + while (__reject); + } + else + { + const result_type __c = 1 / _M_alpha; + + do + { + const result_type __z = -std::log(__urng()); + const result_type __e = -std::log(__urng()); + + __x = std::pow(__z, __c); + + __reject = __z + __e < _M_l_d + __x; + } + while (__reject); + } + + return __x; + } + + template<typename _RealType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const gamma_distribution<_RealType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__os.widen(' ')); + __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); + + __os << __x.alpha(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif diff --git a/libstdc++-v3/include/tr1/regex b/libstdc++-v3/include/tr1/regex new file mode 100644 index 000000000..714a06d33 --- /dev/null +++ b/libstdc++-v3/include/tr1/regex @@ -0,0 +1,2730 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** + * @file tr1/regex + * @author Stephen M. Webb <stephen.webb@bregmasoft.ca> + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_REGEX +#define _GLIBCXX_TR1_REGEX 1 + +#pragma GCC system_header + +#include <algorithm> +#include <bitset> +#include <iterator> +#include <locale> +#include <stdexcept> +#include <string> +#include <vector> +#include <utility> +#include <sstream> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +/** + * @defgroup tr1_regex Regular Expressions + * A facility for performing regular expression pattern matching. + */ + //@{ + +/** @namespace std::regex_constants + * @brief ISO C++ 0x entities sub namespace for regex. + */ +namespace regex_constants +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @name 5.1 Regular Expression Syntax Options + */ + //@{ + enum __syntax_option + { + _S_icase, + _S_nosubs, + _S_optimize, + _S_collate, + _S_ECMAScript, + _S_basic, + _S_extended, + _S_awk, + _S_grep, + _S_egrep, + _S_syntax_last + }; + + /** + * @brief This is a bitmask type indicating how to interpret the regex. + * + * The @c syntax_option_type is implementation defined but it is valid to + * perform bitwise operations on these values and expect the right thing to + * happen. + * + * A valid value of type syntax_option_type shall have exactly one of the + * elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep + * %set. + */ + typedef unsigned int syntax_option_type; + + /** + * Specifies that the matching of regular expressions against a character + * sequence shall be performed without regard to case. + */ + static const syntax_option_type icase = 1 << _S_icase; + + /** + * Specifies that when a regular expression is matched against a character + * container sequence, no sub-expression matches are to be stored in the + * supplied match_results structure. + */ + static const syntax_option_type nosubs = 1 << _S_nosubs; + + /** + * Specifies that the regular expression engine should pay more attention to + * the speed with which regular expressions are matched, and less to the + * speed with which regular expression objects are constructed. Otherwise + * it has no detectable effect on the program output. + */ + static const syntax_option_type optimize = 1 << _S_optimize; + + /** + * Specifies that character ranges of the form [a-b] should be locale + * sensitive. + */ + static const syntax_option_type collate = 1 << _S_collate; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript + * Language Specification, Standard Ecma-262, third edition, 1999], as + * modified in tr1 section [7.13]. This grammar is similar to that defined + * in the PERL scripting language but extended with elements found in the + * POSIX regular expression grammar. + */ + static const syntax_option_type ECMAScript = 1 << _S_ECMAScript; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001, + * Portable Operating System Interface (POSIX), Base Definitions and + * Headers, Section 9, Regular Expressions [IEEE, Information Technology -- + * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. + */ + static const syntax_option_type basic = 1 << _S_basic; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001, + * Portable Operating System Interface (POSIX), Base Definitions and Headers, + * Section 9, Regular Expressions. + */ + static const syntax_option_type extended = 1 << _S_extended; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is + * identical to syntax_option_type extended, except that C-style escape + * sequences are supported. These sequences are: + * \\\\, \\a, \\b, \\f, + * \\n, \\r, \\t , \\v, + * \\', ', and \\ddd + * (where ddd is one, two, or three octal digits). + */ + static const syntax_option_type awk = 1 << _S_awk; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is + * identical to syntax_option_type basic, except that newlines are treated + * as whitespace. + */ + static const syntax_option_type grep = 1 << _S_grep; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility grep when given the -E option in + * IEEE Std 1003.1-2001. This option is identical to syntax_option_type + * extended, except that newlines are treated as whitespace. + */ + static const syntax_option_type egrep = 1 << _S_egrep; + + //@} + + /** + * @name 5.2 Matching Rules + * + * Matching a regular expression against a sequence of characters [first, + * last) proceeds according to the rules of the grammar specified for the + * regular expression object, modified according to the effects listed + * below for any bitmask elements set. + * + */ + //@{ + + enum __match_flag + { + _S_not_bol, + _S_not_eol, + _S_not_bow, + _S_not_eow, + _S_any, + _S_not_null, + _S_continuous, + _S_prev_avail, + _S_sed, + _S_no_copy, + _S_first_only, + _S_match_flag_last + }; + + /** + * @brief This is a bitmask type indicating regex matching rules. + * + * The @c match_flag_type is implementation defined but it is valid to + * perform bitwise operations on these values and expect the right thing to + * happen. + */ + typedef std::bitset<_S_match_flag_last> match_flag_type; + + /** + * The default matching rules. + */ + static const match_flag_type match_default = 0; + + /** + * The first character in the sequence [first, last) is treated as though it + * is not at the beginning of a line, so the character (^) in the regular + * expression shall not match [first, first). + */ + static const match_flag_type match_not_bol = 1 << _S_not_bol; + + /** + * The last character in the sequence [first, last) is treated as though it + * is not at the end of a line, so the character ($) in the regular + * expression shall not match [last, last). + */ + static const match_flag_type match_not_eol = 1 << _S_not_eol; + + /** + * The expression \\b is not matched against the sub-sequence + * [first,first). + */ + static const match_flag_type match_not_bow = 1 << _S_not_bow; + + /** + * The expression \\b should not be matched against the sub-sequence + * [last,last). + */ + static const match_flag_type match_not_eow = 1 << _S_not_eow; + + /** + * If more than one match is possible then any match is an acceptable + * result. + */ + static const match_flag_type match_any = 1 << _S_any; + + /** + * The expression does not match an empty sequence. + */ + static const match_flag_type match_not_null = 1 << _S_not_null; + + /** + * The expression only matches a sub-sequence that begins at first . + */ + static const match_flag_type match_continuous = 1 << _S_continuous; + + /** + * --first is a valid iterator position. When this flag is set then the + * flags match_not_bol and match_not_bow are ignored by the regular + * expression algorithms 7.11 and iterators 7.12. + */ + static const match_flag_type match_prev_avail = 1 << _S_prev_avail; + + /** + * When a regular expression match is to be replaced by a new string, the + * new string is constructed using the rules used by the ECMAScript replace + * function in ECMA- 262 [Ecma International, ECMAScript Language + * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11 + * String.prototype.replace. In addition, during search and replace + * operations all non-overlapping occurrences of the regular expression + * are located and replaced, and sections of the input that did not match + * the expression are copied unchanged to the output string. + * + * Format strings (from ECMA-262 [15.5.4.11]): + * @li $$ The dollar-sign itself ($) + * @li $& The matched substring. + * @li $` The portion of @a string that precedes the matched substring. + * This would be match_results::prefix(). + * @li $' The portion of @a string that follows the matched substring. + * This would be match_results::suffix(). + * @li $n The nth capture, where n is in [1,9] and $n is not followed by a + * decimal digit. If n <= match_results::size() and the nth capture + * is undefined, use the empty string instead. If n > + * match_results::size(), the result is implementation-defined. + * @li $nn The nnth capture, where nn is a two-digit decimal number on + * [01, 99]. If nn <= match_results::size() and the nth capture is + * undefined, use the empty string instead. If + * nn > match_results::size(), the result is implementation-defined. + */ + static const match_flag_type format_default = 0; + + /** + * When a regular expression match is to be replaced by a new string, the + * new string is constructed using the rules used by the POSIX sed utility + * in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable + * Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. + */ + static const match_flag_type format_sed = 1 << _S_sed; + + /** + * During a search and replace operation, sections of the character + * container sequence being searched that do not match the regular + * expression shall not be copied to the output string. + */ + static const match_flag_type format_no_copy = 1 << _S_no_copy; + + /** + * When specified during a search and replace operation, only the first + * occurrence of the regular expression shall be replaced. + */ + static const match_flag_type format_first_only = 1 << _S_first_only; + + //@} + + /** + * @name 5.3 Error Types + */ + //@{ + + enum error_type + { + _S_error_collate, + _S_error_ctype, + _S_error_escape, + _S_error_backref, + _S_error_brack, + _S_error_paren, + _S_error_brace, + _S_error_badbrace, + _S_error_range, + _S_error_space, + _S_error_badrepeat, + _S_error_complexity, + _S_error_stack, + _S_error_last + }; + + /** The expression contained an invalid collating element name. */ + static const error_type error_collate(_S_error_collate); + + /** The expression contained an invalid character class name. */ + static const error_type error_ctype(_S_error_ctype); + + /** + * The expression contained an invalid escaped character, or a trailing + * escape. + */ + static const error_type error_escape(_S_error_escape); + + /** The expression contained an invalid back reference. */ + static const error_type error_backref(_S_error_backref); + + /** The expression contained mismatched [ and ]. */ + static const error_type error_brack(_S_error_brack); + + /** The expression contained mismatched ( and ). */ + static const error_type error_paren(_S_error_paren); + + /** The expression contained mismatched { and } */ + static const error_type error_brace(_S_error_brace); + + /** The expression contained an invalid range in a {} expression. */ + static const error_type error_badbrace(_S_error_badbrace); + + /** + * The expression contained an invalid character range, + * such as [b-a] in most encodings. + */ + static const error_type error_range(_S_error_range); + + /** + * There was insufficient memory to convert the expression into a + * finite state machine. + */ + static const error_type error_space(_S_error_space); + + /** + * One of <em>*?+{</em> was not preceded by a valid regular expression. + */ + static const error_type error_badrepeat(_S_error_badrepeat); + + /** + * The complexity of an attempted match against a regular expression + * exceeded a pre-set level. + */ + static const error_type error_complexity(_S_error_complexity); + + /** + * There was insufficient memory to determine whether the + * regular expression could match the specified character sequence. + */ + static const error_type error_stack(_S_error_stack); + + //@} +_GLIBCXX_END_NAMESPACE_VERSION +} + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // [7.8] Class regex_error + /** + * @brief A regular expression exception class. + * @ingroup exceptions + * + * The regular expression library throws objects of this class on error. + */ + class regex_error + : public std::runtime_error + { + public: + /** + * @brief Constructs a regex_error object. + * + * @param ecode the regex error code. + */ + explicit + regex_error(regex_constants::error_type __ecode) + : std::runtime_error("regex_error"), _M_code(__ecode) + { } + + /** + * @brief Gets the regex error code. + * + * @returns the regex error code. + */ + regex_constants::error_type + code() const + { return _M_code; } + + protected: + regex_constants::error_type _M_code; + }; + + // [7.7] Class regex_traits + /** + * @brief Describes aspects of a regular expression. + * + * A regular expression traits class that satisfies the requirements of tr1 + * section [7.2]. + * + * The class %regex is parameterized around a set of related types and + * functions used to complete the definition of its semantics. This class + * satisfies the requirements of such a traits class. + */ + template<typename _Ch_type> + struct regex_traits + { + public: + typedef _Ch_type char_type; + typedef std::basic_string<char_type> string_type; + typedef std::locale locale_type; + typedef std::ctype_base::mask char_class_type; + + public: + /** + * @brief Constructs a default traits object. + */ + regex_traits() + { } + + /** + * @brief Gives the length of a C-style string starting at @p __p. + * + * @param __p a pointer to the start of a character sequence. + * + * @returns the number of characters between @p *__p and the first + * default-initialized value of type @p char_type. In other words, uses + * the C-string algorithm for determining the length of a sequence of + * characters. + */ + static std::size_t + length(const char_type* __p) + { return string_type::traits_type::length(__p); } + + /** + * @brief Performs the identity translation. + * + * @param c A character to the locale-specific character set. + * + * @returns c. + */ + char_type + translate(char_type __c) const + { return __c; } + + /** + * @brief Translates a character into a case-insensitive equivalent. + * + * @param c A character to the locale-specific character set. + * + * @returns the locale-specific lower-case equivalent of c. + * @throws std::bad_cast if the imbued locale does not support the ctype + * facet. + */ + char_type + translate_nocase(char_type __c) const + { + using std::ctype; + using std::use_facet; + return use_facet<ctype<char_type> >(_M_locale).tolower(__c); + } + + /** + * @brief Gets a sort key for a character sequence. + * + * @param first beginning of the character sequence. + * @param last one-past-the-end of the character sequence. + * + * Returns a sort key for the character sequence designated by the + * iterator range [F1, F2) such that if the character sequence [G1, G2) + * sorts before the character sequence [H1, H2) then + * v.transform(G1, G2) < v.transform(H1, H2). + * + * What this really does is provide a more efficient way to compare a + * string to multiple other strings in locales with fancy collation + * rules and equivalence classes. + * + * @returns a locale-specific sort key equivalent to the input range. + * + * @throws std::bad_cast if the current locale does not have a collate + * facet. + */ + template<typename _Fwd_iter> + string_type + transform(_Fwd_iter __first, _Fwd_iter __last) const + { + using std::collate; + using std::use_facet; + const collate<_Ch_type>& __c(use_facet< + collate<_Ch_type> >(_M_locale)); + string_type __s(__first, __last); + return __c.transform(__s.data(), __s.data() + __s.size()); + } + + /** + * @brief Dunno. + * + * @param first beginning of the character sequence. + * @param last one-past-the-end of the character sequence. + * + * Effects: if typeid(use_facet<collate<_Ch_type> >) == + * typeid(collate_byname<_Ch_type>) and the form of the sort key + * returned by collate_byname<_Ch_type>::transform(first, last) is known + * and can be converted into a primary sort key then returns that key, + * otherwise returns an empty string. WTF?? + * + * @todo Implement this function. + */ + template<typename _Fwd_iter> + string_type + transform_primary(_Fwd_iter __first, _Fwd_iter __last) const; + + /** + * @brief Gets a collation element by name. + * + * @param first beginning of the collation element name. + * @param last one-past-the-end of the collation element name. + * + * @returns a sequence of one or more characters that represents the + * collating element consisting of the character sequence designated by + * the iterator range [first, last). Returns an empty string if the + * character sequence is not a valid collating element. + * + * @todo Implement this function. + */ + template<typename _Fwd_iter> + string_type + lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const; + + /** + * @brief Maps one or more characters to a named character + * classification. + * + * @param first beginning of the character sequence. + * @param last one-past-the-end of the character sequence. + * + * @returns an unspecified value that represents the character + * classification named by the character sequence designated by the + * iterator range [first, last). The value returned shall be independent + * of the case of the characters in the character sequence. If the name + * is not recognized then returns a value that compares equal to 0. + * + * At least the following names (or their wide-character equivalent) are + * supported. + * - d + * - w + * - s + * - alnum + * - alpha + * - blank + * - cntrl + * - digit + * - graph + * - lower + * - print + * - punct + * - space + * - upper + * - xdigit + * + * @todo Implement this function. + */ + template<typename _Fwd_iter> + char_class_type + lookup_classname(_Fwd_iter __first, _Fwd_iter __last) const; + + /** + * @brief Determines if @p c is a member of an identified class. + * + * @param c a character. + * @param f a class type (as returned from lookup_classname). + * + * @returns true if the character @p c is a member of the classification + * represented by @p f, false otherwise. + * + * @throws std::bad_cast if the current locale does not have a ctype + * facet. + */ + bool + isctype(_Ch_type __c, char_class_type __f) const; + + /** + * @brief Converts a digit to an int. + * + * @param ch a character representing a digit. + * @param radix the radix if the numeric conversion (limited to 8, 10, + * or 16). + * + * @returns the value represented by the digit ch in base radix if the + * character ch is a valid digit in base radix; otherwise returns -1. + */ + int + value(_Ch_type __ch, int __radix) const; + + /** + * @brief Imbues the regex_traits object with a copy of a new locale. + * + * @param loc A locale. + * + * @returns a copy of the previous locale in use by the regex_traits + * object. + * + * @note Calling imbue with a different locale than the one currently in + * use invalidates all cached data held by *this. + */ + locale_type + imbue(locale_type __loc) + { + std::swap(_M_locale, __loc); + return __loc; + } + + /** + * @brief Gets a copy of the current locale in use by the regex_traits + * object. + */ + locale_type + getloc() const + { return _M_locale; } + + protected: + locale_type _M_locale; + }; + + template<typename _Ch_type> + bool regex_traits<_Ch_type>:: + isctype(_Ch_type __c, char_class_type __f) const + { + using std::ctype; + using std::use_facet; + const ctype<_Ch_type>& __ctype(use_facet< + ctype<_Ch_type> >(_M_locale)); + + if (__ctype.is(__c, __f)) + return true; + + // special case of underscore in [[:w:]] + if (__c == __ctype.widen('_')) + { + const char* const __wb[] = "w"; + char_class_type __wt = this->lookup_classname(__wb, + __wb + sizeof(__wb)); + if (__f | __wt) + return true; + } + + // special case of [[:space:]] in [[:blank:]] + if (__c == __ctype.isspace(__c)) + { + const char* const __bb[] = "blank"; + char_class_type __bt = this->lookup_classname(__bb, + __bb + sizeof(__bb)); + if (__f | __bt) + return true; + } + + return false; + } + + template<typename _Ch_type> + int regex_traits<_Ch_type>:: + value(_Ch_type __ch, int __radix) const + { + std::basic_istringstream<_Ch_type> __is(string_type(1, __ch)); + int __v; + if (__radix == 8) + __is >> std::oct; + else if (__radix == 16) + __is >> std::hex; + __is >> __v; + return __is.fail() ? -1 : __v; + } + + // [7.8] Class basic_regex + /** + * Objects of specializations of this class represent regular expressions + * constructed from sequences of character type @p _Ch_type. + * + * Storage for the regular expression is allocated and deallocated as + * necessary by the member functions of this class. + */ + template<typename _Ch_type, typename _Rx_traits = regex_traits<_Ch_type> > + class basic_regex + { + public: + // types: + typedef _Ch_type value_type; + typedef regex_constants::syntax_option_type flag_type; + typedef typename _Rx_traits::locale_type locale_type; + typedef typename _Rx_traits::string_type string_type; + + /** + * @name Constants + * tr1 [7.8.1] std [28.8.1] + */ + //@{ + static const regex_constants::syntax_option_type icase + = regex_constants::icase; + static const regex_constants::syntax_option_type nosubs + = regex_constants::nosubs; + static const regex_constants::syntax_option_type optimize + = regex_constants::optimize; + static const regex_constants::syntax_option_type collate + = regex_constants::collate; + static const regex_constants::syntax_option_type ECMAScript + = regex_constants::ECMAScript; + static const regex_constants::syntax_option_type basic + = regex_constants::basic; + static const regex_constants::syntax_option_type extended + = regex_constants::extended; + static const regex_constants::syntax_option_type awk + = regex_constants::awk; + static const regex_constants::syntax_option_type grep + = regex_constants::grep; + static const regex_constants::syntax_option_type egrep + = regex_constants::egrep; + //@} + + // [7.8.2] construct/copy/destroy + /** + * Constructs a basic regular expression that does not match any + * character sequence. + */ + basic_regex() + : _M_flags(regex_constants::ECMAScript), _M_pattern(), _M_mark_count(0) + { _M_compile(); } + + /** + * @brief Constructs a basic regular expression from the sequence + * [p, p + char_traits<_Ch_type>::length(p)) interpreted according to the + * flags in @p f. + * + * @param p A pointer to the start of a C-style null-terminated string + * containing a regular expression. + * @param f Flags indicating the syntax rules and options. + * + * @throws regex_error if @p p is not a valid regular expression. + */ + explicit + basic_regex(const _Ch_type* __p, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), _M_pattern(__p), _M_mark_count(0) + { _M_compile(); } + + /** + * @brief Constructs a basic regular expression from the sequence + * [p, p + len) interpreted according to the flags in @p f. + * + * @param p A pointer to the start of a string containing a regular + * expression. + * @param len The length of the string containing the regular expression. + * @param f Flags indicating the syntax rules and options. + * + * @throws regex_error if @p p is not a valid regular expression. + */ + basic_regex(const _Ch_type* __p, std::size_t __len, flag_type __f) + : _M_flags(__f) , _M_pattern(__p, __len), _M_mark_count(0) + { _M_compile(); } + + /** + * @brief Copy-constructs a basic regular expression. + * + * @param rhs A @p regex object. + */ + basic_regex(const basic_regex& __rhs) + : _M_flags(__rhs._M_flags), _M_pattern(__rhs._M_pattern), + _M_mark_count(__rhs._M_mark_count) + { _M_compile(); } + + /** + * @brief Constructs a basic regular expression from the string + * @p s interpreted according to the flags in @p f. + * + * @param s A string containing a regular expression. + * @param f Flags indicating the syntax rules and options. + * + * @throws regex_error if @p s is not a valid regular expression. + */ + template<typename _Ch_traits, typename _Ch_alloc> + explicit + basic_regex(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), _M_pattern(__s.begin(), __s.end()), _M_mark_count(0) + { _M_compile(); } + + /** + * @brief Constructs a basic regular expression from the range + * [first, last) interpreted according to the flags in @p f. + * + * @param first The start of a range containing a valid regular + * expression. + * @param last The end of a range containing a valid regular + * expression. + * @param f The format flags of the regular expression. + * + * @throws regex_error if @p [first, last) is not a valid regular + * expression. + */ + template<typename _InputIterator> + basic_regex(_InputIterator __first, _InputIterator __last, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), _M_pattern(__first, __last), _M_mark_count(0) + { _M_compile(); } + +#ifdef _GLIBCXX_INCLUDE_AS_CXX0X + /** + * @brief Constructs a basic regular expression from an initializer list. + * + * @param l The initializer list. + * @param f The format flags of the regular expression. + * + * @throws regex_error if @p l is not a valid regular expression. + */ + basic_regex(initializer_list<_Ch_type> __l, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), _M_pattern(__l.begin(), __l.end()), _M_mark_count(0) + { _M_compile(); } +#endif + + /** + * @brief Destroys a basic regular expression. + */ + ~basic_regex() + { } + + /** + * @brief Assigns one regular expression to another. + */ + basic_regex& + operator=(const basic_regex& __rhs) + { return this->assign(__rhs); } + + /** + * @brief Replaces a regular expression with a new one constructed from + * a C-style null-terminated string. + * + * @param A pointer to the start of a null-terminated C-style string + * containing a regular expression. + */ + basic_regex& + operator=(const _Ch_type* __p) + { return this->assign(__p, flags()); } + + /** + * @brief Replaces a regular expression with a new one constructed from + * a string. + * + * @param A pointer to a string containing a regular expression. + */ + template<typename _Ch_typeraits, typename _Allocator> + basic_regex& + operator=(const basic_string<_Ch_type, _Ch_typeraits, _Allocator>& __s) + { return this->assign(__s, flags()); } + + // [7.8.3] assign + /** + * @brief the real assignment operator. + * + * @param that Another regular expression object. + */ + basic_regex& + assign(const basic_regex& __that) + { + basic_regex __tmp(__that); + this->swap(__tmp); + return *this; + } + + /** + * @brief Assigns a new regular expression to a regex object from a + * C-style null-terminated string containing a regular expression + * pattern. + * + * @param p A pointer to a C-style null-terminated string containing + * a regular expression pattern. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * *this remains unchanged. + */ + basic_regex& + assign(const _Ch_type* __p, + flag_type __flags = regex_constants::ECMAScript) + { return this->assign(string_type(__p), __flags); } + + /** + * @brief Assigns a new regular expression to a regex object from a + * C-style string containing a regular expression pattern. + * + * @param p A pointer to a C-style string containing a + * regular expression pattern. + * @param len The length of the regular expression pattern string. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * *this remains unchanged. + */ + basic_regex& + assign(const _Ch_type* __p, std::size_t __len, flag_type __flags) + { return this->assign(string_type(__p, __len), __flags); } + + /** + * @brief Assigns a new regular expression to a regex object from a + * string containing a regular expression pattern. + * + * @param s A string containing a regular expression pattern. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * *this remains unchanged. + */ + template<typename _Ch_typeraits, typename _Allocator> + basic_regex& + assign(const basic_string<_Ch_type, _Ch_typeraits, _Allocator>& __s, + flag_type __f = regex_constants::ECMAScript) + { + basic_regex __tmp(__s, __f); + this->swap(__tmp); + return *this; + } + + /** + * @brief Assigns a new regular expression to a regex object. + * + * @param first The start of a range containing a valid regular + * expression. + * @param last The end of a range containing a valid regular + * expression. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * the object remains unchanged. + */ + template<typename _InputIterator> + basic_regex& + assign(_InputIterator __first, _InputIterator __last, + flag_type __flags = regex_constants::ECMAScript) + { return this->assign(string_type(__first, __last), __flags); } + +#ifdef _GLIBCXX_INCLUDE_AS_CXX0X + /** + * @brief Assigns a new regular expression to a regex object. + * + * @param l An initializer list representing a regular expression. + * @param flags Syntax option flags. + * + * @throws regex_error if @p l does not contain a valid regular + * expression pattern interpreted according to @p flags. If regex_error + * is thrown, the object remains unchanged. + */ + basic_regex& + assign(initializer_list<_Ch_type> __l, + flag_type __f = regex_constants::ECMAScript) + { return this->assign(__l.begin(), __l.end(), __f); } +#endif + + // [7.8.4] const operations + /** + * @brief Gets the number of marked subexpressions within the regular + * expression. + */ + unsigned int + mark_count() const + { return _M_mark_count; } + + /** + * @brief Gets the flags used to construct the regular expression + * or in the last call to assign(). + */ + flag_type + flags() const + { return _M_flags; } + + // [7.8.5] locale + /** + * @brief Imbues the regular expression object with the given locale. + * + * @param loc A locale. + */ + locale_type + imbue(locale_type __loc) + { return _M_traits.imbue(__loc); } + + /** + * @brief Gets the locale currently imbued in the regular expression + * object. + */ + locale_type + getloc() const + { return _M_traits.getloc(); } + + // [7.8.6] swap + /** + * @brief Swaps the contents of two regular expression objects. + * + * @param rhs Another regular expression object. + */ + void + swap(basic_regex& __rhs) + { + std::swap(_M_flags, __rhs._M_flags); + std::swap(_M_pattern, __rhs._M_pattern); + std::swap(_M_mark_count, __rhs._M_mark_count); + std::swap(_M_traits, __rhs._M_traits); + } + + private: + /** + * @brief Compiles a regular expression pattern into a NFA. + * @todo Implement this function. + */ + void _M_compile(); + + protected: + flag_type _M_flags; + string_type _M_pattern; + unsigned int _M_mark_count; + _Rx_traits _M_traits; + }; + + /** @brief Standard regular expressions. */ + typedef basic_regex<char> regex; +#ifdef _GLIBCXX_USE_WCHAR_T + /** @brief Standard wide-character regular expressions. */ + typedef basic_regex<wchar_t> wregex; +#endif + + + // [7.8.6] basic_regex swap + /** + * @brief Swaps the contents of two regular expression objects. + * @param lhs First regular expression. + * @param rhs Second regular expression. + */ + template<typename _Ch_type, typename _Rx_traits> + inline void + swap(basic_regex<_Ch_type, _Rx_traits>& __lhs, + basic_regex<_Ch_type, _Rx_traits>& __rhs) + { __lhs.swap(__rhs); } + + + // [7.9] Class template sub_match + /** + * A sequence of characters matched by a particular marked sub-expression. + * + * An object of this class is essentially a pair of iterators marking a + * matched subexpression within a regular expression pattern match. Such + * objects can be converted to and compared with std::basic_string objects + * of a similar base character type as the pattern matched by the regular + * expression. + * + * The iterators that make up the pair are the usual half-open interval + * referencing the actual original pattern matched. + */ + template<typename _BiIter> + class sub_match : public std::pair<_BiIter, _BiIter> + { + public: + typedef typename iterator_traits<_BiIter>::value_type value_type; + typedef typename iterator_traits<_BiIter>::difference_type + difference_type; + typedef _BiIter iterator; + + public: + bool matched; + + /** + * Gets the length of the matching sequence. + */ + difference_type + length() const + { return this->matched ? std::distance(this->first, this->second) : 0; } + + /** + * @brief Gets the matching sequence as a string. + * + * @returns the matching sequence as a string. + * + * This is the implicit conversion operator. It is identical to the + * str() member function except that it will want to pop up in + * unexpected places and cause a great deal of confusion and cursing + * from the unwary. + */ + operator basic_string<value_type>() const + { + return this->matched + ? std::basic_string<value_type>(this->first, this->second) + : std::basic_string<value_type>(); + } + + /** + * @brief Gets the matching sequence as a string. + * + * @returns the matching sequence as a string. + */ + basic_string<value_type> + str() const + { + return this->matched + ? std::basic_string<value_type>(this->first, this->second) + : std::basic_string<value_type>(); + } + + /** + * @brief Compares this and another matched sequence. + * + * @param s Another matched sequence to compare to this one. + * + * @retval <0 this matched sequence will collate before @p s. + * @retval =0 this matched sequence is equivalent to @p s. + * @retval <0 this matched sequence will collate after @p s. + */ + int + compare(const sub_match& __s) const + { return this->str().compare(__s.str()); } + + /** + * @brief Compares this sub_match to a string. + * + * @param s A string to compare to this sub_match. + * + * @retval <0 this matched sequence will collate before @p s. + * @retval =0 this matched sequence is equivalent to @p s. + * @retval <0 this matched sequence will collate after @p s. + */ + int + compare(const basic_string<value_type>& __s) const + { return this->str().compare(__s); } + + /** + * @brief Compares this sub_match to a C-style string. + * + * @param s A C-style string to compare to this sub_match. + * + * @retval <0 this matched sequence will collate before @p s. + * @retval =0 this matched sequence is equivalent to @p s. + * @retval <0 this matched sequence will collate after @p s. + */ + int + compare(const value_type* __s) const + { return this->str().compare(__s); } + }; + + + /** @brief Standard regex submatch over a C-style null-terminated string. */ + typedef sub_match<const char*> csub_match; + /** @brief Standard regex submatch over a standard string. */ + typedef sub_match<string::const_iterator> ssub_match; +#ifdef _GLIBCXX_USE_WCHAR_T + /** @brief Regex submatch over a C-style null-terminated wide string. */ + typedef sub_match<const wchar_t*> wcsub_match; + /** @brief Regex submatch over a standard wide string. */ + typedef sub_match<wstring::const_iterator> wssub_match; +#endif + + // [7.9.2] sub_match non-member operators + + /** + * @brief Tests the equivalence of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator==(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + /** + * @brief Tests the inequivalence of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator!=(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) != 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator<(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator<=(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator>=(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator>(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Tests the equivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator==(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs == __rhs.str(); } + + /** + * @brief Tests the inequivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator!=(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs != __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator<(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs < __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator>(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs > __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator>=(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs >= __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator<=(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs <= __rhs.str(); } + + /** + * @brief Tests the equivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator==(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() == __rhs; } + + /** + * @brief Tests the inequivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator!=(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() != __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator<(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() < __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator>(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() > __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator>=(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() >= __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator<=(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() <= __rhs; } + + /** + * @brief Tests the equivalence of a C string and a regular expression + * submatch. + * @param lhs A C string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs == __rhs.str(); } + + /** + * @brief Tests the inequivalence of an iterator value and a regular + * expression submatch. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs != __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs < __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs > __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs >= __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs <= __rhs.str(); } + + /** + * @brief Tests the equivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A pointer to a string? + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() == __rhs; } + + /** + * @brief Tests the inequivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A pointer to a string. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() != __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() < __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() > __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() >= __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() <= __rhs; } + + /** + * @brief Tests the equivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs == __rhs.str(); } + + /** + * @brief Tests the inequivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs != __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs < __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs > __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs >= __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs <= __rhs.str(); } + + /** + * @brief Tests the equivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() == __rhs; } + + /** + * @brief Tests the inequivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() != __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() < __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() > __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() >= __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() <= __rhs; } + + /** + * @brief Inserts a matched string into an output stream. + * + * @param os The output stream. + * @param m A submatch string. + * + * @returns the output stream with the submatch string inserted. + */ + template<typename _Ch_type, typename _Ch_traits, typename _Bi_iter> + inline + basic_ostream<_Ch_type, _Ch_traits>& + operator<<(basic_ostream<_Ch_type, _Ch_traits>& __os, + const sub_match<_Bi_iter>& __m) + { return __os << __m.str(); } + + // [7.10] Class template match_results + /** + * @brief The results of a match or search operation. + * + * A collection of character sequences representing the result of a regular + * expression match. Storage for the collection is allocated and freed as + * necessary by the member functions of class template match_results. + * + * This class satisfies the Sequence requirements, with the exception that + * only the operations defined for a const-qualified Sequence are supported. + * + * The sub_match object stored at index 0 represents sub-expression 0, i.e. + * the whole match. In this case the sub_match member matched is always true. + * The sub_match object stored at index n denotes what matched the marked + * sub-expression n within the matched expression. If the sub-expression n + * participated in a regular expression match then the sub_match member + * matched evaluates to true, and members first and second denote the range + * of characters [first, second) which formed that match. Otherwise matched + * is false, and members first and second point to the end of the sequence + * that was searched. + * + * @nosubgrouping + */ + template<typename _Bi_iter, + typename _Allocator = allocator<sub_match<_Bi_iter> > > + class match_results + : private std::vector<std::tr1::sub_match<_Bi_iter>, _Allocator> + { + private: + typedef std::vector<std::tr1::sub_match<_Bi_iter>, _Allocator> + _Base_type; + + public: + /** + * @name 10.? Public Types + */ + //@{ + typedef sub_match<_Bi_iter> value_type; + typedef typename _Allocator::const_reference const_reference; + typedef const_reference reference; + typedef typename _Base_type::const_iterator const_iterator; + typedef const_iterator iterator; + typedef typename iterator_traits<_Bi_iter>::difference_type + difference_type; + typedef typename _Allocator::size_type size_type; + typedef _Allocator allocator_type; + typedef typename iterator_traits<_Bi_iter>::value_type char_type; + typedef basic_string<char_type> string_type; + //@} + + public: + /** + * @name 10.1 Construction, Copying, and Destruction + */ + //@{ + + /** + * @brief Constructs a default %match_results container. + * @post size() returns 0 and str() returns an empty string. + */ + explicit + match_results(const _Allocator& __a = _Allocator()) + : _Base_type(__a), _M_matched(false) + { } + + /** + * @brief Copy constructs a %match_results. + */ + match_results(const match_results& __rhs) + : _Base_type(__rhs), _M_matched(__rhs._M_matched), + _M_prefix(__rhs._M_prefix), _M_suffix(__rhs._M_suffix) + { } + + /** + * @brief Assigns rhs to *this. + */ + match_results& + operator=(const match_results& __rhs) + { + match_results __tmp(__rhs); + this->swap(__tmp); + return *this; + } + + /** + * @brief Destroys a %match_results object. + */ + ~match_results() + { } + + //@} + + /** + * @name 10.2 Size + */ + //@{ + + /** + * @brief Gets the number of matches and submatches. + * + * The number of matches for a given regular expression will be either 0 + * if there was no match or mark_count() + 1 if a match was successful. + * Some matches may be empty. + * + * @returns the number of matches found. + */ + size_type + size() const + { return _M_matched ? _Base_type::size() + 1 : 0; } + + //size_type + //max_size() const; + using _Base_type::max_size; + + /** + * @brief Indicates if the %match_results contains no results. + * @retval true The %match_results object is empty. + * @retval false The %match_results object is not empty. + */ + bool + empty() const + { return size() == 0; } + + //@} + + /** + * @name 10.3 Element Access + */ + //@{ + + /** + * @brief Gets the length of the indicated submatch. + * @param sub indicates the submatch. + * + * This function returns the length of the indicated submatch, or the + * length of the entire match if @p sub is zero (the default). + */ + difference_type + length(size_type __sub = 0) const + { return _M_matched ? this->str(__sub).length() : 0; } + + /** + * @brief Gets the offset of the beginning of the indicated submatch. + * @param sub indicates the submatch. + * + * This function returns the offset from the beginning of the target + * sequence to the beginning of the submatch, unless the value of @p sub + * is zero (the default), in which case this function returns the offset + * from the beginning of the target sequence to the beginning of the + * match. + */ + difference_type + position(size_type __sub = 0) const + { + return _M_matched ? std::distance(this->prefix().first, + (*this)[__sub].first) : 0; + } + + /** + * @brief Gets the match or submatch converted to a string type. + * @param sub indicates the submatch. + * + * This function gets the submatch (or match, if @p sub is zero) extracted + * from the target range and converted to the associated string type. + */ + string_type + str(size_type __sub = 0) const + { return _M_matched ? (*this)[__sub].str() : string_type(); } + + /** + * @brief Gets a %sub_match reference for the match or submatch. + * @param sub indicates the submatch. + * + * This function gets a reference to the indicated submatch, or the entire + * match if @p sub is zero. + * + * If @p sub >= size() then this function returns a %sub_match with a + * special value indicating no submatch. + */ + const_reference + operator[](size_type __sub) const + { return _Base_type::operator[](__sub); } + + /** + * @brief Gets a %sub_match representing the match prefix. + * + * This function gets a reference to a %sub_match object representing the + * part of the target range between the start of the target range and the + * start of the match. + */ + const_reference + prefix() const + { return _M_prefix; } + + /** + * @brief Gets a %sub_match representing the match suffix. + * + * This function gets a reference to a %sub_match object representing the + * part of the target range between the end of the match and the end of + * the target range. + */ + const_reference + suffix() const + { return _M_suffix; } + + /** + * @brief Gets an iterator to the start of the %sub_match collection. + */ + const_iterator + begin() const + { return _Base_type::begin(); } + +#ifdef _GLIBCXX_INCLUDE_AS_CXX0X + /** + * @brief Gets an iterator to the start of the %sub_match collection. + */ + const_iterator + cbegin() const + { return _Base_type::begin(); } +#endif + + /** + * @brief Gets an iterator to one-past-the-end of the collection. + */ + const_iterator + end() const + { return _Base_type::end(); } + +#ifdef _GLIBCXX_INCLUDE_AS_CXX0X + /** + * @brief Gets an iterator to one-past-the-end of the collection. + */ + const_iterator + cend() const + { return _Base_type::end(); } +#endif + + //@} + + /** + * @name 10.4 Formatting + * + * These functions perform formatted substitution of the matched + * character sequences into their target. The format specifiers + * and escape sequences accepted by these functions are + * determined by their @p flags parameter as documented above. + */ + //@{ + + /** + * @todo Implement this function. + */ + template<typename _Out_iter> + _Out_iter + format(_Out_iter __out, const string_type& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::format_default) const; + + /** + * @todo Implement this function. + */ + string_type + format(const string_type& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::format_default) const; + + //@} + + /** + * @name 10.5 Allocator + */ + //@{ + + /** + * @brief Gets a copy of the allocator. + */ + //allocator_type + //get_allocator() const; + using _Base_type::get_allocator; + + //@} + + /** + * @name 10.6 Swap + */ + //@{ + + /** + * @brief Swaps the contents of two match_results. + */ + void + swap(match_results& __that) + { + _Base_type::swap(__that); + std::swap(_M_matched, __that._M_matched); + std::swap(_M_prefix, __that._M_prefix); + std::swap(_M_suffix, __that._M_suffix); + } + //@} + + private: + bool _M_matched; + value_type _M_prefix; + value_type _M_suffix; + }; + + typedef match_results<const char*> cmatch; + typedef match_results<string::const_iterator> smatch; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef match_results<const wchar_t*> wcmatch; + typedef match_results<wstring::const_iterator> wsmatch; +#endif + + // match_results comparisons + /** + * @brief Compares two match_results for equality. + * @returns true if the two objects refer to the same match, + * false otherwise. + * @todo Implement this function. + */ + template<typename _Bi_iter, typename _Allocator> + inline bool + operator==(const match_results<_Bi_iter, _Allocator>& __m1, + const match_results<_Bi_iter, _Allocator>& __m2); + + /** + * @brief Compares two match_results for inequality. + * @returns true if the two objects do not refer to the same match, + * false otherwise. + */ + template<typename _Bi_iter, class _Allocator> + inline bool + operator!=(const match_results<_Bi_iter, _Allocator>& __m1, + const match_results<_Bi_iter, _Allocator>& __m2) + { return !(__m1 == __m2); } + + // [7.10.6] match_results swap + /** + * @brief Swaps two match results. + * @param lhs A match result. + * @param rhs A match result. + * + * The contents of the two match_results objects are swapped. + */ + template<typename _Bi_iter, typename _Allocator> + inline void + swap(match_results<_Bi_iter, _Allocator>& __lhs, + match_results<_Bi_iter, _Allocator>& __rhs) + { __lhs.swap(__rhs); } + + // [7.11.2] Function template regex_match + /** + * @name Matching, Searching, and Replacing + */ + //@{ + + /** + * @brief Determines if there is a match between the regular expression @p e + * and all of the character sequence [first, last). + * + * @param first Beginning of the character sequence to match. + * @param last One-past-the-end of the character sequence to match. + * @param m The match results. + * @param re The regular expression. + * @param flags Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + * + * @todo Implement this function. + */ + template<typename _Bi_iter, typename _Allocator, + typename _Ch_type, typename _Rx_traits> + bool + regex_match(_Bi_iter __first, _Bi_iter __last, + match_results<_Bi_iter, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default); + + /** + * @brief Indicates if there is a match between the regular expression @p e + * and all of the character sequence [first, last). + * + * @param first Beginning of the character sequence to match. + * @param last One-past-the-end of the character sequence to match. + * @param re The regular expression. + * @param flags Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> + bool + regex_match(_Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return regex_match(__first, __last, __what, __re, __flags); + } + + /** + * @brief Determines if there is a match between the regular expression @p e + * and a C-style null-terminated string. + * + * @param s The C-style null-terminated string to match. + * @param m The match results. + * @param re The regular expression. + * @param f Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, typename _Allocator, typename _Rx_traits> + inline bool + regex_match(const _Ch_type* __s, + match_results<const _Ch_type*, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_match(__s, __s + _Rx_traits::length(__s), __m, __re, __f); } + + /** + * @brief Determines if there is a match between the regular expression @p e + * and a string. + * + * @param s The string to match. + * @param m The match results. + * @param re The regular expression. + * @param flags Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _Ch_alloc, + typename _Allocator, typename _Ch_type, typename _Rx_traits> + inline bool + regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, + match_results<typename basic_string<_Ch_type, + _Ch_traits, _Ch_alloc>::const_iterator, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return regex_match(__s.begin(), __s.end(), __m, __re, __flags); } + + /** + * @brief Indicates if there is a match between the regular expression @p e + * and a C-style null-terminated string. + * + * @param s The C-style null-terminated string to match. + * @param re The regular expression. + * @param f Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, class _Rx_traits> + inline bool + regex_match(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_match(__s, __s + _Rx_traits::length(__s), __re, __f); } + + /** + * @brief Indicates if there is a match between the regular expression @p e + * and a string. + * + * @param s [IN] The string to match. + * @param re [IN] The regular expression. + * @param flags [IN] Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _Str_allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_match(const basic_string<_Ch_type, _Ch_traits, _Str_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return regex_match(__s.begin(), __s.end(), __re, __flags); } + + // [7.11.3] Function template regex_search + /** + * Searches for a regular expression within a range. + * @param first [IN] The start of the string to search. + * @param last [IN] One-past-the-end of the string to search. + * @param m [OUT] The match results. + * @param re [IN] The regular expression to search for. + * @param flags [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string, the content of %m is + * undefined. + * + * @throws an exception of type regex_error. + * + * @todo Implement this function. + */ + template<typename _Bi_iter, typename _Allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(_Bi_iter __first, _Bi_iter __last, + match_results<_Bi_iter, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default); + + /** + * Searches for a regular expression within a range. + * @param first [IN] The start of the string to search. + * @param last [IN] One-past-the-end of the string to search. + * @param re [IN] The regular expression to search for. + * @param flags [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(_Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return regex_search(__first, __last, __what, __re, __flags); + } + + /** + * @brief Searches for a regular expression within a C-string. + * @param s [IN] A C-string to search for the regex. + * @param m [OUT] The set of regex matches. + * @param e [IN] The regex to search for in @p s. + * @param f [IN] The search flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string, the content of %m is + * undefined. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, class _Allocator, class _Rx_traits> + inline bool + regex_search(const _Ch_type* __s, + match_results<const _Ch_type*, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_search(__s, __s + _Rx_traits::length(__s), __m, __e, __f); } + + /** + * @brief Searches for a regular expression within a C-string. + * @param s [IN] The C-string to search. + * @param e [IN] The regular expression to search for. + * @param f [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_search(__s, __s + _Rx_traits::length(__s), __e, __f); } + + /** + * @brief Searches for a regular expression within a string. + * @param s [IN] The string to search. + * @param e [IN] The regular expression to search for. + * @param flags [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _String_allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(const basic_string<_Ch_type, _Ch_traits, + _String_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return regex_search(__s.begin(), __s.end(), __e, __flags); } + + /** + * @brief Searches for a regular expression within a string. + * @param s [IN] A C++ string to search for the regex. + * @param m [OUT] The set of regex matches. + * @param e [IN] The regex to search for in @p s. + * @param f [IN] The search flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string, the content of %m is + * undefined. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _Ch_alloc, + typename _Allocator, typename _Ch_type, + typename _Rx_traits> + inline bool + regex_search(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, + match_results<typename basic_string<_Ch_type, + _Ch_traits, _Ch_alloc>::const_iterator, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_search(__s.begin(), __s.end(), __m, __e, __f); } + + // tr1 [7.11.4] std [28.11.4] Function template regex_replace + /** + * @doctodo + * @param out + * @param first + * @param last + * @param e + * @param fmt + * @param flags + * + * @returns out + * @throws an exception of type regex_error. + * + * @todo Implement this function. + */ + template<typename _Out_iter, typename _Bi_iter, + typename _Rx_traits, typename _Ch_type> + inline _Out_iter + regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const basic_string<_Ch_type>& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default); + + /** + * @doctodo + * @param s + * @param e + * @param fmt + * @param flags + * + * @returns a copy of string @p s with replacements. + * + * @throws an exception of type regex_error. + */ + template<typename _Rx_traits, typename _Ch_type> + inline basic_string<_Ch_type> + regex_replace(const basic_string<_Ch_type>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const basic_string<_Ch_type>& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + std::string __result; + regex_replace(std::back_inserter(__result), + __s.begin(), __s.end(), __e, __fmt, __flags); + return __result; + } + + //@} + + // tr1 [7.12.1] std [28.12] Class template regex_iterator + /** + * An iterator adaptor that will provide repeated calls of regex_search over + * a range until no more matches remain. + */ + template<typename _Bi_iter, + typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type, + typename _Rx_traits = regex_traits<_Ch_type> > + class regex_iterator + { + public: + typedef basic_regex<_Ch_type, _Rx_traits> regex_type; + typedef match_results<_Bi_iter> value_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + public: + /** + * @brief Provides a singular iterator, useful for indicating + * one-past-the-end of a range. + * @todo Implement this function. + * @doctodo + */ + regex_iterator(); + + /** + * Constructs a %regex_iterator... + * @param a [IN] The start of a text range to search. + * @param b [IN] One-past-the-end of the text range to search. + * @param re [IN] The regular expression to match. + * @param m [IN] Policy flags for match rules. + * @todo Implement this function. + * @doctodo + */ + regex_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * Copy constructs a %regex_iterator. + * @todo Implement this function. + * @doctodo + */ + regex_iterator(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + regex_iterator& + operator=(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + bool + operator==(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + bool + operator!=(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + const value_type& + operator*(); + + /** + * @todo Implement this function. + * @doctodo + */ + const value_type* + operator->(); + + /** + * @todo Implement this function. + * @doctodo + */ + regex_iterator& + operator++(); + + /** + * @todo Implement this function. + * @doctodo + */ + regex_iterator + operator++(int); + + private: + // these members are shown for exposition only: + _Bi_iter begin; + _Bi_iter end; + const regex_type* pregex; + regex_constants::match_flag_type flags; + match_results<_Bi_iter> match; + }; + + typedef regex_iterator<const char*> cregex_iterator; + typedef regex_iterator<string::const_iterator> sregex_iterator; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef regex_iterator<const wchar_t*> wcregex_iterator; + typedef regex_iterator<wstring::const_iterator> wsregex_iterator; +#endif + + // [7.12.2] Class template regex_token_iterator + /** + * Iterates over submatches in a range (or @a splits a text string). + * + * The purpose of this iterator is to enumerate all, or all specified, + * matches of a regular expression within a text range. The dereferenced + * value of an iterator of this class is a std::tr1::sub_match object. + */ + template<typename _Bi_iter, + typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type, + typename _Rx_traits = regex_traits<_Ch_type> > + class regex_token_iterator + { + public: + typedef basic_regex<_Ch_type, _Rx_traits> regex_type; + typedef sub_match<_Bi_iter> value_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + public: + /** + * @brief Default constructs a %regex_token_iterator. + * @todo Implement this function. + * + * A default-constructed %regex_token_iterator is a singular iterator + * that will compare equal to the one-past-the-end value for any + * iterator of the same type. + */ + regex_token_iterator(); + + /** + * Constructs a %regex_token_iterator... + * @param a [IN] The start of the text to search. + * @param b [IN] One-past-the-end of the text to search. + * @param re [IN] The regular expression to search for. + * @param submatch [IN] Which submatch to return. There are some + * special values for this parameter: + * - -1 each enumerated subexpression does NOT + * match the regular expression (aka field + * splitting) + * - 0 the entire string matching the + * subexpression is returned for each match + * within the text. + * - >0 enumerates only the indicated + * subexpression from a match within the text. + * @param m [IN] Policy flags for match rules. + * + * @todo Implement this function. + * @doctodo + */ + regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, + int __submatch = 0, + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * Constructs a %regex_token_iterator... + * @param a [IN] The start of the text to search. + * @param b [IN] One-past-the-end of the text to search. + * @param re [IN] The regular expression to search for. + * @param submatches [IN] A list of subexpressions to return for each + * regular expression match within the text. + * @param m [IN] Policy flags for match rules. + * + * @todo Implement this function. + * @doctodo + */ + regex_token_iterator(_Bi_iter __a, _Bi_iter __b, + const regex_type& __re, + const std::vector<int>& __submatches, + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * Constructs a %regex_token_iterator... + * @param a [IN] The start of the text to search. + * @param b [IN] One-past-the-end of the text to search. + * @param re [IN] The regular expression to search for. + * @param submatches [IN] A list of subexpressions to return for each + * regular expression match within the text. + * @param m [IN] Policy flags for match rules. + + * @todo Implement this function. + * @doctodo + */ + template<std::size_t _Nm> + regex_token_iterator(_Bi_iter __a, _Bi_iter __b, + const regex_type& __re, + const int (&__submatches)[_Nm], + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * @brief Copy constructs a %regex_token_iterator. + * @param rhs [IN] A %regex_token_iterator to copy. + * @todo Implement this function. + */ + regex_token_iterator(const regex_token_iterator& __rhs); + + /** + * @brief Assigns a %regex_token_iterator to another. + * @param rhs [IN] A %regex_token_iterator to copy. + * @todo Implement this function. + */ + regex_token_iterator& + operator=(const regex_token_iterator& __rhs); + + /** + * @brief Compares a %regex_token_iterator to another for equality. + * @todo Implement this function. + */ + bool + operator==(const regex_token_iterator& __rhs); + + /** + * @brief Compares a %regex_token_iterator to another for inequality. + * @todo Implement this function. + */ + bool + operator!=(const regex_token_iterator& __rhs); + + /** + * @brief Dereferences a %regex_token_iterator. + * @todo Implement this function. + */ + const value_type& + operator*(); + + /** + * @brief Selects a %regex_token_iterator member. + * @todo Implement this function. + */ + const value_type* + operator->(); + + /** + * @brief Increments a %regex_token_iterator. + * @todo Implement this function. + */ + regex_token_iterator& + operator++(); + + /** + * @brief Postincrements a %regex_token_iterator. + * @todo Implement this function. + */ + regex_token_iterator + operator++(int); + + private: // data members for exposition only: + typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> position_iterator; + + position_iterator __position; + const value_type* __result; + value_type __suffix; + std::size_t __n; + std::vector<int> __subs; + }; + + /** @brief Token iterator for C-style NULL-terminated strings. */ + typedef regex_token_iterator<const char*> cregex_token_iterator; + /** @brief Token iterator for standard strings. */ + typedef regex_token_iterator<string::const_iterator> sregex_token_iterator; +#ifdef _GLIBCXX_USE_WCHAR_T + /** @brief Token iterator for C-style NULL-terminated wide strings. */ + typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator; + /** @brief Token iterator for standard wide-character strings. */ + typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; +#endif + + //@} + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_REGEX diff --git a/libstdc++-v3/include/tr1/riemann_zeta.tcc b/libstdc++-v3/include/tr1/riemann_zeta.tcc new file mode 100644 index 000000000..18fe20ed8 --- /dev/null +++ b/libstdc++-v3/include/tr1/riemann_zeta.tcc @@ -0,0 +1,436 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/riemann_zeta.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on: +// (1) Handbook of Mathematical Functions, +// Ed. by Milton Abramowitz and Irene A. Stegun, +// Dover Publications, New-York, Section 5, pp. 807-808. +// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl +// (3) Gamma, Exploring Euler's Constant, Julian Havil, +// Princeton, 2003. + +#ifndef _GLIBCXX_TR1_RIEMANN_ZETA_TCC +#define _GLIBCXX_TR1_RIEMANN_ZETA_TCC 1 + +#include "special_function_util.h" + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + // [5.2] Special functions + + // Implementation-space details. + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Compute the Riemann zeta function @f$ \zeta(s) @f$ + * by summation for s > 1. + * + * The Riemann zeta function is defined by: + * \f[ + * \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1 + * \f] + * For s < 1 use the reflection formula: + * \f[ + * \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s) + * \f] + */ + template<typename _Tp> + _Tp + __riemann_zeta_sum(const _Tp __s) + { + // A user shouldn't get to this. + if (__s < _Tp(1)) + std::__throw_domain_error(__N("Bad argument in zeta sum.")); + + const unsigned int max_iter = 10000; + _Tp __zeta = _Tp(0); + for (unsigned int __k = 1; __k < max_iter; ++__k) + { + _Tp __term = std::pow(static_cast<_Tp>(__k), -__s); + if (__term < std::numeric_limits<_Tp>::epsilon()) + { + break; + } + __zeta += __term; + } + + return __zeta; + } + + + /** + * @brief Evaluate the Riemann zeta function @f$ \zeta(s) @f$ + * by an alternate series for s > 0. + * + * The Riemann zeta function is defined by: + * \f[ + * \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1 + * \f] + * For s < 1 use the reflection formula: + * \f[ + * \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s) + * \f] + */ + template<typename _Tp> + _Tp + __riemann_zeta_alt(const _Tp __s) + { + _Tp __sgn = _Tp(1); + _Tp __zeta = _Tp(0); + for (unsigned int __i = 1; __i < 10000000; ++__i) + { + _Tp __term = __sgn / std::pow(__i, __s); + if (std::abs(__term) < std::numeric_limits<_Tp>::epsilon()) + break; + __zeta += __term; + __sgn *= _Tp(-1); + } + __zeta /= _Tp(1) - std::pow(_Tp(2), _Tp(1) - __s); + + return __zeta; + } + + + /** + * @brief Evaluate the Riemann zeta function by series for all s != 1. + * Convergence is great until largish negative numbers. + * Then the convergence of the > 0 sum gets better. + * + * The series is: + * \f[ + * \zeta(s) = \frac{1}{1-2^{1-s}} + * \sum_{n=0}^{\infty} \frac{1}{2^{n+1}} + * \sum_{k=0}^{n} (-1)^k \frac{n!}{(n-k)!k!} (k+1)^{-s} + * \f] + * Havil 2003, p. 206. + * + * The Riemann zeta function is defined by: + * \f[ + * \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1 + * \f] + * For s < 1 use the reflection formula: + * \f[ + * \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s) + * \f] + */ + template<typename _Tp> + _Tp + __riemann_zeta_glob(const _Tp __s) + { + _Tp __zeta = _Tp(0); + + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + // Max e exponent before overflow. + const _Tp __max_bincoeff = std::numeric_limits<_Tp>::max_exponent10 + * std::log(_Tp(10)) - _Tp(1); + + // This series works until the binomial coefficient blows up + // so use reflection. + if (__s < _Tp(0)) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + if (std::tr1::fmod(__s,_Tp(2)) == _Tp(0)) + return _Tp(0); + else +#endif + { + _Tp __zeta = __riemann_zeta_glob(_Tp(1) - __s); + __zeta *= std::pow(_Tp(2) + * __numeric_constants<_Tp>::__pi(), __s) + * std::sin(__numeric_constants<_Tp>::__pi_2() * __s) +#if _GLIBCXX_USE_C99_MATH_TR1 + * std::exp(std::tr1::lgamma(_Tp(1) - __s)) +#else + * std::exp(__log_gamma(_Tp(1) - __s)) +#endif + / __numeric_constants<_Tp>::__pi(); + return __zeta; + } + } + + _Tp __num = _Tp(0.5L); + const unsigned int __maxit = 10000; + for (unsigned int __i = 0; __i < __maxit; ++__i) + { + bool __punt = false; + _Tp __sgn = _Tp(1); + _Tp __term = _Tp(0); + for (unsigned int __j = 0; __j <= __i; ++__j) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + _Tp __bincoeff = std::tr1::lgamma(_Tp(1 + __i)) + - std::tr1::lgamma(_Tp(1 + __j)) + - std::tr1::lgamma(_Tp(1 + __i - __j)); +#else + _Tp __bincoeff = __log_gamma(_Tp(1 + __i)) + - __log_gamma(_Tp(1 + __j)) + - __log_gamma(_Tp(1 + __i - __j)); +#endif + if (__bincoeff > __max_bincoeff) + { + // This only gets hit for x << 0. + __punt = true; + break; + } + __bincoeff = std::exp(__bincoeff); + __term += __sgn * __bincoeff * std::pow(_Tp(1 + __j), -__s); + __sgn *= _Tp(-1); + } + if (__punt) + break; + __term *= __num; + __zeta += __term; + if (std::abs(__term/__zeta) < __eps) + break; + __num *= _Tp(0.5L); + } + + __zeta /= _Tp(1) - std::pow(_Tp(2), _Tp(1) - __s); + + return __zeta; + } + + + /** + * @brief Compute the Riemann zeta function @f$ \zeta(s) @f$ + * using the product over prime factors. + * \f[ + * \zeta(s) = \Pi_{i=1}^\infty \frac{1}{1 - p_i^{-s}} + * \f] + * where @f$ {p_i} @f$ are the prime numbers. + * + * The Riemann zeta function is defined by: + * \f[ + * \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1 + * \f] + * For s < 1 use the reflection formula: + * \f[ + * \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s) + * \f] + */ + template<typename _Tp> + _Tp + __riemann_zeta_product(const _Tp __s) + { + static const _Tp __prime[] = { + _Tp(2), _Tp(3), _Tp(5), _Tp(7), _Tp(11), _Tp(13), _Tp(17), _Tp(19), + _Tp(23), _Tp(29), _Tp(31), _Tp(37), _Tp(41), _Tp(43), _Tp(47), + _Tp(53), _Tp(59), _Tp(61), _Tp(67), _Tp(71), _Tp(73), _Tp(79), + _Tp(83), _Tp(89), _Tp(97), _Tp(101), _Tp(103), _Tp(107), _Tp(109) + }; + static const unsigned int __num_primes = sizeof(__prime) / sizeof(_Tp); + + _Tp __zeta = _Tp(1); + for (unsigned int __i = 0; __i < __num_primes; ++__i) + { + const _Tp __fact = _Tp(1) - std::pow(__prime[__i], -__s); + __zeta *= __fact; + if (_Tp(1) - __fact < std::numeric_limits<_Tp>::epsilon()) + break; + } + + __zeta = _Tp(1) / __zeta; + + return __zeta; + } + + + /** + * @brief Return the Riemann zeta function @f$ \zeta(s) @f$. + * + * The Riemann zeta function is defined by: + * \f[ + * \zeta(s) = \sum_{k=1}^{\infty} k^{-s} for s > 1 + * \frac{(2\pi)^s}{pi} sin(\frac{\pi s}{2}) + * \Gamma (1 - s) \zeta (1 - s) for s < 1 + * \f] + * For s < 1 use the reflection formula: + * \f[ + * \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s) + * \f] + */ + template<typename _Tp> + _Tp + __riemann_zeta(const _Tp __s) + { + if (__isnan(__s)) + return std::numeric_limits<_Tp>::quiet_NaN(); + else if (__s == _Tp(1)) + return std::numeric_limits<_Tp>::infinity(); + else if (__s < -_Tp(19)) + { + _Tp __zeta = __riemann_zeta_product(_Tp(1) - __s); + __zeta *= std::pow(_Tp(2) * __numeric_constants<_Tp>::__pi(), __s) + * std::sin(__numeric_constants<_Tp>::__pi_2() * __s) +#if _GLIBCXX_USE_C99_MATH_TR1 + * std::exp(std::tr1::lgamma(_Tp(1) - __s)) +#else + * std::exp(__log_gamma(_Tp(1) - __s)) +#endif + / __numeric_constants<_Tp>::__pi(); + return __zeta; + } + else if (__s < _Tp(20)) + { + // Global double sum or McLaurin? + bool __glob = true; + if (__glob) + return __riemann_zeta_glob(__s); + else + { + if (__s > _Tp(1)) + return __riemann_zeta_sum(__s); + else + { + _Tp __zeta = std::pow(_Tp(2) + * __numeric_constants<_Tp>::__pi(), __s) + * std::sin(__numeric_constants<_Tp>::__pi_2() * __s) +#if _GLIBCXX_USE_C99_MATH_TR1 + * std::tr1::tgamma(_Tp(1) - __s) +#else + * std::exp(__log_gamma(_Tp(1) - __s)) +#endif + * __riemann_zeta_sum(_Tp(1) - __s); + return __zeta; + } + } + } + else + return __riemann_zeta_product(__s); + } + + + /** + * @brief Return the Hurwitz zeta function @f$ \zeta(x,s) @f$ + * for all s != 1 and x > -1. + * + * The Hurwitz zeta function is defined by: + * @f[ + * \zeta(x,s) = \sum_{n=0}^{\infty} \frac{1}{(n + x)^s} + * @f] + * The Riemann zeta function is a special case: + * @f[ + * \zeta(s) = \zeta(1,s) + * @f] + * + * This functions uses the double sum that converges for s != 1 + * and x > -1: + * @f[ + * \zeta(x,s) = \frac{1}{s-1} + * \sum_{n=0}^{\infty} \frac{1}{n + 1} + * \sum_{k=0}^{n} (-1)^k \frac{n!}{(n-k)!k!} (x+k)^{-s} + * @f] + */ + template<typename _Tp> + _Tp + __hurwitz_zeta_glob(const _Tp __a, const _Tp __s) + { + _Tp __zeta = _Tp(0); + + const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); + // Max e exponent before overflow. + const _Tp __max_bincoeff = std::numeric_limits<_Tp>::max_exponent10 + * std::log(_Tp(10)) - _Tp(1); + + const unsigned int __maxit = 10000; + for (unsigned int __i = 0; __i < __maxit; ++__i) + { + bool __punt = false; + _Tp __sgn = _Tp(1); + _Tp __term = _Tp(0); + for (unsigned int __j = 0; __j <= __i; ++__j) + { +#if _GLIBCXX_USE_C99_MATH_TR1 + _Tp __bincoeff = std::tr1::lgamma(_Tp(1 + __i)) + - std::tr1::lgamma(_Tp(1 + __j)) + - std::tr1::lgamma(_Tp(1 + __i - __j)); +#else + _Tp __bincoeff = __log_gamma(_Tp(1 + __i)) + - __log_gamma(_Tp(1 + __j)) + - __log_gamma(_Tp(1 + __i - __j)); +#endif + if (__bincoeff > __max_bincoeff) + { + // This only gets hit for x << 0. + __punt = true; + break; + } + __bincoeff = std::exp(__bincoeff); + __term += __sgn * __bincoeff * std::pow(_Tp(__a + __j), -__s); + __sgn *= _Tp(-1); + } + if (__punt) + break; + __term /= _Tp(__i + 1); + if (std::abs(__term / __zeta) < __eps) + break; + __zeta += __term; + } + + __zeta /= __s - _Tp(1); + + return __zeta; + } + + + /** + * @brief Return the Hurwitz zeta function @f$ \zeta(x,s) @f$ + * for all s != 1 and x > -1. + * + * The Hurwitz zeta function is defined by: + * @f[ + * \zeta(x,s) = \sum_{n=0}^{\infty} \frac{1}{(n + x)^s} + * @f] + * The Riemann zeta function is a special case: + * @f[ + * \zeta(s) = \zeta(1,s) + * @f] + */ + template<typename _Tp> + inline _Tp + __hurwitz_zeta(const _Tp __a, const _Tp __s) + { + return __hurwitz_zeta_glob(__a, __s); + } + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace std::tr1::__detail +} +} + +#endif // _GLIBCXX_TR1_RIEMANN_ZETA_TCC diff --git a/libstdc++-v3/include/tr1/shared_ptr.h b/libstdc++-v3/include/tr1/shared_ptr.h new file mode 100644 index 000000000..c42084c95 --- /dev/null +++ b/libstdc++-v3/include/tr1/shared_ptr.h @@ -0,0 +1,1179 @@ +// <tr1/shared_ptr.h> -*- C++ -*- + +// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// shared_count.hpp +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. + +// shared_ptr.hpp +// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. +// Copyright (C) 2001, 2002, 2003 Peter Dimov + +// weak_ptr.hpp +// Copyright (C) 2001, 2002, 2003 Peter Dimov + +// enable_shared_from_this.hpp +// Copyright (C) 2002 Peter Dimov + +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// GCC Note: based on version 1.32.0 of the Boost library. + +/** @file tr1/shared_ptr.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/memory} + */ + +#ifndef _TR1_SHARED_PTR_H +#define _TR1_SHARED_PTR_H 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Exception possibly thrown by @c shared_ptr. + * @ingroup exceptions + */ + class bad_weak_ptr : public std::exception + { + public: + virtual char const* + what() const throw() + { return "tr1::bad_weak_ptr"; } + }; + + // Substitute for bad_weak_ptr object in the case of -fno-exceptions. + inline void + __throw_bad_weak_ptr() + { +#if __EXCEPTIONS + throw bad_weak_ptr(); +#else + __builtin_abort(); +#endif + } + + using __gnu_cxx::_Lock_policy; + using __gnu_cxx::__default_lock_policy; + using __gnu_cxx::_S_single; + using __gnu_cxx::_S_mutex; + using __gnu_cxx::_S_atomic; + + // Empty helper class except when the template argument is _S_mutex. + template<_Lock_policy _Lp> + class _Mutex_base + { + protected: + // The atomic policy uses fully-fenced builtins, single doesn't care. + enum { _S_need_barriers = 0 }; + }; + + template<> + class _Mutex_base<_S_mutex> + : public __gnu_cxx::__mutex + { + protected: + // This policy is used when atomic builtins are not available. + // The replacement atomic operations might not have the necessary + // memory barriers. + enum { _S_need_barriers = 1 }; + }; + + template<_Lock_policy _Lp = __default_lock_policy> + class _Sp_counted_base + : public _Mutex_base<_Lp> + { + public: + _Sp_counted_base() + : _M_use_count(1), _M_weak_count(1) { } + + virtual + ~_Sp_counted_base() // nothrow + { } + + // Called when _M_use_count drops to zero, to release the resources + // managed by *this. + virtual void + _M_dispose() = 0; // nothrow + + // Called when _M_weak_count drops to zero. + virtual void + _M_destroy() // nothrow + { delete this; } + + virtual void* + _M_get_deleter(const std::type_info&) = 0; + + void + _M_add_ref_copy() + { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } + + void + _M_add_ref_lock(); + + void + _M_release() // nothrow + { + // Be race-detector-friendly. For more info see bits/c++config. + _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) + { + _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); + _M_dispose(); + // There must be a memory barrier between dispose() and destroy() + // to ensure that the effects of dispose() are observed in the + // thread that runs destroy(). + // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html + if (_Mutex_base<_Lp>::_S_need_barriers) + { + _GLIBCXX_READ_MEM_BARRIER; + _GLIBCXX_WRITE_MEM_BARRIER; + } + + // Be race-detector-friendly. For more info see bits/c++config. + _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, + -1) == 1) + { + _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); + _M_destroy(); + } + } + } + + void + _M_weak_add_ref() // nothrow + { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } + + void + _M_weak_release() // nothrow + { + // Be race-detector-friendly. For more info see bits/c++config. + _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) + { + _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); + if (_Mutex_base<_Lp>::_S_need_barriers) + { + // See _M_release(), + // destroy() must observe results of dispose() + _GLIBCXX_READ_MEM_BARRIER; + _GLIBCXX_WRITE_MEM_BARRIER; + } + _M_destroy(); + } + } + + long + _M_get_use_count() const // nothrow + { + // No memory barrier is used here so there is no synchronization + // with other threads. + return const_cast<const volatile _Atomic_word&>(_M_use_count); + } + + private: + _Sp_counted_base(_Sp_counted_base const&); + _Sp_counted_base& operator=(_Sp_counted_base const&); + + _Atomic_word _M_use_count; // #shared + _Atomic_word _M_weak_count; // #weak + (#shared != 0) + }; + + template<> + inline void + _Sp_counted_base<_S_single>:: + _M_add_ref_lock() + { + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) + { + _M_use_count = 0; + __throw_bad_weak_ptr(); + } + } + + template<> + inline void + _Sp_counted_base<_S_mutex>:: + _M_add_ref_lock() + { + __gnu_cxx::__scoped_lock sentry(*this); + if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) + { + _M_use_count = 0; + __throw_bad_weak_ptr(); + } + } + + template<> + inline void + _Sp_counted_base<_S_atomic>:: + _M_add_ref_lock() + { + // Perform lock-free add-if-not-zero operation. + _Atomic_word __count; + do + { + __count = _M_use_count; + if (__count == 0) + __throw_bad_weak_ptr(); + + // Replace the current counter value with the old value + 1, as + // long as it's not changed meanwhile. + } + while (!__sync_bool_compare_and_swap(&_M_use_count, __count, + __count + 1)); + } + + template<typename _Ptr, typename _Deleter, _Lock_policy _Lp> + class _Sp_counted_base_impl + : public _Sp_counted_base<_Lp> + { + public: + // Precondition: __d(__p) must not throw. + _Sp_counted_base_impl(_Ptr __p, _Deleter __d) + : _M_ptr(__p), _M_del(__d) { } + + virtual void + _M_dispose() // nothrow + { _M_del(_M_ptr); } + + virtual void* + _M_get_deleter(const std::type_info& __ti) + { +#ifdef __GXX_RTTI + return __ti == typeid(_Deleter) ? &_M_del : 0; +#else + return 0; +#endif + } + + private: + _Sp_counted_base_impl(const _Sp_counted_base_impl&); + _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); + + _Ptr _M_ptr; // copy constructor must not throw + _Deleter _M_del; // copy constructor must not throw + }; + + template<_Lock_policy _Lp = __default_lock_policy> + class __weak_count; + + template<typename _Tp> + struct _Sp_deleter + { + typedef void result_type; + typedef _Tp* argument_type; + void operator()(_Tp* __p) const { delete __p; } + }; + + template<_Lock_policy _Lp = __default_lock_policy> + class __shared_count + { + public: + __shared_count() + : _M_pi(0) // nothrow + { } + + template<typename _Ptr> + __shared_count(_Ptr __p) : _M_pi(0) + { + __try + { + typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp; + _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>( + __p, _Sp_deleter<_Tp>()); + } + __catch(...) + { + delete __p; + __throw_exception_again; + } + } + + template<typename _Ptr, typename _Deleter> + __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) + { + __try + { + _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d); + } + __catch(...) + { + __d(__p); // Call _Deleter on __p. + __throw_exception_again; + } + } + + // Special case for auto_ptr<_Tp> to provide the strong guarantee. + template<typename _Tp> + explicit + __shared_count(std::auto_ptr<_Tp>& __r) + : _M_pi(new _Sp_counted_base_impl<_Tp*, + _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>())) + { __r.release(); } + + // Throw bad_weak_ptr when __r._M_get_use_count() == 0. + explicit + __shared_count(const __weak_count<_Lp>& __r); + + ~__shared_count() // nothrow + { + if (_M_pi != 0) + _M_pi->_M_release(); + } + + __shared_count(const __shared_count& __r) + : _M_pi(__r._M_pi) // nothrow + { + if (_M_pi != 0) + _M_pi->_M_add_ref_copy(); + } + + __shared_count& + operator=(const __shared_count& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + if (__tmp != _M_pi) + { + if (__tmp != 0) + __tmp->_M_add_ref_copy(); + if (_M_pi != 0) + _M_pi->_M_release(); + _M_pi = __tmp; + } + return *this; + } + + void + _M_swap(__shared_count& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + __r._M_pi = _M_pi; + _M_pi = __tmp; + } + + long + _M_get_use_count() const // nothrow + { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } + + bool + _M_unique() const // nothrow + { return this->_M_get_use_count() == 1; } + + friend inline bool + operator==(const __shared_count& __a, const __shared_count& __b) + { return __a._M_pi == __b._M_pi; } + + friend inline bool + operator<(const __shared_count& __a, const __shared_count& __b) + { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } + + void* + _M_get_deleter(const std::type_info& __ti) const + { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } + + private: + friend class __weak_count<_Lp>; + + _Sp_counted_base<_Lp>* _M_pi; + }; + + + template<_Lock_policy _Lp> + class __weak_count + { + public: + __weak_count() + : _M_pi(0) // nothrow + { } + + __weak_count(const __shared_count<_Lp>& __r) + : _M_pi(__r._M_pi) // nothrow + { + if (_M_pi != 0) + _M_pi->_M_weak_add_ref(); + } + + __weak_count(const __weak_count<_Lp>& __r) + : _M_pi(__r._M_pi) // nothrow + { + if (_M_pi != 0) + _M_pi->_M_weak_add_ref(); + } + + ~__weak_count() // nothrow + { + if (_M_pi != 0) + _M_pi->_M_weak_release(); + } + + __weak_count<_Lp>& + operator=(const __shared_count<_Lp>& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + if (__tmp != 0) + __tmp->_M_weak_add_ref(); + if (_M_pi != 0) + _M_pi->_M_weak_release(); + _M_pi = __tmp; + return *this; + } + + __weak_count<_Lp>& + operator=(const __weak_count<_Lp>& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + if (__tmp != 0) + __tmp->_M_weak_add_ref(); + if (_M_pi != 0) + _M_pi->_M_weak_release(); + _M_pi = __tmp; + return *this; + } + + void + _M_swap(__weak_count<_Lp>& __r) // nothrow + { + _Sp_counted_base<_Lp>* __tmp = __r._M_pi; + __r._M_pi = _M_pi; + _M_pi = __tmp; + } + + long + _M_get_use_count() const // nothrow + { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } + + friend inline bool + operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) + { return __a._M_pi == __b._M_pi; } + + friend inline bool + operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) + { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } + + private: + friend class __shared_count<_Lp>; + + _Sp_counted_base<_Lp>* _M_pi; + }; + + // now that __weak_count is defined we can define this constructor: + template<_Lock_policy _Lp> + inline + __shared_count<_Lp>:: + __shared_count(const __weak_count<_Lp>& __r) + : _M_pi(__r._M_pi) + { + if (_M_pi != 0) + _M_pi->_M_add_ref_lock(); + else + __throw_bad_weak_ptr(); + } + + // Forward declarations. + template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> + class __shared_ptr; + + template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> + class __weak_ptr; + + template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> + class __enable_shared_from_this; + + template<typename _Tp> + class shared_ptr; + + template<typename _Tp> + class weak_ptr; + + template<typename _Tp> + class enable_shared_from_this; + + // Support for enable_shared_from_this. + + // Friend of __enable_shared_from_this. + template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> + void + __enable_shared_from_this_helper(const __shared_count<_Lp>&, + const __enable_shared_from_this<_Tp1, + _Lp>*, const _Tp2*); + + // Friend of enable_shared_from_this. + template<typename _Tp1, typename _Tp2> + void + __enable_shared_from_this_helper(const __shared_count<>&, + const enable_shared_from_this<_Tp1>*, + const _Tp2*); + + template<_Lock_policy _Lp> + inline void + __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) + { } + + + struct __static_cast_tag { }; + struct __const_cast_tag { }; + struct __dynamic_cast_tag { }; + + // A smart pointer with reference-counted copy semantics. The + // object pointed to is deleted when the last shared_ptr pointing to + // it is destroyed or reset. + template<typename _Tp, _Lock_policy _Lp> + class __shared_ptr + { + public: + typedef _Tp element_type; + + __shared_ptr() + : _M_ptr(0), _M_refcount() // never throws + { } + + template<typename _Tp1> + explicit + __shared_ptr(_Tp1* __p) + : _M_ptr(__p), _M_refcount(__p) + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + typedef int _IsComplete[sizeof(_Tp1)]; + __enable_shared_from_this_helper(_M_refcount, __p, __p); + } + + template<typename _Tp1, typename _Deleter> + __shared_ptr(_Tp1* __p, _Deleter __d) + : _M_ptr(__p), _M_refcount(__p, __d) + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + // TODO requires _Deleter CopyConstructible and __d(__p) well-formed + __enable_shared_from_this_helper(_M_refcount, __p, __p); + } + + // generated copy constructor, assignment, destructor are fine. + + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) + : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws + { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } + + template<typename _Tp1> + explicit + __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) + : _M_refcount(__r._M_refcount) // may throw + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) + // did not throw. + _M_ptr = __r._M_ptr; + } + +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED + // Postcondition: use_count() == 1 and __r.get() == 0 + template<typename _Tp1> + explicit + __shared_ptr(std::auto_ptr<_Tp1>& __r) + : _M_ptr(__r.get()), _M_refcount() + { // TODO requries delete __r.release() well-formed + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + typedef int _IsComplete[sizeof(_Tp1)]; + _Tp1* __tmp = __r.get(); + _M_refcount = __shared_count<_Lp>(__r); + __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); + } + +#endif + + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag) + : _M_ptr(static_cast<element_type*>(__r._M_ptr)), + _M_refcount(__r._M_refcount) + { } + + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag) + : _M_ptr(const_cast<element_type*>(__r._M_ptr)), + _M_refcount(__r._M_refcount) + { } + + template<typename _Tp1> + __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag) + : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)), + _M_refcount(__r._M_refcount) + { + if (_M_ptr == 0) // need to allocate new counter -- the cast failed + _M_refcount = __shared_count<_Lp>(); + } + + template<typename _Tp1> + __shared_ptr& + operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws + { + _M_ptr = __r._M_ptr; + _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw + return *this; + } + +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED + template<typename _Tp1> + __shared_ptr& + operator=(std::auto_ptr<_Tp1>& __r) + { + __shared_ptr(__r).swap(*this); + return *this; + } +#endif + + void + reset() // never throws + { __shared_ptr().swap(*this); } + + template<typename _Tp1> + void + reset(_Tp1* __p) // _Tp1 must be complete. + { + // Catch self-reset errors. + _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); + __shared_ptr(__p).swap(*this); + } + + template<typename _Tp1, typename _Deleter> + void + reset(_Tp1* __p, _Deleter __d) + { __shared_ptr(__p, __d).swap(*this); } + + // Allow class instantiation when _Tp is [cv-qual] void. + typename std::tr1::add_reference<_Tp>::type + operator*() const // never throws + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return *_M_ptr; + } + + _Tp* + operator->() const // never throws + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return _M_ptr; + } + + _Tp* + get() const // never throws + { return _M_ptr; } + + // Implicit conversion to "bool" + private: + typedef _Tp* __shared_ptr::*__unspecified_bool_type; + + public: + operator __unspecified_bool_type() const // never throws + { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } + + bool + unique() const // never throws + { return _M_refcount._M_unique(); } + + long + use_count() const // never throws + { return _M_refcount._M_get_use_count(); } + + void + swap(__shared_ptr<_Tp, _Lp>& __other) // never throws + { + std::swap(_M_ptr, __other._M_ptr); + _M_refcount._M_swap(__other._M_refcount); + } + + private: + void* + _M_get_deleter(const std::type_info& __ti) const + { return _M_refcount._M_get_deleter(__ti); } + + template<typename _Tp1, _Lock_policy _Lp1> + bool + _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const + { return _M_refcount < __rhs._M_refcount; } + + template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; + template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; + + template<typename _Del, typename _Tp1, _Lock_policy _Lp1> + friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); + + // Friends injected into enclosing namespace and found by ADL: + template<typename _Tp1> + friend inline bool + operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) + { return __a.get() == __b.get(); } + + template<typename _Tp1> + friend inline bool + operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) + { return __a.get() != __b.get(); } + + template<typename _Tp1> + friend inline bool + operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) + { return __a._M_less(__b); } + + _Tp* _M_ptr; // Contained pointer. + __shared_count<_Lp> _M_refcount; // Reference counter. + }; + + // 2.2.3.8 shared_ptr specialized algorithms. + template<typename _Tp, _Lock_policy _Lp> + inline void + swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) + { __a.swap(__b); } + + // 2.2.3.9 shared_ptr casts + /* The seemingly equivalent + * shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) + * will eventually result in undefined behaviour, + * attempting to delete the same object twice. + */ + template<typename _Tp, typename _Tp1, _Lock_policy _Lp> + inline __shared_ptr<_Tp, _Lp> + static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) + { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); } + + /* The seemingly equivalent + * shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) + * will eventually result in undefined behaviour, + * attempting to delete the same object twice. + */ + template<typename _Tp, typename _Tp1, _Lock_policy _Lp> + inline __shared_ptr<_Tp, _Lp> + const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) + { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); } + + /* The seemingly equivalent + * shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) + * will eventually result in undefined behaviour, + * attempting to delete the same object twice. + */ + template<typename _Tp, typename _Tp1, _Lock_policy _Lp> + inline __shared_ptr<_Tp, _Lp> + dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) + { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); } + + // 2.2.3.7 shared_ptr I/O + template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> + std::basic_ostream<_Ch, _Tr>& + operator<<(std::basic_ostream<_Ch, _Tr>& __os, + const __shared_ptr<_Tp, _Lp>& __p) + { + __os << __p.get(); + return __os; + } + + // 2.2.3.10 shared_ptr get_deleter (experimental) + template<typename _Del, typename _Tp, _Lock_policy _Lp> + inline _Del* + get_deleter(const __shared_ptr<_Tp, _Lp>& __p) + { +#ifdef __GXX_RTTI + return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); +#else + return 0; +#endif + } + + + template<typename _Tp, _Lock_policy _Lp> + class __weak_ptr + { + public: + typedef _Tp element_type; + + __weak_ptr() + : _M_ptr(0), _M_refcount() // never throws + { } + + // Generated copy constructor, assignment, destructor are fine. + + // The "obvious" converting constructor implementation: + // + // template<typename _Tp1> + // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) + // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws + // { } + // + // has a serious problem. + // + // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) + // conversion may require access to *__r._M_ptr (virtual inheritance). + // + // It is not possible to avoid spurious access violations since + // in multithreaded programs __r._M_ptr may be invalidated at any point. + template<typename _Tp1> + __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) + : _M_refcount(__r._M_refcount) // never throws + { + __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) + _M_ptr = __r.lock().get(); + } + + template<typename _Tp1> + __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) + : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws + { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } + + template<typename _Tp1> + __weak_ptr& + operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws + { + _M_ptr = __r.lock().get(); + _M_refcount = __r._M_refcount; + return *this; + } + + template<typename _Tp1> + __weak_ptr& + operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws + { + _M_ptr = __r._M_ptr; + _M_refcount = __r._M_refcount; + return *this; + } + + __shared_ptr<_Tp, _Lp> + lock() const // never throws + { +#ifdef __GTHREADS + // Optimization: avoid throw overhead. + if (expired()) + return __shared_ptr<element_type, _Lp>(); + + __try + { + return __shared_ptr<element_type, _Lp>(*this); + } + __catch(const bad_weak_ptr&) + { + // Q: How can we get here? + // A: Another thread may have invalidated r after the + // use_count test above. + return __shared_ptr<element_type, _Lp>(); + } + +#else + // Optimization: avoid try/catch overhead when single threaded. + return expired() ? __shared_ptr<element_type, _Lp>() + : __shared_ptr<element_type, _Lp>(*this); + +#endif + } // XXX MT + + long + use_count() const // never throws + { return _M_refcount._M_get_use_count(); } + + bool + expired() const // never throws + { return _M_refcount._M_get_use_count() == 0; } + + void + reset() // never throws + { __weak_ptr().swap(*this); } + + void + swap(__weak_ptr& __s) // never throws + { + std::swap(_M_ptr, __s._M_ptr); + _M_refcount._M_swap(__s._M_refcount); + } + + private: + // Used by __enable_shared_from_this. + void + _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) + { + _M_ptr = __ptr; + _M_refcount = __refcount; + } + + template<typename _Tp1> + bool + _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const + { return _M_refcount < __rhs._M_refcount; } + + template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; + template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; + friend class __enable_shared_from_this<_Tp, _Lp>; + friend class enable_shared_from_this<_Tp>; + + // Friend injected into namespace and found by ADL. + template<typename _Tp1> + friend inline bool + operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs) + { return __lhs._M_less(__rhs); } + + _Tp* _M_ptr; // Contained pointer. + __weak_count<_Lp> _M_refcount; // Reference counter. + }; + + // 2.2.4.7 weak_ptr specialized algorithms. + template<typename _Tp, _Lock_policy _Lp> + inline void + swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) + { __a.swap(__b); } + + + template<typename _Tp, _Lock_policy _Lp> + class __enable_shared_from_this + { + protected: + __enable_shared_from_this() { } + + __enable_shared_from_this(const __enable_shared_from_this&) { } + + __enable_shared_from_this& + operator=(const __enable_shared_from_this&) + { return *this; } + + ~__enable_shared_from_this() { } + + public: + __shared_ptr<_Tp, _Lp> + shared_from_this() + { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } + + __shared_ptr<const _Tp, _Lp> + shared_from_this() const + { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } + + private: + template<typename _Tp1> + void + _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const + { _M_weak_this._M_assign(__p, __n); } + + template<typename _Tp1> + friend void + __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, + const __enable_shared_from_this* __pe, + const _Tp1* __px) + { + if (__pe != 0) + __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); + } + + mutable __weak_ptr<_Tp, _Lp> _M_weak_this; + }; + + + // The actual shared_ptr, with forwarding constructors and + // assignment operators. + template<typename _Tp> + class shared_ptr + : public __shared_ptr<_Tp> + { + public: + shared_ptr() + : __shared_ptr<_Tp>() { } + + template<typename _Tp1> + explicit + shared_ptr(_Tp1* __p) + : __shared_ptr<_Tp>(__p) { } + + template<typename _Tp1, typename _Deleter> + shared_ptr(_Tp1* __p, _Deleter __d) + : __shared_ptr<_Tp>(__p, __d) { } + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r) + : __shared_ptr<_Tp>(__r) { } + + template<typename _Tp1> + explicit + shared_ptr(const weak_ptr<_Tp1>& __r) + : __shared_ptr<_Tp>(__r) { } + +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED + template<typename _Tp1> + explicit + shared_ptr(std::auto_ptr<_Tp1>& __r) + : __shared_ptr<_Tp>(__r) { } +#endif + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag) + : __shared_ptr<_Tp>(__r, __static_cast_tag()) { } + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag) + : __shared_ptr<_Tp>(__r, __const_cast_tag()) { } + + template<typename _Tp1> + shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) + : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { } + + template<typename _Tp1> + shared_ptr& + operator=(const shared_ptr<_Tp1>& __r) // never throws + { + this->__shared_ptr<_Tp>::operator=(__r); + return *this; + } + +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED + template<typename _Tp1> + shared_ptr& + operator=(std::auto_ptr<_Tp1>& __r) + { + this->__shared_ptr<_Tp>::operator=(__r); + return *this; + } +#endif + }; + + // 2.2.3.8 shared_ptr specialized algorithms. + template<typename _Tp> + inline void + swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b) + { __a.swap(__b); } + + template<typename _Tp, typename _Tp1> + inline shared_ptr<_Tp> + static_pointer_cast(const shared_ptr<_Tp1>& __r) + { return shared_ptr<_Tp>(__r, __static_cast_tag()); } + + template<typename _Tp, typename _Tp1> + inline shared_ptr<_Tp> + const_pointer_cast(const shared_ptr<_Tp1>& __r) + { return shared_ptr<_Tp>(__r, __const_cast_tag()); } + + template<typename _Tp, typename _Tp1> + inline shared_ptr<_Tp> + dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) + { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); } + + + // The actual weak_ptr, with forwarding constructors and + // assignment operators. + template<typename _Tp> + class weak_ptr + : public __weak_ptr<_Tp> + { + public: + weak_ptr() + : __weak_ptr<_Tp>() { } + + template<typename _Tp1> + weak_ptr(const weak_ptr<_Tp1>& __r) + : __weak_ptr<_Tp>(__r) { } + + template<typename _Tp1> + weak_ptr(const shared_ptr<_Tp1>& __r) + : __weak_ptr<_Tp>(__r) { } + + template<typename _Tp1> + weak_ptr& + operator=(const weak_ptr<_Tp1>& __r) // never throws + { + this->__weak_ptr<_Tp>::operator=(__r); + return *this; + } + + template<typename _Tp1> + weak_ptr& + operator=(const shared_ptr<_Tp1>& __r) // never throws + { + this->__weak_ptr<_Tp>::operator=(__r); + return *this; + } + + shared_ptr<_Tp> + lock() const // never throws + { +#ifdef __GTHREADS + if (this->expired()) + return shared_ptr<_Tp>(); + + __try + { + return shared_ptr<_Tp>(*this); + } + __catch(const bad_weak_ptr&) + { + return shared_ptr<_Tp>(); + } +#else + return this->expired() ? shared_ptr<_Tp>() + : shared_ptr<_Tp>(*this); +#endif + } + }; + + template<typename _Tp> + class enable_shared_from_this + { + protected: + enable_shared_from_this() { } + + enable_shared_from_this(const enable_shared_from_this&) { } + + enable_shared_from_this& + operator=(const enable_shared_from_this&) + { return *this; } + + ~enable_shared_from_this() { } + + public: + shared_ptr<_Tp> + shared_from_this() + { return shared_ptr<_Tp>(this->_M_weak_this); } + + shared_ptr<const _Tp> + shared_from_this() const + { return shared_ptr<const _Tp>(this->_M_weak_this); } + + private: + template<typename _Tp1> + void + _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const + { _M_weak_this._M_assign(__p, __n); } + + template<typename _Tp1> + friend void + __enable_shared_from_this_helper(const __shared_count<>& __pn, + const enable_shared_from_this* __pe, + const _Tp1* __px) + { + if (__pe != 0) + __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); + } + + mutable weak_ptr<_Tp> _M_weak_this; + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _TR1_SHARED_PTR_H diff --git a/libstdc++-v3/include/tr1/special_function_util.h b/libstdc++-v3/include/tr1/special_function_util.h new file mode 100644 index 000000000..c90fc599f --- /dev/null +++ b/libstdc++-v3/include/tr1/special_function_util.h @@ -0,0 +1,144 @@ +// Special functions -*- C++ -*- + +// Copyright (C) 2006, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/special_function_util.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/cmath} + */ + +// +// ISO C++ 14882 TR1: 5.2 Special functions +// + +// Written by Edward Smith-Rowland based on numerous mathematics books. + +#ifndef _GLIBCXX_TR1_SPECIAL_FUNCTION_UTIL_H +#define _GLIBCXX_TR1_SPECIAL_FUNCTION_UTIL_H 1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ + namespace __detail + { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + + /// A class to encapsulate type dependent floating point + /// constants. Not everything will be able to be expressed as + /// type logic. + template<typename _Tp> + struct __floating_point_constant + { + static const _Tp __value; + }; + + + /// A structure for numeric constants. + template<typename _Tp> + struct __numeric_constants + { + /// Constant @f$ \pi @f$. + static _Tp __pi() throw() + { return static_cast<_Tp>(3.1415926535897932384626433832795029L); } + /// Constant @f$ \pi / 2 @f$. + static _Tp __pi_2() throw() + { return static_cast<_Tp>(1.5707963267948966192313216916397514L); } + /// Constant @f$ \pi / 3 @f$. + static _Tp __pi_3() throw() + { return static_cast<_Tp>(1.0471975511965977461542144610931676L); } + /// Constant @f$ \pi / 4 @f$. + static _Tp __pi_4() throw() + { return static_cast<_Tp>(0.7853981633974483096156608458198757L); } + /// Constant @f$ 1 / \pi @f$. + static _Tp __1_pi() throw() + { return static_cast<_Tp>(0.3183098861837906715377675267450287L); } + /// Constant @f$ 2 / \sqrt(\pi) @f$. + static _Tp __2_sqrtpi() throw() + { return static_cast<_Tp>(1.1283791670955125738961589031215452L); } + /// Constant @f$ \sqrt(2) @f$. + static _Tp __sqrt2() throw() + { return static_cast<_Tp>(1.4142135623730950488016887242096981L); } + /// Constant @f$ \sqrt(3) @f$. + static _Tp __sqrt3() throw() + { return static_cast<_Tp>(1.7320508075688772935274463415058723L); } + /// Constant @f$ \sqrt(\pi/2) @f$. + static _Tp __sqrtpio2() throw() + { return static_cast<_Tp>(1.2533141373155002512078826424055226L); } + /// Constant @f$ 1 / sqrt(2) @f$. + static _Tp __sqrt1_2() throw() + { return static_cast<_Tp>(0.7071067811865475244008443621048490L); } + /// Constant @f$ \log(\pi) @f$. + static _Tp __lnpi() throw() + { return static_cast<_Tp>(1.1447298858494001741434273513530587L); } + /// Constant Euler's constant @f$ \gamma_E @f$. + static _Tp __gamma_e() throw() + { return static_cast<_Tp>(0.5772156649015328606065120900824024L); } + /// Constant Euler-Mascheroni @f$ e @f$ + static _Tp __euler() throw() + { return static_cast<_Tp>(2.7182818284590452353602874713526625L); } + }; + + +#if _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC + + /// This is a wrapper for the isnan function. Otherwise, for NaN, + /// all comparisons result in false. If/when we build a std::isnan + /// out of intrinsics, this will disappear completely in favor of + /// std::isnan. + template<typename _Tp> + inline bool __isnan(const _Tp __x) + { + return std::isnan(__x); + } + +#else + + template<typename _Tp> + inline bool __isnan(const _Tp __x) + { + return __builtin_isnan(__x); + } + + template<> + inline bool __isnan<float>(const float __x) + { + return __builtin_isnanf(__x); + } + + template<> + inline bool __isnan<long double>(const long double __x) + { + return __builtin_isnanl(__x); + } + +#endif + + _GLIBCXX_END_NAMESPACE_VERSION + } // namespace __detail +} +} + +#endif // _GLIBCXX_TR1_SPECIAL_FUNCTION_UTIL_H + diff --git a/libstdc++-v3/include/tr1/stdarg.h b/libstdc++-v3/include/tr1/stdarg.h new file mode 100644 index 000000000..41173e847 --- /dev/null +++ b/libstdc++-v3/include/tr1/stdarg.h @@ -0,0 +1,34 @@ +// TR1 stdarg.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/stdarg.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDARG_H +#define _TR1_STDARG_H 1 + +#include <tr1/cstdarg> + +#endif diff --git a/libstdc++-v3/include/tr1/stdbool.h b/libstdc++-v3/include/tr1/stdbool.h new file mode 100644 index 000000000..3861e4457 --- /dev/null +++ b/libstdc++-v3/include/tr1/stdbool.h @@ -0,0 +1,34 @@ +// TR1 stdbool.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/stdbool.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDBOOL_H +#define _TR1_STDBOOL_H 1 + +#include <tr1/cstdbool> + +#endif diff --git a/libstdc++-v3/include/tr1/stdint.h b/libstdc++-v3/include/tr1/stdint.h new file mode 100644 index 000000000..8113fa5ad --- /dev/null +++ b/libstdc++-v3/include/tr1/stdint.h @@ -0,0 +1,34 @@ +// TR1 stdint.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/stdint.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDINT_H +#define _TR1_STDINT_H 1 + +#include <tr1/cstdint> + +#endif diff --git a/libstdc++-v3/include/tr1/stdio.h b/libstdc++-v3/include/tr1/stdio.h new file mode 100644 index 000000000..f1edf8395 --- /dev/null +++ b/libstdc++-v3/include/tr1/stdio.h @@ -0,0 +1,34 @@ +// TR1 stdio.h -*- C++ -*- + +// Copyright (C) 2006, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/stdio.h + * This is a TR1 C++ Library header. + */ + +#ifndef _TR1_STDIO_H +#define _TR1_STDIO_H 1 + +#include <tr1/cstdio> + +#endif diff --git a/libstdc++-v3/include/tr1/stdlib.h b/libstdc++-v3/include/tr1/stdlib.h new file mode 100644 index 000000000..5e57aecbf --- /dev/null +++ b/libstdc++-v3/include/tr1/stdlib.h @@ -0,0 +1,52 @@ +// TR1 stdlib.h -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/stdlib.h + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_STDLIB_H +#define _GLIBCXX_TR1_STDLIB_H 1 + +#include <tr1/cstdlib> + +#if _GLIBCXX_HOSTED + +#if _GLIBCXX_USE_C99 + +using std::tr1::atoll; +using std::tr1::strtoll; +using std::tr1::strtoull; + +using std::tr1::abs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC +using std::tr1::div; +#endif + +#endif + +#endif + +#endif // _GLIBCXX_TR1_STDLIB_H + diff --git a/libstdc++-v3/include/tr1/tgmath.h b/libstdc++-v3/include/tr1/tgmath.h new file mode 100644 index 000000000..c807031e5 --- /dev/null +++ b/libstdc++-v3/include/tr1/tgmath.h @@ -0,0 +1,34 @@ +// TR1 tgmath.h -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/tgmath.h + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_TGMATH_H +#define _GLIBCXX_TR1_TGMATH_H 1 + +#include <tr1/ctgmath> + +#endif // _GLIBCXX_TR1_TGMATH_H diff --git a/libstdc++-v3/include/tr1/tuple b/libstdc++-v3/include/tr1/tuple new file mode 100644 index 000000000..15ac642a1 --- /dev/null +++ b/libstdc++-v3/include/tr1/tuple @@ -0,0 +1,426 @@ +// class template tuple -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/tuple +* This is a TR1 C++ Library header. +*/ + +// Chris Jefferson <chris@bubblescope.net> +// Variadic Templates support by Douglas Gregor <doug.gregor@gmail.com> + +#ifndef _GLIBCXX_TR1_TUPLE +#define _GLIBCXX_TR1_TUPLE 1 + +#pragma GCC system_header + +#include <utility> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Adds a const reference to a non-reference type. + template<typename _Tp> + struct __add_c_ref + { typedef const _Tp& type; }; + + template<typename _Tp> + struct __add_c_ref<_Tp&> + { typedef _Tp& type; }; + + // Adds a reference to a non-reference type. + template<typename _Tp> + struct __add_ref + { typedef _Tp& type; }; + + template<typename _Tp> + struct __add_ref<_Tp&> + { typedef _Tp& type; }; + + /** + * Contains the actual implementation of the @c tuple template, stored + * as a recursive inheritance hierarchy from the first element (most + * derived class) to the last (least derived class). The @c Idx + * parameter gives the 0-based index of the element stored at this + * point in the hierarchy; we use it to implement a constant-time + * get() operation. + */ + template<int _Idx, typename... _Elements> + struct _Tuple_impl; + + /** + * Zero-element tuple implementation. This is the basis case for the + * inheritance recursion. + */ + template<int _Idx> + struct _Tuple_impl<_Idx> { }; + + /** + * Recursive tuple implementation. Here we store the @c Head element + * and derive from a @c Tuple_impl containing the remaining elements + * (which contains the @c Tail). + */ + template<int _Idx, typename _Head, typename... _Tail> + struct _Tuple_impl<_Idx, _Head, _Tail...> + : public _Tuple_impl<_Idx + 1, _Tail...> + { + typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; + + _Head _M_head; + + _Inherited& _M_tail() { return *this; } + const _Inherited& _M_tail() const { return *this; } + + _Tuple_impl() : _Inherited(), _M_head() { } + + explicit + _Tuple_impl(typename __add_c_ref<_Head>::type __head, + typename __add_c_ref<_Tail>::type... __tail) + : _Inherited(__tail...), _M_head(__head) { } + + template<typename... _UElements> + _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) + : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } + + _Tuple_impl(const _Tuple_impl& __in) + : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } + + template<typename... _UElements> + _Tuple_impl& + operator=(const _Tuple_impl<_Idx, _UElements...>& __in) + { + _M_head = __in._M_head; + _M_tail() = __in._M_tail(); + return *this; + } + + _Tuple_impl& + operator=(const _Tuple_impl& __in) + { + _M_head = __in._M_head; + _M_tail() = __in._M_tail(); + return *this; + } + }; + + template<typename... _Elements> + class tuple : public _Tuple_impl<0, _Elements...> + { + typedef _Tuple_impl<0, _Elements...> _Inherited; + + public: + tuple() : _Inherited() { } + + explicit + tuple(typename __add_c_ref<_Elements>::type... __elements) + : _Inherited(__elements...) { } + + template<typename... _UElements> + tuple(const tuple<_UElements...>& __in) + : _Inherited(__in) { } + + tuple(const tuple& __in) + : _Inherited(__in) { } + + template<typename... _UElements> + tuple& + operator=(const tuple<_UElements...>& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + tuple& + operator=(const tuple& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + }; + + template<> class tuple<> { }; + + // 2-element tuple, with construction and assignment from a pair. + template<typename _T1, typename _T2> + class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> + { + typedef _Tuple_impl<0, _T1, _T2> _Inherited; + + public: + tuple() : _Inherited() { } + + explicit + tuple(typename __add_c_ref<_T1>::type __a1, + typename __add_c_ref<_T2>::type __a2) + : _Inherited(__a1, __a2) { } + + template<typename _U1, typename _U2> + tuple(const tuple<_U1, _U2>& __in) + : _Inherited(__in) { } + + tuple(const tuple& __in) + : _Inherited(__in) { } + + template<typename _U1, typename _U2> + tuple(const pair<_U1, _U2>& __in) + : _Inherited(_Tuple_impl<0, + typename __add_c_ref<_U1>::type, + typename __add_c_ref<_U2>::type>(__in.first, + __in.second)) + { } + + template<typename _U1, typename _U2> + tuple& + operator=(const tuple<_U1, _U2>& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + tuple& + operator=(const tuple& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + template<typename _U1, typename _U2> + tuple& + operator=(const pair<_U1, _U2>& __in) + { + this->_M_head = __in.first; + this->_M_tail()._M_head = __in.second; + return *this; + } + }; + + + /// Gives the type of the ith element of a given tuple type. + template<int __i, typename _Tp> + struct tuple_element; + + /** + * Recursive case for tuple_element: strip off the first element in + * the tuple and retrieve the (i-1)th element of the remaining tuple. + */ + template<int __i, typename _Head, typename... _Tail> + struct tuple_element<__i, tuple<_Head, _Tail...> > + : tuple_element<__i - 1, tuple<_Tail...> > { }; + + /** + * Basis case for tuple_element: The first element is the one we're seeking. + */ + template<typename _Head, typename... _Tail> + struct tuple_element<0, tuple<_Head, _Tail...> > + { + typedef _Head type; + }; + + /// Finds the size of a given tuple type. + template<typename _Tp> + struct tuple_size; + + /// class tuple_size + template<typename... _Elements> + struct tuple_size<tuple<_Elements...> > + { + static const int value = sizeof...(_Elements); + }; + + template<typename... _Elements> + const int tuple_size<tuple<_Elements...> >::value; + + template<int __i, typename _Head, typename... _Tail> + inline typename __add_ref<_Head>::type + __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) + { + return __t._M_head; + } + + template<int __i, typename _Head, typename... _Tail> + inline typename __add_c_ref<_Head>::type + __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) + { + return __t._M_head; + } + + // Return a reference (const reference) to the ith element of a tuple. + // Any const or non-const ref elements are returned with their original type. + template<int __i, typename... _Elements> + inline typename __add_ref< + typename tuple_element<__i, tuple<_Elements...> >::type + >::type + get(tuple<_Elements...>& __t) + { + return __get_helper<__i>(__t); + } + + template<int __i, typename... _Elements> + inline typename __add_c_ref< + typename tuple_element<__i, tuple<_Elements...> >::type + >::type + get(const tuple<_Elements...>& __t) + { + return __get_helper<__i>(__t); + } + + // This class helps construct the various comparison operations on tuples + template<int __check_equal_size, int __i, int __j, + typename _Tp, typename _Up> + struct __tuple_compare; + + template<int __i, int __j, typename _Tp, typename _Up> + struct __tuple_compare<0, __i, __j, _Tp, _Up> + { + static bool __eq(const _Tp& __t, const _Up& __u) + { + return (get<__i>(__t) == get<__i>(__u) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u)); + } + + static bool __less(const _Tp& __t, const _Up& __u) + { + return ((get<__i>(__t) < get<__i>(__u)) + || !(get<__i>(__u) < get<__i>(__t)) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u)); + } + }; + + template<int __i, typename _Tp, typename _Up> + struct __tuple_compare<0, __i, __i, _Tp, _Up> + { + static bool __eq(const _Tp&, const _Up&) + { return true; } + + static bool __less(const _Tp&, const _Up&) + { return false; } + }; + + template<typename... _TElements, typename... _UElements> + bool + operator==(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { + typedef tuple<_TElements...> _Tp; + typedef tuple<_UElements...> _Up; + return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, + 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); + } + + template<typename... _TElements, typename... _UElements> + bool + operator<(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { + typedef tuple<_TElements...> _Tp; + typedef tuple<_UElements...> _Up; + return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, + 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); + } + + template<typename... _TElements, typename... _UElements> + inline bool + operator!=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__t == __u); } + + template<typename... _TElements, typename... _UElements> + inline bool + operator>(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return __u < __t; } + + template<typename... _TElements, typename... _UElements> + inline bool + operator<=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__u < __t); } + + template<typename... _TElements, typename... _UElements> + inline bool + operator>=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__t < __u); } + + template<typename _Tp> + class reference_wrapper; + + // Helper which adds a reference to a type when given a reference_wrapper + template<typename _Tp> + struct __strip_reference_wrapper + { + typedef _Tp __type; + }; + + template<typename _Tp> + struct __strip_reference_wrapper<reference_wrapper<_Tp> > + { + typedef _Tp& __type; + }; + + template<typename _Tp> + struct __strip_reference_wrapper<const reference_wrapper<_Tp> > + { + typedef _Tp& __type; + }; + + template<typename... _Elements> + inline tuple<typename __strip_reference_wrapper<_Elements>::__type...> + make_tuple(_Elements... __args) + { + typedef tuple<typename __strip_reference_wrapper<_Elements>::__type...> + __result_type; + return __result_type(__args...); + } + + template<typename... _Elements> + inline tuple<_Elements&...> + tie(_Elements&... __args) + { + return tuple<_Elements&...>(__args...); + } + + // A class (and instance) which can be used in 'tie' when an element + // of a tuple is not required + struct _Swallow_assign + { + template<class _Tp> + _Swallow_assign& + operator=(const _Tp&) + { return *this; } + }; + + // TODO: Put this in some kind of shared file. + namespace + { + _Swallow_assign ignore; + }; // anonymous namespace + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_TUPLE diff --git a/libstdc++-v3/include/tr1/type_traits b/libstdc++-v3/include/tr1/type_traits new file mode 100644 index 000000000..2825fe6f4 --- /dev/null +++ b/libstdc++-v3/include/tr1/type_traits @@ -0,0 +1,689 @@ +// TR1 type_traits -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/type_traits + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_TYPE_TRAITS +#define _GLIBCXX_TR1_TYPE_TRAITS 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup metaprogramming Type Traits + * @ingroup utilities + * + * Compile time type transformation and information. + * @{ + */ + + struct __sfinae_types + { + typedef char __one; + typedef struct { char __arr[2]; } __two; + }; + +#define _DEFINE_SPEC_0_HELPER \ + template<> + +#define _DEFINE_SPEC_1_HELPER \ + template<typename _Tp> + +#define _DEFINE_SPEC_2_HELPER \ + template<typename _Tp, typename _Cp> + +#define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ + _DEFINE_SPEC_##_Order##_HELPER \ + struct _Trait<_Type> \ + : public integral_constant<bool, _Value> { }; + + // helper classes [4.3]. + + /// integral_constant + template<typename _Tp, _Tp __v> + struct integral_constant + { + static const _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; + }; + + /// typedef for true_type + typedef integral_constant<bool, true> true_type; + + /// typedef for false_type + typedef integral_constant<bool, false> false_type; + + template<typename _Tp, _Tp __v> + const _Tp integral_constant<_Tp, __v>::value; + + /// remove_cv + template<typename> + struct remove_cv; + + template<typename> + struct __is_void_helper + : public false_type { }; + _DEFINE_SPEC(0, __is_void_helper, void, true) + + // primary type categories [4.5.1]. + + /// is_void + template<typename _Tp> + struct is_void + : public integral_constant<bool, (__is_void_helper<typename + remove_cv<_Tp>::type>::value)> + { }; + + template<typename> + struct __is_integral_helper + : public false_type { }; + _DEFINE_SPEC(0, __is_integral_helper, bool, true) + _DEFINE_SPEC(0, __is_integral_helper, char, true) + _DEFINE_SPEC(0, __is_integral_helper, signed char, true) + _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) +#ifdef _GLIBCXX_USE_WCHAR_T + _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) +#endif + _DEFINE_SPEC(0, __is_integral_helper, short, true) + _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true) + _DEFINE_SPEC(0, __is_integral_helper, int, true) + _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true) + _DEFINE_SPEC(0, __is_integral_helper, long, true) + _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true) + _DEFINE_SPEC(0, __is_integral_helper, long long, true) + _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true) + + /// is_integral + template<typename _Tp> + struct is_integral + : public integral_constant<bool, (__is_integral_helper<typename + remove_cv<_Tp>::type>::value)> + { }; + + template<typename> + struct __is_floating_point_helper + : public false_type { }; + _DEFINE_SPEC(0, __is_floating_point_helper, float, true) + _DEFINE_SPEC(0, __is_floating_point_helper, double, true) + _DEFINE_SPEC(0, __is_floating_point_helper, long double, true) + + /// is_floating_point + template<typename _Tp> + struct is_floating_point + : public integral_constant<bool, (__is_floating_point_helper<typename + remove_cv<_Tp>::type>::value)> + { }; + + /// is_array + template<typename> + struct is_array + : public false_type { }; + + template<typename _Tp, std::size_t _Size> + struct is_array<_Tp[_Size]> + : public true_type { }; + + template<typename _Tp> + struct is_array<_Tp[]> + : public true_type { }; + + template<typename> + struct __is_pointer_helper + : public false_type { }; + _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true) + + /// is_pointer + template<typename _Tp> + struct is_pointer + : public integral_constant<bool, (__is_pointer_helper<typename + remove_cv<_Tp>::type>::value)> + { }; + + /// is_reference + template<typename _Tp> + struct is_reference; + + /// is_function + template<typename _Tp> + struct is_function; + + template<typename> + struct __is_member_object_pointer_helper + : public false_type { }; + _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*, + !is_function<_Tp>::value) + + /// is_member_object_pointer + template<typename _Tp> + struct is_member_object_pointer + : public integral_constant<bool, (__is_member_object_pointer_helper< + typename remove_cv<_Tp>::type>::value)> + { }; + + template<typename> + struct __is_member_function_pointer_helper + : public false_type { }; + _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*, + is_function<_Tp>::value) + + /// is_member_function_pointer + template<typename _Tp> + struct is_member_function_pointer + : public integral_constant<bool, (__is_member_function_pointer_helper< + typename remove_cv<_Tp>::type>::value)> + { }; + + /// is_enum + template<typename _Tp> + struct is_enum + : public integral_constant<bool, __is_enum(_Tp)> + { }; + + /// is_union + template<typename _Tp> + struct is_union + : public integral_constant<bool, __is_union(_Tp)> + { }; + + /// is_class + template<typename _Tp> + struct is_class + : public integral_constant<bool, __is_class(_Tp)> + { }; + + /// is_function + template<typename> + struct is_function + : public false_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes...)> + : public true_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes......)> + : public true_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes...) const> + : public true_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes......) const> + : public true_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes...) volatile> + : public true_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes......) volatile> + : public true_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes...) const volatile> + : public true_type { }; + template<typename _Res, typename... _ArgTypes> + struct is_function<_Res(_ArgTypes......) const volatile> + : public true_type { }; + + // composite type traits [4.5.2]. + + /// is_arithmetic + template<typename _Tp> + struct is_arithmetic + : public integral_constant<bool, (is_integral<_Tp>::value + || is_floating_point<_Tp>::value)> + { }; + + /// is_fundamental + template<typename _Tp> + struct is_fundamental + : public integral_constant<bool, (is_arithmetic<_Tp>::value + || is_void<_Tp>::value)> + { }; + + /// is_object + template<typename _Tp> + struct is_object + : public integral_constant<bool, !(is_function<_Tp>::value + || is_reference<_Tp>::value + || is_void<_Tp>::value)> + { }; + + /// is_member_pointer + template<typename _Tp> + struct is_member_pointer; + + /// is_scalar + template<typename _Tp> + struct is_scalar + : public integral_constant<bool, (is_arithmetic<_Tp>::value + || is_enum<_Tp>::value + || is_pointer<_Tp>::value + || is_member_pointer<_Tp>::value)> + { }; + + /// is_compound + template<typename _Tp> + struct is_compound + : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; + + /// is_member_pointer + template<typename _Tp> + struct __is_member_pointer_helper + : public false_type { }; + _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) + + template<typename _Tp> + struct is_member_pointer + : public integral_constant<bool, (__is_member_pointer_helper< + typename remove_cv<_Tp>::type>::value)> + { }; + + // type properties [4.5.3]. + /// is_const + template<typename> + struct is_const + : public false_type { }; + + template<typename _Tp> + struct is_const<_Tp const> + : public true_type { }; + + /// is_volatile + template<typename> + struct is_volatile + : public false_type { }; + + template<typename _Tp> + struct is_volatile<_Tp volatile> + : public true_type { }; + + /// is_empty + template<typename _Tp> + struct is_empty + : public integral_constant<bool, __is_empty(_Tp)> + { }; + + /// is_polymorphic + template<typename _Tp> + struct is_polymorphic + : public integral_constant<bool, __is_polymorphic(_Tp)> + { }; + + /// is_abstract + template<typename _Tp> + struct is_abstract + : public integral_constant<bool, __is_abstract(_Tp)> + { }; + + /// has_virtual_destructor + template<typename _Tp> + struct has_virtual_destructor + : public integral_constant<bool, __has_virtual_destructor(_Tp)> + { }; + + /// alignment_of + template<typename _Tp> + struct alignment_of + : public integral_constant<std::size_t, __alignof__(_Tp)> { }; + + /// rank + template<typename> + struct rank + : public integral_constant<std::size_t, 0> { }; + + template<typename _Tp, std::size_t _Size> + struct rank<_Tp[_Size]> + : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; + + template<typename _Tp> + struct rank<_Tp[]> + : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; + + /// extent + template<typename, unsigned _Uint = 0> + struct extent + : public integral_constant<std::size_t, 0> { }; + + template<typename _Tp, unsigned _Uint, std::size_t _Size> + struct extent<_Tp[_Size], _Uint> + : public integral_constant<std::size_t, + _Uint == 0 ? _Size : extent<_Tp, + _Uint - 1>::value> + { }; + + template<typename _Tp, unsigned _Uint> + struct extent<_Tp[], _Uint> + : public integral_constant<std::size_t, + _Uint == 0 ? 0 : extent<_Tp, + _Uint - 1>::value> + { }; + + // relationships between types [4.6]. + + /// is_same + template<typename, typename> + struct is_same + : public false_type { }; + + template<typename _Tp> + struct is_same<_Tp, _Tp> + : public true_type { }; + + // const-volatile modifications [4.7.1]. + + /// remove_const + template<typename _Tp> + struct remove_const + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_const<_Tp const> + { typedef _Tp type; }; + + /// remove_volatile + template<typename _Tp> + struct remove_volatile + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_volatile<_Tp volatile> + { typedef _Tp type; }; + + /// remove_cv + template<typename _Tp> + struct remove_cv + { + typedef typename + remove_const<typename remove_volatile<_Tp>::type>::type type; + }; + + /// add_const + template<typename _Tp> + struct add_const + { typedef _Tp const type; }; + + /// add_volatile + template<typename _Tp> + struct add_volatile + { typedef _Tp volatile type; }; + + /// add_cv + template<typename _Tp> + struct add_cv + { + typedef typename + add_const<typename add_volatile<_Tp>::type>::type type; + }; + + // array modifications [4.7.3]. + + /// remove_extent + template<typename _Tp> + struct remove_extent + { typedef _Tp type; }; + + template<typename _Tp, std::size_t _Size> + struct remove_extent<_Tp[_Size]> + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_extent<_Tp[]> + { typedef _Tp type; }; + + /// remove_all_extents + template<typename _Tp> + struct remove_all_extents + { typedef _Tp type; }; + + template<typename _Tp, std::size_t _Size> + struct remove_all_extents<_Tp[_Size]> + { typedef typename remove_all_extents<_Tp>::type type; }; + + template<typename _Tp> + struct remove_all_extents<_Tp[]> + { typedef typename remove_all_extents<_Tp>::type type; }; + + // pointer modifications [4.7.4]. + + template<typename _Tp, typename> + struct __remove_pointer_helper + { typedef _Tp type; }; + + template<typename _Tp, typename _Up> + struct __remove_pointer_helper<_Tp, _Up*> + { typedef _Up type; }; + + /// remove_pointer + template<typename _Tp> + struct remove_pointer + : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> + { }; + + template<typename> + struct remove_reference; + + /// add_pointer + template<typename _Tp> + struct add_pointer + { typedef typename remove_reference<_Tp>::type* type; }; + + template<typename> + struct is_reference + : public false_type { }; + + template<typename _Tp> + struct is_reference<_Tp&> + : public true_type { }; + + template<typename _Tp> + struct is_pod + : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value> + { }; + + template<typename _Tp> + struct has_trivial_constructor + : public integral_constant<bool, is_pod<_Tp>::value> + { }; + + template<typename _Tp> + struct has_trivial_copy + : public integral_constant<bool, is_pod<_Tp>::value> + { }; + + template<typename _Tp> + struct has_trivial_assign + : public integral_constant<bool, is_pod<_Tp>::value> + { }; + + template<typename _Tp> + struct has_trivial_destructor + : public integral_constant<bool, is_pod<_Tp>::value> + { }; + + template<typename _Tp> + struct has_nothrow_constructor + : public integral_constant<bool, is_pod<_Tp>::value> + { }; + + template<typename _Tp> + struct has_nothrow_copy + : public integral_constant<bool, is_pod<_Tp>::value> + { }; + + template<typename _Tp> + struct has_nothrow_assign + : public integral_constant<bool, is_pod<_Tp>::value> + { }; + + template<typename> + struct __is_signed_helper + : public false_type { }; + _DEFINE_SPEC(0, __is_signed_helper, signed char, true) + _DEFINE_SPEC(0, __is_signed_helper, short, true) + _DEFINE_SPEC(0, __is_signed_helper, int, true) + _DEFINE_SPEC(0, __is_signed_helper, long, true) + _DEFINE_SPEC(0, __is_signed_helper, long long, true) + + template<typename _Tp> + struct is_signed + : public integral_constant<bool, (__is_signed_helper<typename + remove_cv<_Tp>::type>::value)> + { }; + + template<typename> + struct __is_unsigned_helper + : public false_type { }; + _DEFINE_SPEC(0, __is_unsigned_helper, unsigned char, true) + _DEFINE_SPEC(0, __is_unsigned_helper, unsigned short, true) + _DEFINE_SPEC(0, __is_unsigned_helper, unsigned int, true) + _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long, true) + _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long long, true) + + template<typename _Tp> + struct is_unsigned + : public integral_constant<bool, (__is_unsigned_helper<typename + remove_cv<_Tp>::type>::value)> + { }; + + template<typename _Base, typename _Derived> + struct __is_base_of_helper + { + typedef typename remove_cv<_Base>::type _NoCv_Base; + typedef typename remove_cv<_Derived>::type _NoCv_Derived; + static const bool __value = (is_same<_Base, _Derived>::value + || (__is_base_of(_Base, _Derived) + && !is_same<_NoCv_Base, + _NoCv_Derived>::value)); + }; + + template<typename _Base, typename _Derived> + struct is_base_of + : public integral_constant<bool, + __is_base_of_helper<_Base, _Derived>::__value> + { }; + + template<typename _From, typename _To> + struct __is_convertible_simple + : public __sfinae_types + { + private: + static __one __test(_To); + static __two __test(...); + static _From __makeFrom(); + + public: + static const bool __value = sizeof(__test(__makeFrom())) == 1; + }; + + template<typename _Tp> + struct add_reference; + + template<typename _Tp> + struct __is_int_or_cref + { + typedef typename remove_reference<_Tp>::type __rr_Tp; + static const bool __value = (is_integral<_Tp>::value + || (is_integral<__rr_Tp>::value + && is_const<__rr_Tp>::value + && !is_volatile<__rr_Tp>::value)); + }; + + template<typename _From, typename _To, + bool = (is_void<_From>::value || is_void<_To>::value + || is_function<_To>::value || is_array<_To>::value + // This special case is here only to avoid warnings. + || (is_floating_point<typename + remove_reference<_From>::type>::value + && __is_int_or_cref<_To>::__value))> + struct __is_convertible_helper + { + // "An imaginary lvalue of type From...". + static const bool __value = (__is_convertible_simple<typename + add_reference<_From>::type, _To>::__value); + }; + + template<typename _From, typename _To> + struct __is_convertible_helper<_From, _To, true> + { static const bool __value = (is_void<_To>::value + || (__is_int_or_cref<_To>::__value + && !is_void<_From>::value)); }; + + template<typename _From, typename _To> + struct is_convertible + : public integral_constant<bool, + __is_convertible_helper<_From, _To>::__value> + { }; + + // reference modifications [4.7.2]. + template<typename _Tp> + struct remove_reference + { typedef _Tp type; }; + + template<typename _Tp> + struct remove_reference<_Tp&> + { typedef _Tp type; }; + + // NB: Careful with reference to void. + template<typename _Tp, bool = (is_void<_Tp>::value + || is_reference<_Tp>::value)> + struct __add_reference_helper + { typedef _Tp& type; }; + + template<typename _Tp> + struct __add_reference_helper<_Tp, true> + { typedef _Tp type; }; + + template<typename _Tp> + struct add_reference + : public __add_reference_helper<_Tp> + { }; + + // other transformations [4.8]. + template<std::size_t _Len, std::size_t _Align> + struct aligned_storage + { + union type + { + unsigned char __data[_Len]; + struct __attribute__((__aligned__((_Align)))) { } __align; + }; + }; + +#undef _DEFINE_SPEC_0_HELPER +#undef _DEFINE_SPEC_1_HELPER +#undef _DEFINE_SPEC_2_HELPER +#undef _DEFINE_SPEC + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_TYPE_TRAITS diff --git a/libstdc++-v3/include/tr1/unordered_map b/libstdc++-v3/include/tr1/unordered_map new file mode 100644 index 000000000..50bab9e4a --- /dev/null +++ b/libstdc++-v3/include/tr1/unordered_map @@ -0,0 +1,44 @@ +// TR1 unordered_map -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/unordered_map + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_UNORDERED_MAP +#define _GLIBCXX_TR1_UNORDERED_MAP 1 + +#pragma GCC system_header + +#include <utility> +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_function.h> // equal_to, _Identity, _Select1st +#include <bits/stringfwd.h> +#include <tr1/type_traits> +#include <tr1/functional_hash.h> +#include <tr1/hashtable.h> +#include <tr1/unordered_map.h> + +#endif // _GLIBCXX_TR1_UNORDERED_MAP diff --git a/libstdc++-v3/include/tr1/unordered_map.h b/libstdc++-v3/include/tr1/unordered_map.h new file mode 100644 index 000000000..96404d3d0 --- /dev/null +++ b/libstdc++-v3/include/tr1/unordered_map.h @@ -0,0 +1,278 @@ +// TR1 unordered_map implementation -*- C++ -*- + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/unordered_map.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/unordered_map} + */ + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // NB: When we get typedef templates these class definitions + // will be unnecessary. + template<class _Key, class _Tp, + class _Hash = hash<_Key>, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, + bool __cache_hash_code = false> + class __unordered_map + : public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, true> + { + typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, true> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + __unordered_map(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + + template<typename _InputIterator> + __unordered_map(_InputIterator __f, _InputIterator __l, + size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + }; + + template<class _Key, class _Tp, + class _Hash = hash<_Key>, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, + bool __cache_hash_code = false> + class __unordered_multimap + : public _Hashtable<_Key, std::pair<const _Key, _Tp>, + _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, false> + { + typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, + _Alloc, + std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, false, false> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + __unordered_multimap(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + + + template<typename _InputIterator> + __unordered_multimap(_InputIterator __f, _InputIterator __l, + typename _Base::size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), + __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + { } + }; + + template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap(__unordered_map<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __x, + __unordered_map<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + + template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap(__unordered_multimap<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __x, + __unordered_multimap<_Key, _Tp, _Hash, _Pred, + _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + + + /** + * @brief A standard container composed of unique keys (containing + * at most one of each key value) that associates values of another type + * with the keys. + * + * @ingroup unordered_associative_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, and + * <a href="tables.html#xx">unordered associative container</a> + * + * @param Key Type of key objects. + * @param Tp Type of mapped objects. + * @param Hash Hashing function object type, defaults to hash<Value>. + * @param Pred Predicate function object type, defaults to equal_to<Value>. + * @param Alloc Allocator type, defaults to allocator<Key>. + * + * The resulting value type of the container is std::pair<const Key, Tp>. + */ + template<class _Key, class _Tp, + class _Hash = hash<_Key>, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > + class unordered_map + : public __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> + { + typedef __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> _Base; + + public: + typedef typename _Base::value_type value_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_map(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template<typename _InputIterator> + unordered_map(_InputIterator __f, _InputIterator __l, + size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __eql, __a) + { } + }; + + /** + * @brief A standard container composed of equivalent keys + * (possibly containing multiple of each key value) that associates + * values of another type with the keys. + * + * @ingroup unordered_associative_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, and + * <a href="tables.html#xx">unordered associative container</a> + * + * @param Key Type of key objects. + * @param Tp Type of mapped objects. + * @param Hash Hashing function object type, defaults to hash<Value>. + * @param Pred Predicate function object type, defaults to equal_to<Value>. + * @param Alloc Allocator type, defaults to allocator<Key>. + * + * The resulting value type of the container is std::pair<const Key, Tp>. + */ + template<class _Key, class _Tp, + class _Hash = hash<_Key>, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > + class unordered_multimap + : public __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> + { + typedef __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> _Base; + + public: + typedef typename _Base::value_type value_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_multimap(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + + template<typename _InputIterator> + unordered_multimap(_InputIterator __f, _InputIterator __l, + typename _Base::size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __eql, __a) + { } + + }; + + template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> + inline void + swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + + template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> + inline void + swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NAMESPACE_VERSION +} +} diff --git a/libstdc++-v3/include/tr1/unordered_set b/libstdc++-v3/include/tr1/unordered_set new file mode 100644 index 000000000..3e2cbb039 --- /dev/null +++ b/libstdc++-v3/include/tr1/unordered_set @@ -0,0 +1,44 @@ +// TR1 unordered_set -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/unordered_set + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_UNORDERED_SET +#define _GLIBCXX_TR1_UNORDERED_SET 1 + +#pragma GCC system_header + +#include <utility> +#include <bits/stl_algobase.h> +#include <bits/allocator.h> +#include <bits/stl_function.h> // equal_to, _Identity, _Select1st +#include <bits/stringfwd.h> +#include <tr1/type_traits> +#include <tr1/functional_hash.h> +#include <tr1/hashtable.h> +#include <tr1/unordered_set.h> + +#endif // _GLIBCXX_TR1_UNORDERED_SET diff --git a/libstdc++-v3/include/tr1/unordered_set.h b/libstdc++-v3/include/tr1/unordered_set.h new file mode 100644 index 000000000..e65a4cced --- /dev/null +++ b/libstdc++-v3/include/tr1/unordered_set.h @@ -0,0 +1,267 @@ +// TR1 unordered_set implementation -*- C++ -*- + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/unordered_set.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr1/unordered_set} + */ + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // NB: When we get typedef templates these class definitions + // will be unnecessary. + template<class _Value, + class _Hash = hash<_Value>, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value>, + bool __cache_hash_code = false> + class __unordered_set + : public _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, true> + { + typedef _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, true> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + __unordered_set(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + + template<typename _InputIterator> + __unordered_set(_InputIterator __f, _InputIterator __l, + size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + }; + + template<class _Value, + class _Hash = hash<_Value>, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value>, + bool __cache_hash_code = false> + class __unordered_multiset + : public _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, false> + { + typedef _Hashtable<_Value, _Value, _Alloc, + std::_Identity<_Value>, _Pred, + _Hash, __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, + __cache_hash_code, true, false> + _Base; + + public: + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + __unordered_multiset(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + + + template<typename _InputIterator> + __unordered_multiset(_InputIterator __f, _InputIterator __l, + typename _Base::size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), + __detail::_Default_ranged_hash(), __eql, + std::_Identity<_Value>(), __a) + { } + }; + + template<class _Value, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap(__unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __x, + __unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + + template<class _Value, class _Hash, class _Pred, class _Alloc, + bool __cache_hash_code> + inline void + swap(__unordered_multiset<_Value, _Hash, _Pred, + _Alloc, __cache_hash_code>& __x, + __unordered_multiset<_Value, _Hash, _Pred, + _Alloc, __cache_hash_code>& __y) + { __x.swap(__y); } + + + /** + * @brief A standard container composed of unique keys (containing + * at most one of each key value) in which the elements' keys are + * the elements themselves. + * + * @ingroup unordered_associative_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, and + * <a href="tables.html#xx">unordered associative container</a> + * + * @param Value Type of key objects. + * @param Hash Hashing function object type, defaults to hash<Value>. + * @param Pred Predicate function object type, defaults to equal_to<Value>. + * @param Alloc Allocator type, defaults to allocator<Key>. + */ + template<class _Value, + class _Hash = hash<_Value>, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class unordered_set + : public __unordered_set<_Value, _Hash, _Pred, _Alloc> + { + typedef __unordered_set<_Value, _Hash, _Pred, _Alloc> _Base; + + public: + typedef typename _Base::value_type value_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_set(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template<typename _InputIterator> + unordered_set(_InputIterator __f, _InputIterator __l, + size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __eql, __a) + { } + }; + + /** + * @brief A standard container composed of equivalent keys + * (possibly containing multiple of each key value) in which the + * elements' keys are the elements themselves. + * + * @ingroup unordered_associative_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, and + * <a href="tables.html#xx">unordered associative container</a> + * + * @param Value Type of key objects. + * @param Hash Hashing function object type, defaults to hash<Value>. + * @param Pred Predicate function object type, defaults to equal_to<Value>. + * @param Alloc Allocator type, defaults to allocator<Key>. + */ + template<class _Value, + class _Hash = hash<_Value>, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class unordered_multiset + : public __unordered_multiset<_Value, _Hash, _Pred, _Alloc> + { + typedef __unordered_multiset<_Value, _Hash, _Pred, _Alloc> _Base; + + public: + typedef typename _Base::value_type value_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; + + explicit + unordered_multiset(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + + template<typename _InputIterator> + unordered_multiset(_InputIterator __f, _InputIterator __l, + typename _Base::size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Base(__f, __l, __n, __hf, __eql, __a) + { } + }; + + template<class _Value, class _Hash, class _Pred, class _Alloc> + inline void + swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, + unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + + template<class _Value, class _Hash, class _Pred, class _Alloc> + inline void + swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, + unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + +_GLIBCXX_END_NAMESPACE_VERSION +} +} diff --git a/libstdc++-v3/include/tr1/utility b/libstdc++-v3/include/tr1/utility new file mode 100644 index 000000000..ef3673a44 --- /dev/null +++ b/libstdc++-v3/include/tr1/utility @@ -0,0 +1,109 @@ +// TR1 utility -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007, 2008. 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/utility + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_UTILITY +#define _GLIBCXX_TR1_UTILITY 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/stl_relops.h> +#include <bits/stl_pair.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr1 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<class _Tp> + class tuple_size; + + template<int _Int, class _Tp> + class tuple_element; + + // Various functions which give std::pair a tuple-like interface. + template<class _Tp1, class _Tp2> + struct tuple_size<std::pair<_Tp1, _Tp2> > + { static const int value = 2; }; + + template<class _Tp1, class _Tp2> + const int + tuple_size<std::pair<_Tp1, _Tp2> >::value; + + template<class _Tp1, class _Tp2> + struct tuple_element<0, std::pair<_Tp1, _Tp2> > + { typedef _Tp1 type; }; + + template<class _Tp1, class _Tp2> + struct tuple_element<1, std::pair<_Tp1, _Tp2> > + { typedef _Tp2 type; }; + + template<int _Int> + struct __pair_get; + + template<> + struct __pair_get<0> + { + template<typename _Tp1, typename _Tp2> + static _Tp1& __get(std::pair<_Tp1, _Tp2>& __pair) + { return __pair.first; } + + template<typename _Tp1, typename _Tp2> + static const _Tp1& __const_get(const std::pair<_Tp1, _Tp2>& __pair) + { return __pair.first; } + }; + + template<> + struct __pair_get<1> + { + template<typename _Tp1, typename _Tp2> + static _Tp2& __get(std::pair<_Tp1, _Tp2>& __pair) + { return __pair.second; } + + template<typename _Tp1, typename _Tp2> + static const _Tp2& __const_get(const std::pair<_Tp1, _Tp2>& __pair) + { return __pair.second; } + }; + + template<int _Int, class _Tp1, class _Tp2> + inline typename tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& + get(std::pair<_Tp1, _Tp2>& __in) + { return __pair_get<_Int>::__get(__in); } + + template<int _Int, class _Tp1, class _Tp2> + inline const typename tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& + get(const std::pair<_Tp1, _Tp2>& __in) + { return __pair_get<_Int>::__const_get(__in); } + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR1_UTILITY diff --git a/libstdc++-v3/include/tr1/wchar.h b/libstdc++-v3/include/tr1/wchar.h new file mode 100644 index 000000000..599604896 --- /dev/null +++ b/libstdc++-v3/include/tr1/wchar.h @@ -0,0 +1,34 @@ +// TR1 wchar.h -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/wchar.h + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_WCHAR_H +#define _GLIBCXX_TR1_WCHAR_H 1 + +#include <tr1/cwchar> + +#endif // _GLIBCXX_TR1_WCHAR_H diff --git a/libstdc++-v3/include/tr1/wctype.h b/libstdc++-v3/include/tr1/wctype.h new file mode 100644 index 000000000..604948a58 --- /dev/null +++ b/libstdc++-v3/include/tr1/wctype.h @@ -0,0 +1,34 @@ +// TR1 wctype.h -*- C++ -*- + +// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr1/wctype.h + * This is a TR1 C++ Library header. + */ + +#ifndef _GLIBCXX_TR1_WCTYPE_H +#define _GLIBCXX_TR1_WCTYPE_H 1 + +#include <tr1/cwctype> + +#endif // _GLIBCXX_TR1_WCTYPE_H |