1// Copyright Neil Groves 2009. Use, modification and
2// distribution is subject to the Boost Software License, Version
3// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5//
6//
7// For more information, see http://www.boost.org/libs/range/
8//
9#ifndef BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
10#define BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
11
12#include <boost/concept_check.hpp>
13#include <boost/range/begin.hpp>
14#include <boost/range/end.hpp>
15#include <boost/range/concepts.hpp>
16#include <algorithm>
17#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
18#include <cstdlib>
19#endif
20
21namespace boost
22{
23 namespace range
24 {
25
26 namespace detail
27 {
28#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
29
30// wrap std::rand as UniformRandomBitGenerator
31struct wrap_rand
32{
33 typedef unsigned int result_type;
34
35 static BOOST_CONSTEXPR result_type (min)()
36 {
37 return 0;
38 }
39
40 static BOOST_CONSTEXPR result_type (max)()
41 {
42 return RAND_MAX;
43 }
44
45 result_type operator()()
46 {
47 return std::rand();
48 }
49};
50
51template< class RandomIt >
52inline void random_shuffle(RandomIt first, RandomIt last)
53{
54 std::shuffle(first, last, wrap_rand());
55}
56
57// wrap Generator as UniformRandomBitGenerator
58template< class Generator >
59struct wrap_generator
60{
61 typedef unsigned int result_type;
62 static const int max_arg = ((0u - 1u) >> 2) + 1;
63 Generator& g;
64
65 wrap_generator(Generator& gen) : g(gen) {}
66
67 static BOOST_CONSTEXPR result_type (min)()
68 {
69 return 0;
70 }
71
72 static BOOST_CONSTEXPR result_type (max)()
73 {
74 return max_arg - 1;
75 }
76
77 result_type operator()()
78 {
79 return static_cast<result_type>(g(max_arg));
80 }
81};
82
83template< class RandomIt, class Generator >
84inline void random_shuffle(RandomIt first, RandomIt last, Generator& gen)
85{
86 std::shuffle(first, last, wrap_generator< Generator >(gen));
87}
88
89#else
90
91using std::random_shuffle;
92
93#endif
94 } // namespace detail
95
96/// \brief template function random_shuffle
97///
98/// range-based version of the random_shuffle std algorithm
99///
100/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
101/// \pre Generator is a model of the UnaryFunctionConcept
102template<class RandomAccessRange>
103inline RandomAccessRange& random_shuffle(RandomAccessRange& rng)
104{
105 BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
106 detail::random_shuffle(boost::begin(rng), boost::end(rng));
107 return rng;
108}
109
110/// \overload
111template<class RandomAccessRange>
112inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng)
113{
114 BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
115 detail::random_shuffle(boost::begin(rng), boost::end(rng));
116 return rng;
117}
118
119/// \overload
120template<class RandomAccessRange, class Generator>
121inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen)
122{
123 BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
124 detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
125 return rng;
126}
127
128/// \overload
129template<class RandomAccessRange, class Generator>
130inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen)
131{
132 BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
133 detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
134 return rng;
135}
136
137 } // namespace range
138 using range::random_shuffle;
139} // namespace boost
140
141#endif // include guard
142

source code of boost/libs/range/include/boost/range/algorithm/random_shuffle.hpp