1732e2681SEvgeniy Stepanov// -*- C++ -*- 2732e2681SEvgeniy Stepanov//===-------------------------- algorithm ---------------------------------===// 3732e2681SEvgeniy Stepanov// 4732e2681SEvgeniy Stepanov// The LLVM Compiler Infrastructure 5732e2681SEvgeniy Stepanov// 6732e2681SEvgeniy Stepanov// This file is dual licensed under the MIT and the University of Illinois Open 7732e2681SEvgeniy Stepanov// Source Licenses. See LICENSE.TXT for details. 8732e2681SEvgeniy Stepanov// 9732e2681SEvgeniy Stepanov//===----------------------------------------------------------------------===// 10732e2681SEvgeniy Stepanov 11732e2681SEvgeniy Stepanov#ifndef _LIBCPP_EXPERIMENTAL_ALGORITHM 12732e2681SEvgeniy Stepanov#define _LIBCPP_EXPERIMENTAL_ALGORITHM 13732e2681SEvgeniy Stepanov 14732e2681SEvgeniy Stepanov/* 15732e2681SEvgeniy Stepanov experimental/algorithm synopsis 16732e2681SEvgeniy Stepanov 17732e2681SEvgeniy Stepanov#include <algorithm> 18732e2681SEvgeniy Stepanov 19732e2681SEvgeniy Stepanovnamespace std { 20732e2681SEvgeniy Stepanovnamespace experimental { 21732e2681SEvgeniy Stepanovinline namespace fundamentals_v1 { 22732e2681SEvgeniy Stepanov 23732e2681SEvgeniy Stepanovtemplate <class ForwardIterator, class Searcher> 24732e2681SEvgeniy StepanovForwardIterator search(ForwardIterator first, ForwardIterator last, 25732e2681SEvgeniy Stepanov const Searcher &searcher); 26732e2681SEvgeniy Stepanovtemplate <class PopulationIterator, class SampleIterator, class Distance, 27732e2681SEvgeniy Stepanov class UniformRandomNumberGenerator> 28732e2681SEvgeniy StepanovSampleIterator sample(PopulationIterator first, PopulationIterator last, 29732e2681SEvgeniy Stepanov SampleIterator out, Distance n, 30732e2681SEvgeniy Stepanov UniformRandomNumberGenerator &&g); 31732e2681SEvgeniy Stepanov 32732e2681SEvgeniy Stepanov} // namespace fundamentals_v1 33732e2681SEvgeniy Stepanov} // namespace experimental 34732e2681SEvgeniy Stepanov} // namespace std 35732e2681SEvgeniy Stepanov 36732e2681SEvgeniy Stepanov*/ 37732e2681SEvgeniy Stepanov 38732e2681SEvgeniy Stepanov#include <experimental/__config> 39732e2681SEvgeniy Stepanov#include <algorithm> 40732e2681SEvgeniy Stepanov#include <type_traits> 41732e2681SEvgeniy Stepanov 42732e2681SEvgeniy Stepanov#include <__undef_min_max> 43732e2681SEvgeniy Stepanov 44732e2681SEvgeniy Stepanov#include <__debug> 45732e2681SEvgeniy Stepanov 46732e2681SEvgeniy Stepanov#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 47732e2681SEvgeniy Stepanov#pragma GCC system_header 48732e2681SEvgeniy Stepanov#endif 49732e2681SEvgeniy Stepanov 50732e2681SEvgeniy Stepanov_LIBCPP_BEGIN_NAMESPACE_LFTS 51732e2681SEvgeniy Stepanov 52732e2681SEvgeniy Stepanov 5381416e49SMarshall Clowtemplate <class _ForwardIterator, class _Searcher> 5481416e49SMarshall Clow_LIBCPP_INLINE_VISIBILITY 5581416e49SMarshall Clow_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) 56*28cc4ddeSMarshall Clow{ return __s(__f, __l).first; } 5781416e49SMarshall Clow 5881416e49SMarshall Clow 59732e2681SEvgeniy Stepanovtemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 60732e2681SEvgeniy Stepanov class _UniformRandomNumberGenerator> 61732e2681SEvgeniy Stepanov_LIBCPP_INLINE_VISIBILITY 62732e2681SEvgeniy Stepanov_SampleIterator __sample(_PopulationIterator __first, 63732e2681SEvgeniy Stepanov _PopulationIterator __last, _SampleIterator __out, 64732e2681SEvgeniy Stepanov _Distance __n, 65732e2681SEvgeniy Stepanov _UniformRandomNumberGenerator &&__g, 66732e2681SEvgeniy Stepanov input_iterator_tag) { 67732e2681SEvgeniy Stepanov 68732e2681SEvgeniy Stepanov _Distance __k = 0; 69732e2681SEvgeniy Stepanov for (; __first != __last && __k < __n; ++__first, (void)++__k) 70732e2681SEvgeniy Stepanov __out[__k] = *__first; 71732e2681SEvgeniy Stepanov _Distance __sz = __k; 72732e2681SEvgeniy Stepanov for (; __first != __last; ++__first, (void)++__k) { 73732e2681SEvgeniy Stepanov _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); 74732e2681SEvgeniy Stepanov if (__r < __sz) 75732e2681SEvgeniy Stepanov __out[__r] = *__first; 76732e2681SEvgeniy Stepanov } 77732e2681SEvgeniy Stepanov return __out + _VSTD::min(__n, __k); 78732e2681SEvgeniy Stepanov} 79732e2681SEvgeniy Stepanov 80732e2681SEvgeniy Stepanovtemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 81732e2681SEvgeniy Stepanov class _UniformRandomNumberGenerator> 82732e2681SEvgeniy Stepanov_LIBCPP_INLINE_VISIBILITY 83732e2681SEvgeniy Stepanov_SampleIterator __sample(_PopulationIterator __first, 84732e2681SEvgeniy Stepanov _PopulationIterator __last, _SampleIterator __out, 85732e2681SEvgeniy Stepanov _Distance __n, 86732e2681SEvgeniy Stepanov _UniformRandomNumberGenerator &&__g, 87732e2681SEvgeniy Stepanov forward_iterator_tag) { 88732e2681SEvgeniy Stepanov _Distance __unsampled_sz = _VSTD::distance(__first, __last); 89732e2681SEvgeniy Stepanov for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { 90732e2681SEvgeniy Stepanov _Distance __r = 91732e2681SEvgeniy Stepanov _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); 92732e2681SEvgeniy Stepanov if (__r < __n) { 93732e2681SEvgeniy Stepanov *__out++ = *__first; 94732e2681SEvgeniy Stepanov --__n; 95732e2681SEvgeniy Stepanov } 96732e2681SEvgeniy Stepanov } 97732e2681SEvgeniy Stepanov return __out; 98732e2681SEvgeniy Stepanov} 99732e2681SEvgeniy Stepanov 100732e2681SEvgeniy Stepanovtemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 101732e2681SEvgeniy Stepanov class _UniformRandomNumberGenerator> 102732e2681SEvgeniy Stepanov_LIBCPP_INLINE_VISIBILITY 103732e2681SEvgeniy Stepanov_SampleIterator sample(_PopulationIterator __first, 104732e2681SEvgeniy Stepanov _PopulationIterator __last, _SampleIterator __out, 105732e2681SEvgeniy Stepanov _Distance __n, _UniformRandomNumberGenerator &&__g) { 106732e2681SEvgeniy Stepanov typedef typename iterator_traits<_PopulationIterator>::iterator_category 107732e2681SEvgeniy Stepanov _PopCategory; 108732e2681SEvgeniy Stepanov typedef typename iterator_traits<_PopulationIterator>::difference_type 109732e2681SEvgeniy Stepanov _Difference; 110732e2681SEvgeniy Stepanov typedef typename common_type<_Distance, _Difference>::type _CommonType; 111732e2681SEvgeniy Stepanov _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); 112732e2681SEvgeniy Stepanov return _VSTD_LFTS::__sample( 113732e2681SEvgeniy Stepanov __first, __last, __out, _CommonType(__n), 114732e2681SEvgeniy Stepanov _VSTD::forward<_UniformRandomNumberGenerator>(__g), 115732e2681SEvgeniy Stepanov _PopCategory()); 116732e2681SEvgeniy Stepanov} 117732e2681SEvgeniy Stepanov 118732e2681SEvgeniy Stepanov_LIBCPP_END_NAMESPACE_LFTS 119732e2681SEvgeniy Stepanov 120732e2681SEvgeniy Stepanov#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */ 121