From 085b55410d90cdfcd0733a16884aabb693a1f050 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 12 Nov 2008 09:59:27 +0000 Subject: [PATCH] PR libstdc++/37986 (cont) 2008-11-12 Paolo Carlini PR libstdc++/37986 (cont) * include/tr1_impl/random (struct _Adaptor): Use only remove_reference on _Engine. (struct _Adaptor<_Engine*, _Distribution>): Add. * testsuite/tr1/5_numerical_facilities/random/variate_generator/ 37986.cc: Extend. From-SVN: r141784 --- libstdc++-v3/ChangeLog | 9 +++ libstdc++-v3/include/tr1_impl/random | 71 +++++++++++++++++-- .../random/variate_generator/37986.cc | 4 ++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 191d27c743c..c089507e56f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2008-11-12 Paolo Carlini + + PR libstdc++/37986 (cont) + * include/tr1_impl/random (struct _Adaptor): Use only remove_reference + on _Engine. + (struct _Adaptor<_Engine*, _Distribution>): Add. + * testsuite/tr1/5_numerical_facilities/random/variate_generator/ + 37986.cc: Extend. + 2008-11-11 Paolo Carlini PR libstdc++/37986 diff --git a/libstdc++-v3/include/tr1_impl/random b/libstdc++-v3/include/tr1_impl/random index 9e30eb32795..dd9c57d162b 100644 --- a/libstdc++-v3/include/tr1_impl/random +++ b/libstdc++-v3/include/tr1_impl/random @@ -79,11 +79,9 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1 template struct _Adaptor { - typedef typename remove_reference< - typename remove_pointer<_Engine>::type>::type _BEngine; - - typedef typename _BEngine::result_type _Engine_result_type; - typedef typename _Distribution::input_type result_type; + 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) @@ -149,6 +147,69 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1 private: _Engine _M_g; }; + + // Specialization for _Engine*. + template + 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::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::value) + __return_value = _M_g->max(); + else if (!is_integral::value) + __return_value = result_type(1); + else + __return_value = std::numeric_limits::max() - 1; + return __return_value; + } + + result_type + operator()() + { + result_type __return_value; + if (is_integral<_Engine_result_type>::value + && is_integral::value) + __return_value = (*_M_g)(); + else if (!is_integral<_Engine_result_type>::value + && !is_integral::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::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::max()); + return __return_value; + } + + private: + _Engine* _M_g; + }; } // namespace __detail /** diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc index 50ca3b96ea3..38137f65a00 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc @@ -42,4 +42,8 @@ void test01() std::tr1::mt19937*, std::tr1::uniform_real > g3(&mt, dist); + + g1(); + g2(); + g3(); }