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_SAMPLE_HPP
00008 #define INSTIGATE_STL_RANDOM_SAMPLE_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_random_number.hpp"
00062 #include "_distance.hpp"
00063 #include "_advance.hpp"
00064 #include "_basis.hpp"
00065
00066
00067
00068
00069
00070
00071 namespace instigate {
00072 namespace stl {
00073 namespace implementation {
00074 template <typename I, typename R, typename D>
00075 R random_sample_aux(I b, I e, R o, const D n);
00076 template <typename I, typename R, typename G,
00077 typename D>
00078 R random_sample_aux(I b, I e, R o, G& g, const D n);
00079 }
00080 template <typename I, typename R>
00081 inline R random_sample(I b, I e, R f, R l);
00082 template <typename I, typename R, typename G>
00083 inline R random_sample(I b, I e, R f, R l, G& g);
00084 }
00085 }
00086
00087
00129 template <typename I, typename R>
00130 R instigate::stl::random_sample(I b, I e, R f, R l)
00131 {
00132 namespace SP = instigate::stl::single_pass_iterator;
00133 namespace RI = instigate::stl::readable_iterator;
00134 namespace RA = instigate::stl::random_access_iterator;
00135 namespace WR = instigate::stl::writable_iterator;
00136 CHECK(SP::requirements<I>);
00137 CHECK(RI::requirements<I>);
00138 CHECK(RA::requirements<R>);
00139 CHECK(WR::requirements<R>);
00140 typedef typename RI::interface<I>::value_type value_type1;
00141 typedef typename WR::interface<R>::value_type value_type2;
00142 CHECK_CONVERTIBILITY(value_type1, value_type2);
00143 return instigate::stl::implementation::random_sample_aux(b, e, f,
00144 instigate::stl::distance(f, l));
00145 }
00146
00147
00149 template <typename I, typename R, typename D>
00150 R instigate::stl::implementation::random_sample_aux(I b, I e, R o, const D n)
00151 {
00152 D m = 0;
00153 D t = n;
00154 for (; !equal(b, e) && less_than(m, n); ++m, increment(b)) {
00155 dereference_assign(o, const_dereference(b));
00156 increment(o);
00157 }
00158 D x = 0;
00159 assign(x, m);
00160 while (!equal(b, e)) {
00161 ++t;
00162 D M;
00163 assign(M, instigate::stl::random_number(t));
00164 if (less_than(M, n)) {
00165 instigate::stl::advance(o, (M - x));
00166 dereference_assign(o, const_dereference(b));
00167 assign(x, M);
00168 }
00169 increment(b);
00170 }
00171 instigate::stl::advance(o, m);
00172 return o;
00173 }
00174
00223 template <typename I, typename R, typename G>
00224 R instigate::stl::random_sample(I b, I e, R f, R l, G& g)
00225 {
00226 namespace SP = instigate::stl::single_pass_iterator;
00227 namespace RI = instigate::stl::readable_iterator;
00228 namespace RA = instigate::stl::random_access_iterator;
00229 namespace WR = instigate::stl::writable_iterator;
00230 namespace UF = instigate::stl::unary_function;
00231 CHECK(SP::requirements<I>);
00232 CHECK(RI::requirements<I>);
00233 CHECK(RA::requirements<R>);
00234 CHECK(WR::requirements<R>);
00235 CHECK(UF::requirements<G>);
00236 typedef typename RI::interface<I>::value_type value_type1;
00237 typedef typename WR::interface<R>::value_type value_type2;
00238 CHECK_CONVERTIBILITY(value_type1, value_type2);
00239 typedef typename RA::interface<R>::difference_type difference_type;
00240 typedef typename UF::interface<G>::argument_type argument_type;
00241 CHECK_CONVERTIBILITY(difference_type, argument_type);
00242 return instigate::stl::implementation::random_sample_aux(b, e, f, g,
00243 (int)instigate::stl::distance(f, l));
00244 }
00245
00247 template <typename I, typename R, typename G, typename D>
00248 R instigate::stl::implementation::random_sample_aux(I b, I e, R o, G& g,
00249 const D n)
00250 {
00251 D m = 0;
00252 D t = n;
00253 for (; !equal(b, e) && less_than(m, n); ++m, increment(b)) {
00254 dereference_assign(o, const_dereference(b));
00255 increment(o);
00256 }
00257 D x = 0;
00258 assign(x, m);
00259 while (!equal(b, e)) {
00260 ++t;
00261 D M = invoke(g, t);
00262 if (less_than(M, n)) {
00263 instigate::stl::advance(o, (M - x));
00264 dereference_assign(o, const_dereference(b));
00265 assign(x, m);
00266 assign(x, M);
00267 }
00268 increment(b);
00269 }
00270 instigate::stl::advance(o, m);
00271 return o;
00272 }
00273
00274
00275
00276 #endif // INSTIGATE_STL_RANDOM_SAMPLE_HPP