diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/tr1_impl/random | 71 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc | 4 |
3 files changed, 79 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 191d27c..c089507 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2008-11-12 Paolo Carlini <paolo.carlini@oracle.com> + + 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 <paolo.carlini@oracle.com> PR libstdc++/37986 diff --git a/libstdc++-v3/include/tr1_impl/random b/libstdc++-v3/include/tr1_impl/random index 9e30eb3..dd9c57d 100644 --- a/libstdc++-v3/include/tr1_impl/random +++ b/libstdc++-v3/include/tr1_impl/random @@ -79,11 +79,9 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1 template<typename _Engine, typename _Distribution> 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<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; + }; } // 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 50ca3b9..38137f6 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<double> > g3(&mt, dist); + + g1(); + g2(); + g3(); } |