00001
00002 #ifndef _INSTIGATE_STL_INTERNAL_HEADER_IN_ALGORITHM
00003 #error This is an internal header file used to implement Instigate STL.\
00004 It should never be included directly by a program.
00005 #endif
00006
00007 #ifndef INSTIGATE_STL_RANDOM_SHUFFLE_HPP
00008 #define INSTIGATE_STL_RANDOM_SHUFFLE_HPP
00009
00056
00057 #include "concept.hpp"
00058 #include "_random_number.hpp"
00059 #include "_iter_swap.hpp"
00060 #include "_advance.hpp"
00061 #include "_distance.hpp"
00062 #include "_basis.hpp"
00063
00064
00065
00066
00067
00068
00069 namespace instigate {
00070 namespace stl {
00071 template <typename R>
00072 inline void random_shuffle(R f, R l);
00073 template <typename R, typename G>
00074 void random_shuffle(R f, R l, G& g);
00075 }
00076 }
00077
00100 template <typename R>
00101 inline void instigate::stl::random_shuffle(R f, R l)
00102 {
00103 namespace RA = instigate::stl::random_access_iterator;
00104 namespace WR = instigate::stl::writable_iterator;
00105 CHECK(RA::requirements<R>);
00106 CHECK(WR::requirements<R>);
00107 if (equal(f, l)) {
00108 return;
00109 }
00110 char k[sizeof(R)];
00111 R* i = 0;
00112 assign(i, copy_constructor(k, f));
00113 assert(0 != i);
00114 increment(*i);
00115 char p[sizeof(R)];
00116 R* t = 0;
00117 assign(t, initialize<R>(p));
00118 while (!equal(*i, l)) {
00119 assert(0 != t);
00120 assign(*t, f);
00121 instigate::stl::advance(*t,
00122 instigate::stl::random_number(
00123 instigate::stl::distance(f, *i) + 1));
00124 instigate::stl::iter_swap(*i, *t);
00125 increment(*i);
00126 }
00127 }
00128
00161 template <typename R, typename G>
00162 void instigate::stl::random_shuffle(R f, R l, G& g)
00163 {
00164 namespace RA = instigate::stl::random_access_iterator;
00165 namespace WR = instigate::stl::writable_iterator;
00166 namespace UF = instigate::stl::unary_function;
00167 CHECK(RA::requirements<R>);
00168 CHECK(WR::requirements<R>);
00169 CHECK(UF::requirements<G>);
00170 typedef typename RA::interface<R>::difference_type difference_type;
00171 typedef typename UF::interface<G>::argument_type argument_type;
00172 CHECK_CONVERTIBILITY(difference_type, argument_type);
00173 if (equal(f, l)) {
00174 return;
00175 }
00176 char k[sizeof(R)];
00177 R* i = 0;
00178 assign(i, copy_constructor(k, f));
00179 assert(0 != i);
00180 increment(*i);
00181 char p[sizeof(R)];
00182 R* t = 0;
00183 assign(t, initialize<R>(p));
00184 while (!equal(*i, l)) {
00185 assert(0 != t);
00186 assign(*t, f);
00187 instigate::stl::advance( *t, invoke(g,
00188 (int)instigate::stl::distance(f, *i) + 1));
00189 instigate::stl::iter_swap(*i, *t);
00190 increment(*i);
00191 }
00192 }
00193
00194
00195
00196 #endif // INSTIGATE_STL_RANDOM_SHUFFLE_HPP