176d0caaeSpatrick //===----------------------------------------------------------------------===//
276d0caaeSpatrick //
376d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
476d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
576d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
676d0caaeSpatrick //
776d0caaeSpatrick //===----------------------------------------------------------------------===//
876d0caaeSpatrick
976d0caaeSpatrick #ifndef _LIBCPP___ALGORITHM_SHUFFLE_H
1076d0caaeSpatrick #define _LIBCPP___ALGORITHM_SHUFFLE_H
1176d0caaeSpatrick
12*4bdff4beSrobert #include <__algorithm/iterator_operations.h>
1376d0caaeSpatrick #include <__config>
14*4bdff4beSrobert #include <__debug>
1576d0caaeSpatrick #include <__iterator/iterator_traits.h>
1676d0caaeSpatrick #include <__random/uniform_int_distribution.h>
17*4bdff4beSrobert #include <__utility/forward.h>
18*4bdff4beSrobert #include <__utility/move.h>
1976d0caaeSpatrick #include <__utility/swap.h>
2076d0caaeSpatrick #include <cstddef>
2176d0caaeSpatrick #include <cstdint>
2276d0caaeSpatrick
2376d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2476d0caaeSpatrick # pragma GCC system_header
2576d0caaeSpatrick #endif
2676d0caaeSpatrick
2776d0caaeSpatrick _LIBCPP_PUSH_MACROS
2876d0caaeSpatrick #include <__undef_macros>
2976d0caaeSpatrick
3076d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
3176d0caaeSpatrick
32*4bdff4beSrobert class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer {
33*4bdff4beSrobert public:
__libcpp_debug_randomizer()34*4bdff4beSrobert __libcpp_debug_randomizer() {
35*4bdff4beSrobert __state_ = __seed();
36*4bdff4beSrobert __inc_ = __state_ + 0xda3e39cb94b95bdbULL;
37*4bdff4beSrobert __inc_ = (__inc_ << 1) | 1;
38*4bdff4beSrobert }
39*4bdff4beSrobert typedef uint_fast32_t result_type;
40*4bdff4beSrobert
41*4bdff4beSrobert static const result_type _Min = 0;
42*4bdff4beSrobert static const result_type _Max = 0xFFFFFFFF;
43*4bdff4beSrobert
operator()44*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI result_type operator()() {
45*4bdff4beSrobert uint_fast64_t __oldstate = __state_;
46*4bdff4beSrobert __state_ = __oldstate * 6364136223846793005ULL + __inc_;
47*4bdff4beSrobert return __oldstate >> 32;
48*4bdff4beSrobert }
49*4bdff4beSrobert
min()50*4bdff4beSrobert static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; }
max()51*4bdff4beSrobert static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; }
52*4bdff4beSrobert
53*4bdff4beSrobert private:
54*4bdff4beSrobert uint_fast64_t __state_;
55*4bdff4beSrobert uint_fast64_t __inc_;
__seed()56*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI static uint_fast64_t __seed() {
57*4bdff4beSrobert #ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED
58*4bdff4beSrobert return _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED;
59*4bdff4beSrobert #else
60*4bdff4beSrobert static char __x;
61*4bdff4beSrobert return reinterpret_cast<uintptr_t>(&__x);
62*4bdff4beSrobert #endif
63*4bdff4beSrobert }
64*4bdff4beSrobert };
6576d0caaeSpatrick
6676d0caaeSpatrick #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \
6776d0caaeSpatrick || defined(_LIBCPP_BUILDING_LIBRARY)
6876d0caaeSpatrick class _LIBCPP_TYPE_VIS __rs_default;
6976d0caaeSpatrick
7076d0caaeSpatrick _LIBCPP_FUNC_VIS __rs_default __rs_get();
7176d0caaeSpatrick
7276d0caaeSpatrick class _LIBCPP_TYPE_VIS __rs_default
7376d0caaeSpatrick {
7476d0caaeSpatrick static unsigned __c_;
7576d0caaeSpatrick
7676d0caaeSpatrick __rs_default();
7776d0caaeSpatrick public:
7876d0caaeSpatrick typedef uint_fast32_t result_type;
7976d0caaeSpatrick
8076d0caaeSpatrick static const result_type _Min = 0;
8176d0caaeSpatrick static const result_type _Max = 0xFFFFFFFF;
8276d0caaeSpatrick
8376d0caaeSpatrick __rs_default(const __rs_default&);
8476d0caaeSpatrick ~__rs_default();
8576d0caaeSpatrick
8676d0caaeSpatrick result_type operator()();
8776d0caaeSpatrick
min()8876d0caaeSpatrick static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
max()8976d0caaeSpatrick static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
9076d0caaeSpatrick
9176d0caaeSpatrick friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
9276d0caaeSpatrick };
9376d0caaeSpatrick
9476d0caaeSpatrick _LIBCPP_FUNC_VIS __rs_default __rs_get();
9576d0caaeSpatrick
9676d0caaeSpatrick template <class _RandomAccessIterator>
97*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first,_RandomAccessIterator __last)9876d0caaeSpatrick random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
9976d0caaeSpatrick {
10076d0caaeSpatrick typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
10176d0caaeSpatrick typedef uniform_int_distribution<ptrdiff_t> _Dp;
10276d0caaeSpatrick typedef typename _Dp::param_type _Pp;
10376d0caaeSpatrick difference_type __d = __last - __first;
10476d0caaeSpatrick if (__d > 1)
10576d0caaeSpatrick {
10676d0caaeSpatrick _Dp __uid;
10776d0caaeSpatrick __rs_default __g = __rs_get();
10876d0caaeSpatrick for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
10976d0caaeSpatrick {
11076d0caaeSpatrick difference_type __i = __uid(__g, _Pp(0, __d));
11176d0caaeSpatrick if (__i != difference_type(0))
11276d0caaeSpatrick swap(*__first, *(__first + __i));
11376d0caaeSpatrick }
11476d0caaeSpatrick }
11576d0caaeSpatrick }
11676d0caaeSpatrick
11776d0caaeSpatrick template <class _RandomAccessIterator, class _RandomNumberGenerator>
118*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first,_RandomAccessIterator __last,_RandomNumberGenerator && __rand)11976d0caaeSpatrick random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
12076d0caaeSpatrick #ifndef _LIBCPP_CXX03_LANG
12176d0caaeSpatrick _RandomNumberGenerator&& __rand)
12276d0caaeSpatrick #else
12376d0caaeSpatrick _RandomNumberGenerator& __rand)
12476d0caaeSpatrick #endif
12576d0caaeSpatrick {
12676d0caaeSpatrick typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
12776d0caaeSpatrick difference_type __d = __last - __first;
12876d0caaeSpatrick if (__d > 1)
12976d0caaeSpatrick {
13076d0caaeSpatrick for (--__last; __first < __last; ++__first, (void) --__d)
13176d0caaeSpatrick {
13276d0caaeSpatrick difference_type __i = __rand(__d);
13376d0caaeSpatrick if (__i != difference_type(0))
13476d0caaeSpatrick swap(*__first, *(__first + __i));
13576d0caaeSpatrick }
13676d0caaeSpatrick }
13776d0caaeSpatrick }
13876d0caaeSpatrick #endif
13976d0caaeSpatrick
140*4bdff4beSrobert template <class _AlgPolicy, class _RandomAccessIterator, class _Sentinel, class _UniformRandomNumberGenerator>
__shuffle(_RandomAccessIterator __first,_Sentinel __last_sentinel,_UniformRandomNumberGenerator && __g)141*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator __shuffle(
142*4bdff4beSrobert _RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) {
14376d0caaeSpatrick typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
14476d0caaeSpatrick typedef uniform_int_distribution<ptrdiff_t> _Dp;
14576d0caaeSpatrick typedef typename _Dp::param_type _Pp;
146*4bdff4beSrobert
147*4bdff4beSrobert auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel);
148*4bdff4beSrobert auto __last = __original_last;
14976d0caaeSpatrick difference_type __d = __last - __first;
15076d0caaeSpatrick if (__d > 1)
15176d0caaeSpatrick {
15276d0caaeSpatrick _Dp __uid;
15376d0caaeSpatrick for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
15476d0caaeSpatrick {
15576d0caaeSpatrick difference_type __i = __uid(__g, _Pp(0, __d));
15676d0caaeSpatrick if (__i != difference_type(0))
157*4bdff4beSrobert _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i);
15876d0caaeSpatrick }
15976d0caaeSpatrick }
160*4bdff4beSrobert
161*4bdff4beSrobert return __original_last;
162*4bdff4beSrobert }
163*4bdff4beSrobert
164*4bdff4beSrobert template <class _RandomAccessIterator, class _UniformRandomNumberGenerator>
165*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI void
shuffle(_RandomAccessIterator __first,_RandomAccessIterator __last,_UniformRandomNumberGenerator && __g)166*4bdff4beSrobert shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _UniformRandomNumberGenerator&& __g) {
167*4bdff4beSrobert (void)std::__shuffle<_ClassicAlgPolicy>(
168*4bdff4beSrobert std::move(__first), std::move(__last), std::forward<_UniformRandomNumberGenerator>(__g));
16976d0caaeSpatrick }
17076d0caaeSpatrick
17176d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
17276d0caaeSpatrick
17376d0caaeSpatrick _LIBCPP_POP_MACROS
17476d0caaeSpatrick
17576d0caaeSpatrick #endif // _LIBCPP___ALGORITHM_SHUFFLE_H
176