[cfe-commits] [libcxx] r104708 - in /libcxx/trunk: include/algorithm include/random src/algorithm.cpp test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.pass.cpp test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_rand.pass.cpp test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_urng.pass.cpp

Howard Hinnant hhinnant at apple.com
Wed May 26 10:49:34 PDT 2010


Author: hhinnant
Date: Wed May 26 12:49:34 2010
New Revision: 104708

URL: http://llvm.org/viewvc/llvm-project?rev=104708&view=rev
Log:
Completed [alg.random.shuffle].

Modified:
    libcxx/trunk/include/algorithm
    libcxx/trunk/include/random
    libcxx/trunk/src/algorithm.cpp
    libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.pass.cpp
    libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_rand.pass.cpp
    libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_urng.pass.cpp

Modified: libcxx/trunk/include/algorithm
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/algorithm?rev=104708&r1=104707&r2=104708&view=diff
==============================================================================
--- libcxx/trunk/include/algorithm (original)
+++ libcxx/trunk/include/algorithm Wed May 26 12:49:34 2010
@@ -254,6 +254,10 @@
     void
     random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand);
 
+template<class RandomAccessIterator, class UniformRandomNumberGenerator>
+    void shuffle(RandomAccessIterator first, RandomAccessIterator last,
+                 UniformRandomNumberGenerator& g);
+
 template <class InputIterator, class Predicate>
     bool
     is_partitioned(InputIterator first, InputIterator last, Predicate pred);
@@ -2277,132 +2281,286 @@
 
 // random_shuffle
 
-template <unsigned int _Bits>
-struct __num_bits
+// __independent_bits_engine
+
+template <unsigned long long _X, size_t _R>
+struct __log2_imp
 {
-    static const int __value = 1 + __num_bits<(_Bits >> 1)>::__value;
+    static const size_t value = _X & ((unsigned long long)(1) << _R) ? _R
+                                           : __log2_imp<_X, _R - 1>::value;
 };
 
-template <>
-struct __num_bits<0>
+template <unsigned long long _X>
+struct __log2_imp<_X, 0>
 {
-    static const int __value = 0;
+    static const size_t value = 0;
 };
 
-const int __rbits = __num_bits<RAND_MAX>::__value;
-const int __lbits = static_cast<int>(sizeof(unsigned long) * __CHAR_BIT__);
-
-template <int _NBits, bool = _NBits <= __rbits>
-struct __random_bits
+template <size_t _R>
+struct __log2_imp<0, _R>
 {
-    _LIBCPP_INLINE_VISIBILITY operator unsigned long () const
-        {return static_cast<unsigned long>(_STD::rand()) >> (__rbits - _NBits);}
+    static const size_t value = _R + 1;
 };
 
-template <int _NBits>
-struct __random_bits<_NBits, false>
+template <class _UI, _UI _X>
+struct __log2
 {
-    _LIBCPP_INLINE_VISIBILITY operator unsigned long () const
-        {return static_cast<unsigned long>(_STD::rand()) << (_NBits - __rbits) | __random_bits<_NBits - __rbits>();}
+    static const size_t value = __log2_imp<_X,
+                                         sizeof(_UI) * __CHAR_BIT__ - 1>::value;
 };
 
-template <int _NBits>
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long
-__slab_size(unsigned long __n)
+template<class _Engine, class _UIntType>
+class __independent_bits_engine
 {
-    return (1UL << _NBits) / __n;
+public:
+    // types
+    typedef _UIntType result_type;
+
+private:
+    typedef typename _Engine::result_type _Engine_result_type;
+    typedef typename conditional
+        <
+            sizeof(_Engine_result_type) <= sizeof(result_type),
+                result_type,
+                _Engine_result_type
+        >::type _Working_result_type;
+
+    _Engine& __e_;
+    size_t __w_;
+    size_t __w0_;
+    size_t __n_;
+    size_t __n0_;
+    _Working_result_type __y0_;
+    _Working_result_type __y1_;
+    _Engine_result_type __mask0_;
+    _Engine_result_type __mask1_;
+
+    static const _Working_result_type _R = _Engine::_Max - _Engine::_Min
+                                                         + _Working_result_type(1);
+    static const size_t __m = __log2<_Working_result_type, _R>::value;
+    static const size_t _WDt = numeric_limits<_Working_result_type>::digits;
+    static const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
+
+public:
+    // constructors and seeding functions
+    __independent_bits_engine(_Engine& __e, size_t __w);
+
+    // generating functions
+    result_type operator()() {return __eval(integral_constant<bool, _R != 0>());}
+
+private:
+    result_type __eval(false_type);
+    result_type __eval(true_type);
+};
+
+template<class _Engine, class _UIntType>
+__independent_bits_engine<_Engine, _UIntType>
+    ::__independent_bits_engine(_Engine& __e, size_t __w)
+        : __e_(__e),
+          __w_(__w)
+{
+    __n_ = __w_ / __m + (__w_ % __m != 0);
+    __w0_ = __w_ / __n_;
+    if (_R == 0)
+        __y0_ = _R;
+    else if (__w0_ < _WDt)
+        __y0_ = (_R >> __w0_) << __w0_;
+    else
+        __y0_ = 0;
+    if (_R - __y0_ > __y0_ / __n_)
+    {
+        ++__n_;
+        __w0_ = __w_ / __n_;
+        if (__w0_ < _WDt)
+            __y0_ = (_R >> __w0_) << __w0_;
+        else
+            __y0_ = 0;
+    }
+    __n0_ = __n_ - __w_ % __n_;
+    if (__w0_ < _WDt - 1)
+        __y1_ = (_R >> (__w0_ + 1)) << (__w0_ + 1);
+    else
+        __y1_ = 0;
+    __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
+                          _Engine_result_type(0);
+    __mask1_ = __w0_ < _EDt - 1 ?
+                               _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
+                               _Engine_result_type(~0);
 }
 
-template <>
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long
-__slab_size<__lbits>(unsigned long __n)
+template<class _Engine, class _UIntType>
+inline
+_UIntType
+__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)
 {
-    if (__n & 1)
-        return (unsigned long)(~0) / __n;
-    return (1UL << (__lbits-1)) / (__n >> 1);
+    return static_cast<result_type>(__e_() & __mask0_);
 }
 
-template <int _NBits>
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long
-__scaled_random_number(unsigned long __n)
+template<class _Engine, class _UIntType>
+_UIntType
+__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
 {
-    const unsigned long __slab = __slab_size<_NBits>(__n);
-    const unsigned long __usable = __slab * __n;
-    unsigned long __raw;
-    do
-        __raw = __random_bits<_NBits>();
-    while (__raw >= __usable);
-    return __raw / __slab;
+    result_type _S = 0;
+    for (size_t __k = 0; __k < __n0_; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y0_);
+        if (__w0_ < _EDt)
+            _S <<= __w0_;
+        else
+            _S = 0;
+        _S += __u & __mask0_;
+    }
+    for (size_t __k = __n0_; __k < __n_; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y1_);
+        if (__w0_ < _EDt - 1)
+            _S <<= __w0_ + 1;
+        else
+            _S = 0;
+        _S += __u & __mask1_;
+    }
+    return _S;
 }
 
-template <bool __b, unsigned long = __lbits/__rbits> struct __rs_default;
+// uniform_int_distribution
 
-template <bool __b>
-struct __rs_default<__b, 1>
+template<class _IntType = int>
+class uniform_int_distribution
 {
-    unsigned long operator()(unsigned long __n = 0) const;
+public:
+    // types
+    typedef _IntType result_type;
+
+    class param_type
+    {
+        result_type __a_;
+        result_type __b_;
+    public:
+        typedef uniform_int_distribution distribution_type;
+
+        explicit param_type(result_type __a = 0,
+                            result_type __b = numeric_limits<result_type>::max())
+            : __a_(__a), __b_(__b) {}
+
+        result_type a() const {return __a_;}
+        result_type b() const {return __b_;}
+
+        friend bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
+        friend bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    explicit uniform_int_distribution(result_type __a = 0,
+                                      result_type __b = numeric_limits<result_type>::max())
+        : __p_(param_type(__a, __b)) {}
+    explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
+    void reset() {}
+
+    // generating functions
+    template<class _URNG> result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    result_type a() const {return __p_.a();}
+    result_type b() const {return __p_.b();}
+
+    param_type param() const {return __p_;}
+    void param(const param_type& __p) {__p_ = __p;}
+
+    result_type min() const {return a();}
+    result_type max() const {return b();}
+
+    friend bool operator==(const uniform_int_distribution& __x,
+                           const uniform_int_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend bool operator!=(const uniform_int_distribution& __x,
+                           const uniform_int_distribution& __y)
+            {return !(__x == __y);}
 };
 
-template <bool __b>
-unsigned long
-__rs_default<__b, 1>::operator()(unsigned long __n) const
-{
-    switch (__n)
+template<class _IntType>
+template<class _URNG>
+typename uniform_int_distribution<_IntType>::result_type
+uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
+{
+    typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
+                                            uint32_t, uint64_t>::type _UIntType;
+    const _UIntType _R = __p.b() - __p.a() + _UIntType(1);
+    if (_R == 1)
+        return __p.a();
+    const size_t _Dt = numeric_limits<_UIntType>::digits;
+    typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
+    if (_R == 0)
+        return static_cast<result_type>(_Eng(__g, _Dt)());
+    size_t __w = _Dt - __clz(_R) - 1;
+    if ((_R & (_UIntType(~0) >> (_Dt - __w))) != 0)
+        ++__w;
+    _Eng __e(__g, __w);
+    _UIntType __u;
+    do
     {
-    case 0:
-        return __random_bits<__lbits>();
-    case 1:
-        return 0;
-    }
-    if (__n <= (1UL << __rbits))
-        return __scaled_random_number<__rbits>(__n);
-    return __scaled_random_number<__lbits>(__n);
+        __u = __e();
+    } while (__u >= _R);
+    return static_cast<result_type>(__u + __p.a());
 }
 
-template <bool __b>
-struct __rs_default<__b, 2>
+class __rs_default;
+
+__rs_default __rs_get();
+
+class __rs_default
 {
-    unsigned long operator()(unsigned long __n = 0) const;
+    static unsigned __c_;
+
+    __rs_default();
+public:
+    typedef unsigned result_type;
+
+    static const result_type _Min = 0;
+    static const result_type _Max = 0xFFFFFFFF;
+
+    __rs_default(const __rs_default&);
+    ~__rs_default();
+
+    result_type operator()();
+
+    static const/*expr*/ result_type min() {return _Min;}
+    static const/*expr*/ result_type max() {return _Max;}
+
+    friend __rs_default __rs_get();
 };
 
-template <bool __b>
-unsigned long
-__rs_default<__b, 2>::operator()(unsigned long __n) const
-{
-    switch (__n)
-    {
-    case 0:
-        return __random_bits<__lbits>();
-    case 1:
-        return 0;
-    }
-    int __nb = __rbits;
-    while (__nb < __lbits && __n > (1UL << __nb))
-        __nb += _STD::min(__rbits, __lbits - __nb);
-    switch (__nb)
-    {
-    case __rbits:
-        return __scaled_random_number<__rbits>(__n);
-    case 2*__rbits:
-        return __scaled_random_number<2*__rbits>(__n);
-    }
-    return __scaled_random_number<__lbits>(__n);
-}
+__rs_default __rs_get();
 
 template <class _RandomAccessIterator>
 void
 random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
 {
     typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef uniform_int_distribution<ptrdiff_t> _D;
+    typedef typename _D::param_type _P;
     difference_type __d = __last - __first;
     if (__d > 1)
     {
-        for (--__last; __first < __last; ++__first, --__d)
-            swap(*__first, *(__first
-                + static_cast<difference_type>(__rs_default<true>()(static_cast<unsigned long>(__d)))));
+        _D __uid;
+        __rs_default __g = __rs_get();
+        for (--__last, --__d; __first < __last; ++__first, --__d)
+            swap(*__first, *(__first + __uid(__g, _P(0, __d))));
     }
 }
 
@@ -2424,6 +2582,22 @@
     }
 }
 
+template<class _RandomAccessIterator, class _UniformRandomNumberGenerator>
+    void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
+                 _UniformRandomNumberGenerator& __g)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef uniform_int_distribution<ptrdiff_t> _D;
+    typedef typename _D::param_type _P;
+    difference_type __d = __last - __first;
+    if (__d > 1)
+    {
+        _D __uid;
+        for (--__last, --__d; __first < __last; ++__first, --__d)
+            swap(*__first, *(__first + __uid(__g, _P(0, __d))));
+    }
+}
+
 template <class _InputIterator, class _Predicate>
 bool
 is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)

Modified: libcxx/trunk/include/random
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/random?rev=104708&r1=104707&r2=104708&view=diff
==============================================================================
--- libcxx/trunk/include/random (original)
+++ libcxx/trunk/include/random Wed May 26 12:49:34 2010
@@ -2793,32 +2793,6 @@
 
 // independent_bits_engine
 
-template <unsigned long long _X, size_t _R>
-struct __log2_imp
-{
-    static const size_t value = _X & ((unsigned long long)(1) << _R) ? _R
-                                           : __log2_imp<_X, _R - 1>::value;
-};
-
-template <unsigned long long _X>
-struct __log2_imp<_X, 0>
-{
-    static const size_t value = 0;
-};
-
-template <size_t _R>
-struct __log2_imp<0, _R>
-{
-    static const size_t value = _R + 1;
-};
-
-template <class _UI, _UI _X>
-struct __log2
-{
-    static const size_t value = __log2_imp<_X,
-                                         sizeof(_UI) * __CHAR_BIT__ - 1>::value;
-};
-
 template<class _Engine, size_t __w, class _UIntType>
 class independent_bits_engine
 {
@@ -3396,217 +3370,9 @@
     return _S / __base;
 }
 
-// __independent_bits_engine
-
-template<class _Engine, class _UIntType>
-class __independent_bits_engine
-{
-public:
-    // types
-    typedef _UIntType result_type;
-
-private:
-    typedef typename _Engine::result_type _Engine_result_type;
-    typedef typename conditional
-        <
-            sizeof(_Engine_result_type) <= sizeof(result_type),
-                result_type,
-                _Engine_result_type
-        >::type _Working_result_type;
-
-    _Engine& __e_;
-    size_t __w_;
-    size_t __w0_;
-    size_t __n_;
-    size_t __n0_;
-    _Working_result_type __y0_;
-    _Working_result_type __y1_;
-    _Engine_result_type __mask0_;
-    _Engine_result_type __mask1_;
-
-    static const _Working_result_type _R = _Engine::_Max - _Engine::_Min
-                                                         + _Working_result_type(1);
-    static const size_t __m = __log2<_Working_result_type, _R>::value;
-    static const size_t _WDt = numeric_limits<_Working_result_type>::digits;
-    static const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
-
-public:
-    // constructors and seeding functions
-    __independent_bits_engine(_Engine& __e, size_t __w);
-
-    // generating functions
-    result_type operator()() {return __eval(integral_constant<bool, _R != 0>());}
-
-private:
-    result_type __eval(false_type);
-    result_type __eval(true_type);
-};
-
-template<class _Engine, class _UIntType>
-__independent_bits_engine<_Engine, _UIntType>
-    ::__independent_bits_engine(_Engine& __e, size_t __w)
-        : __e_(__e),
-          __w_(__w)
-{
-    __n_ = __w_ / __m + (__w_ % __m != 0);
-    __w0_ = __w_ / __n_;
-    if (_R == 0)
-        __y0_ = _R;
-    else if (__w0_ < _WDt)
-        __y0_ = (_R >> __w0_) << __w0_;
-    else
-        __y0_ = 0;
-    if (_R - __y0_ > __y0_ / __n_)
-    {
-        ++__n_;
-        __w0_ = __w_ / __n_;
-        if (__w0_ < _WDt)
-            __y0_ = (_R >> __w0_) << __w0_;
-        else
-            __y0_ = 0;
-    }
-    __n0_ = __n_ - __w_ % __n_;
-    if (__w0_ < _WDt - 1)
-        __y1_ = (_R >> (__w0_ + 1)) << (__w0_ + 1);
-    else
-        __y1_ = 0;
-    __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
-                          _Engine_result_type(0);
-    __mask1_ = __w0_ < _EDt - 1 ?
-                               _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
-                               _Engine_result_type(~0);
-}
-
-template<class _Engine, class _UIntType>
-inline
-_UIntType
-__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)
-{
-    return static_cast<result_type>(__e_() & __mask0_);
-}
-
-template<class _Engine, class _UIntType>
-_UIntType
-__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
-{
-    result_type _S = 0;
-    for (size_t __k = 0; __k < __n0_; ++__k)
-    {
-        _Engine_result_type __u;
-        do
-        {
-            __u = __e_() - _Engine::min();
-        } while (__u >= __y0_);
-        if (__w0_ < _EDt)
-            _S <<= __w0_;
-        else
-            _S = 0;
-        _S += __u & __mask0_;
-    }
-    for (size_t __k = __n0_; __k < __n_; ++__k)
-    {
-        _Engine_result_type __u;
-        do
-        {
-            __u = __e_() - _Engine::min();
-        } while (__u >= __y1_);
-        if (__w0_ < _EDt - 1)
-            _S <<= __w0_ + 1;
-        else
-            _S = 0;
-        _S += __u & __mask1_;
-    }
-    return _S;
-}
-
 // uniform_int_distribution
 
-template<class _IntType = int>
-class uniform_int_distribution
-{
-public:
-    // types
-    typedef _IntType result_type;
-
-    class param_type
-    {
-        result_type __a_;
-        result_type __b_;
-    public:
-        typedef uniform_int_distribution distribution_type;
-
-        explicit param_type(result_type __a = 0,
-                            result_type __b = numeric_limits<result_type>::max())
-            : __a_(__a), __b_(__b) {}
-
-        result_type a() const {return __a_;}
-        result_type b() const {return __b_;}
-
-        friend bool operator==(const param_type& __x, const param_type& __y)
-            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
-        friend bool operator!=(const param_type& __x, const param_type& __y)
-            {return !(__x == __y);}
-    };
-
-private:
-    param_type __p_;
-
-public:
-    // constructors and reset functions
-    explicit uniform_int_distribution(result_type __a = 0,
-                                      result_type __b = numeric_limits<result_type>::max())
-        : __p_(param_type(__a, __b)) {}
-    explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
-    void reset() {}
-
-    // generating functions
-    template<class _URNG> result_type operator()(_URNG& __g)
-        {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
-
-    // property functions
-    result_type a() const {return __p_.a();}
-    result_type b() const {return __p_.b();}
-
-    param_type param() const {return __p_;}
-    void param(const param_type& __p) {__p_ = __p;}
-
-    result_type min() const {return a();}
-    result_type max() const {return b();}
-
-    friend bool operator==(const uniform_int_distribution& __x,
-                           const uniform_int_distribution& __y)
-        {return __x.__p_ == __y.__p_;}
-    friend bool operator!=(const uniform_int_distribution& __x,
-                           const uniform_int_distribution& __y)
-            {return !(__x == __y);}
-};
-
-template<class _IntType>
-template<class _URNG>
-typename uniform_int_distribution<_IntType>::result_type
-uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
-{
-    typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
-                                            uint32_t, uint64_t>::type _UIntType;
-    const _UIntType _R = __p.b() - __p.a() + _UIntType(1);
-    if (_R == 1)
-        return __p.a();
-    const size_t _Dt = numeric_limits<_UIntType>::digits;
-    typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
-    if (_R == 0)
-        return static_cast<result_type>(_Eng(__g, _Dt)());
-    size_t __w = _Dt - __clz(_R) - 1;
-    if ((_R & (_UIntType(~0) >> (_Dt - __w))) != 0)
-        ++__w;
-    _Eng __e(__g, __w);
-    _UIntType __u;
-    do
-    {
-        __u = __e();
-    } while (__u >= _R);
-    return static_cast<result_type>(__u + __p.a());
-}
+// in <algorithm>
 
 template <class _CharT, class _Traits, class _IT>
 basic_ostream<_CharT, _Traits>&

Modified: libcxx/trunk/src/algorithm.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/algorithm.cpp?rev=104708&r1=104707&r2=104708&view=diff
==============================================================================
--- libcxx/trunk/src/algorithm.cpp (original)
+++ libcxx/trunk/src/algorithm.cpp Wed May 26 12:49:34 2010
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "algorithm"
+#include "random"
+#include "mutex"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -45,4 +47,37 @@
 
 template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
 
+static pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER;
+unsigned __rs_default::__c_ = 0;
+
+__rs_default::__rs_default()
+{
+    pthread_mutex_lock(&__rs_mut);
+    __c_ = 1;
+}
+
+__rs_default::__rs_default(const __rs_default&)
+{
+    ++__c_;
+}
+
+__rs_default::~__rs_default()
+{
+    if (--__c_ == 0)
+        pthread_mutex_unlock(&__rs_mut);
+}
+
+__rs_default::result_type
+__rs_default::operator()()
+{
+    static mt19937 __rs_g;
+    return __rs_g();
+}
+
+__rs_default
+__rs_get()
+{
+    return __rs_default();
+}
+
 _LIBCPP_END_NAMESPACE_STD

Modified: libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.pass.cpp?rev=104708&r1=104707&r2=104708&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.pass.cpp Wed May 26 12:49:34 2010
@@ -15,12 +15,16 @@
 //   random_shuffle(Iter first, Iter last);
 
 #include <algorithm>
-
-#include "../../iterators.h"
+#include <cassert>
 
 int main()
 {
     int ia[] = {1, 2, 3, 4};
+    int ia1[] = {1, 4, 3, 2};
+    int ia2[] = {4, 1, 2, 3};
     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
     std::random_shuffle(ia, ia+sa);
+    assert(std::equal(ia, ia+sa, ia1));
+    std::random_shuffle(ia, ia+sa);
+    assert(std::equal(ia, ia+sa, ia2));
 }

Modified: libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_rand.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_rand.pass.cpp?rev=104708&r1=104707&r2=104708&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_rand.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_rand.pass.cpp Wed May 26 12:49:34 2010
@@ -16,21 +16,22 @@
 //   random_shuffle(Iter first, Iter last, Rand&& rand);
 
 #include <algorithm>
-
-#include "../../iterators.h"
+#include <cassert>
 
 struct gen
 {
     int operator()(int n)
     {
-        return 0;
+        return n-1;
     }
 };
 
 int main()
 {
     int ia[] = {1, 2, 3, 4};
+    int ia1[] = {4, 1, 2, 3};
     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
     gen r;
     std::random_shuffle(ia, ia+sa, r);
+    assert(std::equal(ia, ia+sa, ia1));
 }

Modified: libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_urng.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_urng.pass.cpp?rev=104708&r1=104707&r2=104708&view=diff
==============================================================================
--- libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_urng.pass.cpp (original)
+++ libcxx/trunk/test/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle_urng.pass.cpp Wed May 26 12:49:34 2010
@@ -9,14 +9,23 @@
 
 // <algorithm>
 
-// template<RandomAccessIterator Iter, UniformRandomNumberGenerator Rand> 
-//   void
-//   random_shuffle(Iter first, Iter last, Rand&& g);
+// template<class RandomAccessIterator, class UniformRandomNumberGenerator>
+//     void shuffle(RandomAccessIterator first, RandomAccessIterator last,
+//                  UniformRandomNumberGenerator& g);
 
 #include <algorithm>
-
-#error random_shuffle for UniformRandomNumberGenerator not implemented
+#include <random>
+#include <cassert>
 
 int main()
 {
+    int ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    int ia1[] = {2, 7, 1, 4, 3, 6, 5, 10, 9, 8};
+    int ia2[] = {1, 8, 3, 4, 6, 9, 5, 7, 2, 10};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    std::minstd_rand g;
+    std::shuffle(ia, ia+sa, g);
+    assert(std::equal(ia, ia+sa, ia1));
+    std::shuffle(ia, ia+sa, g);
+    assert(std::equal(ia, ia+sa, ia2));
 }





More information about the cfe-commits mailing list