algorithm 4.0 KB

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