1*732e2681SEvgeniy Stepanov// -*- C++ -*- 2*732e2681SEvgeniy Stepanov//===-------------------------- algorithm ---------------------------------===// 3*732e2681SEvgeniy Stepanov// 4*732e2681SEvgeniy Stepanov// The LLVM Compiler Infrastructure 5*732e2681SEvgeniy Stepanov// 6*732e2681SEvgeniy Stepanov// This file is dual licensed under the MIT and the University of Illinois Open 7*732e2681SEvgeniy Stepanov// Source Licenses. See LICENSE.TXT for details. 8*732e2681SEvgeniy Stepanov// 9*732e2681SEvgeniy Stepanov//===----------------------------------------------------------------------===// 10*732e2681SEvgeniy Stepanov 11*732e2681SEvgeniy Stepanov#ifndef _LIBCPP_EXPERIMENTAL_ALGORITHM 12*732e2681SEvgeniy Stepanov#define _LIBCPP_EXPERIMENTAL_ALGORITHM 13*732e2681SEvgeniy Stepanov 14*732e2681SEvgeniy Stepanov/* 15*732e2681SEvgeniy Stepanov experimental/algorithm synopsis 16*732e2681SEvgeniy Stepanov 17*732e2681SEvgeniy Stepanov#include <algorithm> 18*732e2681SEvgeniy Stepanov 19*732e2681SEvgeniy Stepanovnamespace std { 20*732e2681SEvgeniy Stepanovnamespace experimental { 21*732e2681SEvgeniy Stepanovinline namespace fundamentals_v1 { 22*732e2681SEvgeniy Stepanov 23*732e2681SEvgeniy Stepanovtemplate <class ForwardIterator, class Searcher> 24*732e2681SEvgeniy StepanovForwardIterator search(ForwardIterator first, ForwardIterator last, 25*732e2681SEvgeniy Stepanov const Searcher &searcher); 26*732e2681SEvgeniy Stepanovtemplate <class PopulationIterator, class SampleIterator, class Distance, 27*732e2681SEvgeniy Stepanov class UniformRandomNumberGenerator> 28*732e2681SEvgeniy StepanovSampleIterator sample(PopulationIterator first, PopulationIterator last, 29*732e2681SEvgeniy Stepanov SampleIterator out, Distance n, 30*732e2681SEvgeniy Stepanov UniformRandomNumberGenerator &&g); 31*732e2681SEvgeniy Stepanov 32*732e2681SEvgeniy Stepanov} // namespace fundamentals_v1 33*732e2681SEvgeniy Stepanov} // namespace experimental 34*732e2681SEvgeniy Stepanov} // namespace std 35*732e2681SEvgeniy Stepanov 36*732e2681SEvgeniy Stepanov*/ 37*732e2681SEvgeniy Stepanov 38*732e2681SEvgeniy Stepanov#include <experimental/__config> 39*732e2681SEvgeniy Stepanov#include <algorithm> 40*732e2681SEvgeniy Stepanov#include <type_traits> 41*732e2681SEvgeniy Stepanov 42*732e2681SEvgeniy Stepanov#include <__undef_min_max> 43*732e2681SEvgeniy Stepanov 44*732e2681SEvgeniy Stepanov#include <__debug> 45*732e2681SEvgeniy Stepanov 46*732e2681SEvgeniy Stepanov#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 47*732e2681SEvgeniy Stepanov#pragma GCC system_header 48*732e2681SEvgeniy Stepanov#endif 49*732e2681SEvgeniy Stepanov 50*732e2681SEvgeniy Stepanov_LIBCPP_BEGIN_NAMESPACE_LFTS 51*732e2681SEvgeniy Stepanov 52*732e2681SEvgeniy Stepanov 53*732e2681SEvgeniy Stepanovtemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 54*732e2681SEvgeniy Stepanov class _UniformRandomNumberGenerator> 55*732e2681SEvgeniy Stepanov_LIBCPP_INLINE_VISIBILITY 56*732e2681SEvgeniy Stepanov_SampleIterator __sample(_PopulationIterator __first, 57*732e2681SEvgeniy Stepanov _PopulationIterator __last, _SampleIterator __out, 58*732e2681SEvgeniy Stepanov _Distance __n, 59*732e2681SEvgeniy Stepanov _UniformRandomNumberGenerator &&__g, 60*732e2681SEvgeniy Stepanov input_iterator_tag) { 61*732e2681SEvgeniy Stepanov 62*732e2681SEvgeniy Stepanov _Distance __k = 0; 63*732e2681SEvgeniy Stepanov for (; __first != __last && __k < __n; ++__first, (void)++__k) 64*732e2681SEvgeniy Stepanov __out[__k] = *__first; 65*732e2681SEvgeniy Stepanov _Distance __sz = __k; 66*732e2681SEvgeniy Stepanov for (; __first != __last; ++__first, (void)++__k) { 67*732e2681SEvgeniy Stepanov _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); 68*732e2681SEvgeniy Stepanov if (__r < __sz) 69*732e2681SEvgeniy Stepanov __out[__r] = *__first; 70*732e2681SEvgeniy Stepanov } 71*732e2681SEvgeniy Stepanov return __out + _VSTD::min(__n, __k); 72*732e2681SEvgeniy Stepanov} 73*732e2681SEvgeniy Stepanov 74*732e2681SEvgeniy Stepanovtemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 75*732e2681SEvgeniy Stepanov class _UniformRandomNumberGenerator> 76*732e2681SEvgeniy Stepanov_LIBCPP_INLINE_VISIBILITY 77*732e2681SEvgeniy Stepanov_SampleIterator __sample(_PopulationIterator __first, 78*732e2681SEvgeniy Stepanov _PopulationIterator __last, _SampleIterator __out, 79*732e2681SEvgeniy Stepanov _Distance __n, 80*732e2681SEvgeniy Stepanov _UniformRandomNumberGenerator &&__g, 81*732e2681SEvgeniy Stepanov forward_iterator_tag) { 82*732e2681SEvgeniy Stepanov _Distance __unsampled_sz = _VSTD::distance(__first, __last); 83*732e2681SEvgeniy Stepanov for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { 84*732e2681SEvgeniy Stepanov _Distance __r = 85*732e2681SEvgeniy Stepanov _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); 86*732e2681SEvgeniy Stepanov if (__r < __n) { 87*732e2681SEvgeniy Stepanov *__out++ = *__first; 88*732e2681SEvgeniy Stepanov --__n; 89*732e2681SEvgeniy Stepanov } 90*732e2681SEvgeniy Stepanov } 91*732e2681SEvgeniy Stepanov return __out; 92*732e2681SEvgeniy Stepanov} 93*732e2681SEvgeniy Stepanov 94*732e2681SEvgeniy Stepanovtemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 95*732e2681SEvgeniy Stepanov class _UniformRandomNumberGenerator> 96*732e2681SEvgeniy Stepanov_LIBCPP_INLINE_VISIBILITY 97*732e2681SEvgeniy Stepanov_SampleIterator sample(_PopulationIterator __first, 98*732e2681SEvgeniy Stepanov _PopulationIterator __last, _SampleIterator __out, 99*732e2681SEvgeniy Stepanov _Distance __n, _UniformRandomNumberGenerator &&__g) { 100*732e2681SEvgeniy Stepanov typedef typename iterator_traits<_PopulationIterator>::iterator_category 101*732e2681SEvgeniy Stepanov _PopCategory; 102*732e2681SEvgeniy Stepanov typedef typename iterator_traits<_PopulationIterator>::difference_type 103*732e2681SEvgeniy Stepanov _Difference; 104*732e2681SEvgeniy Stepanov typedef typename common_type<_Distance, _Difference>::type _CommonType; 105*732e2681SEvgeniy Stepanov _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); 106*732e2681SEvgeniy Stepanov return _VSTD_LFTS::__sample( 107*732e2681SEvgeniy Stepanov __first, __last, __out, _CommonType(__n), 108*732e2681SEvgeniy Stepanov _VSTD::forward<_UniformRandomNumberGenerator>(__g), 109*732e2681SEvgeniy Stepanov _PopCategory()); 110*732e2681SEvgeniy Stepanov} 111*732e2681SEvgeniy Stepanov 112*732e2681SEvgeniy Stepanov_LIBCPP_END_NAMESPACE_LFTS 113*732e2681SEvgeniy Stepanov 114*732e2681SEvgeniy Stepanov#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */ 115