aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxx/include/__algorithm/sample.h
blob: 8664beb32fd699553ca8a21d9398515c53be0c0c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//===----------------------------------------------------------------------===// 
// 
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
// See https://llvm.org/LICENSE.txt for license information. 
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
// 
//===----------------------------------------------------------------------===// 
 
#ifndef _LIBCPP___ALGORITHM_SAMPLE_H 
#define _LIBCPP___ALGORITHM_SAMPLE_H 
 
#include <__algorithm/min.h> 
#include <__config> 
#include <__debug> 
#include <__random/uniform_int_distribution.h> 
#include <iterator> 
 
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 
#pragma GCC system_header 
#endif 
 
_LIBCPP_PUSH_MACROS 
#include <__undef_macros> 
 
_LIBCPP_BEGIN_NAMESPACE_STD 
 
template <class _PopulationIterator, class _SampleIterator, class _Distance, 
          class _UniformRandomNumberGenerator> 
_LIBCPP_INLINE_VISIBILITY 
_SampleIterator __sample(_PopulationIterator __first, 
                         _PopulationIterator __last, _SampleIterator __output_iter, 
                         _Distance __n, 
                         _UniformRandomNumberGenerator & __g, 
                         input_iterator_tag) { 
 
  _Distance __k = 0; 
  for (; __first != __last && __k < __n; ++__first, (void) ++__k) 
    __output_iter[__k] = *__first; 
  _Distance __sz = __k; 
  for (; __first != __last; ++__first, (void) ++__k) { 
    _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g); 
    if (__r < __sz) 
      __output_iter[__r] = *__first; 
  } 
  return __output_iter + _VSTD::min(__n, __k); 
} 
 
template <class _PopulationIterator, class _SampleIterator, class _Distance, 
          class _UniformRandomNumberGenerator> 
_LIBCPP_INLINE_VISIBILITY 
_SampleIterator __sample(_PopulationIterator __first, 
                         _PopulationIterator __last, _SampleIterator __output_iter, 
                         _Distance __n, 
                         _UniformRandomNumberGenerator& __g, 
                         forward_iterator_tag) { 
  _Distance __unsampled_sz = _VSTD::distance(__first, __last); 
  for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { 
    _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); 
    if (__r < __n) { 
      *__output_iter++ = *__first; 
      --__n; 
    } 
  } 
  return __output_iter; 
} 
 
template <class _PopulationIterator, class _SampleIterator, class _Distance, 
          class _UniformRandomNumberGenerator> 
_LIBCPP_INLINE_VISIBILITY 
_SampleIterator __sample(_PopulationIterator __first, 
                         _PopulationIterator __last, _SampleIterator __output_iter, 
                         _Distance __n, _UniformRandomNumberGenerator& __g) { 
  typedef typename iterator_traits<_PopulationIterator>::iterator_category 
        _PopCategory; 
  typedef typename iterator_traits<_PopulationIterator>::difference_type 
        _Difference; 
  static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || 
                __is_cpp17_random_access_iterator<_SampleIterator>::value, 
                "SampleIterator must meet the requirements of RandomAccessIterator"); 
  typedef typename common_type<_Distance, _Difference>::type _CommonType; 
  _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); 
  return _VSTD::__sample( 
      __first, __last, __output_iter, _CommonType(__n), 
      __g, _PopCategory()); 
} 
 
#if _LIBCPP_STD_VER > 14 
template <class _PopulationIterator, class _SampleIterator, class _Distance, 
          class _UniformRandomNumberGenerator> 
inline _LIBCPP_INLINE_VISIBILITY 
_SampleIterator sample(_PopulationIterator __first, 
                       _PopulationIterator __last, _SampleIterator __output_iter, 
                       _Distance __n, _UniformRandomNumberGenerator&& __g) { 
    return _VSTD::__sample(__first, __last, __output_iter, __n, __g); 
} 
#endif // _LIBCPP_STD_VER > 14 
 
_LIBCPP_END_NAMESPACE_STD 
 
_LIBCPP_POP_MACROS 
 
#endif // _LIBCPP___ALGORITHM_SAMPLE_H