Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc++][ranges] Implement
ranges::sample
.
Differential Revision: https://reviews.llvm.org/D130865
- Loading branch information
Showing
14 changed files
with
542 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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_RANGES_SAMPLE_H | ||
#define _LIBCPP___ALGORITHM_RANGES_SAMPLE_H | ||
|
||
#include <__algorithm/iterator_operations.h> | ||
#include <__algorithm/sample.h> | ||
#include <__algorithm/uniform_random_bit_generator_adaptor.h> | ||
#include <__config> | ||
#include <__iterator/concepts.h> | ||
#include <__iterator/incrementable_traits.h> | ||
#include <__iterator/iterator_traits.h> | ||
#include <__random/uniform_random_bit_generator.h> | ||
#include <__ranges/access.h> | ||
#include <__ranges/concepts.h> | ||
#include <__utility/forward.h> | ||
#include <__utility/move.h> | ||
#include <type_traits> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
namespace ranges { | ||
namespace __sample { | ||
|
||
struct __fn { | ||
|
||
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Gen> | ||
requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) && | ||
indirectly_copyable<_Iter, _OutIter> && | ||
uniform_random_bit_generator<remove_reference_t<_Gen>> | ||
_LIBCPP_HIDE_FROM_ABI | ||
_OutIter operator()(_Iter __first, _Sent __last, | ||
_OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const { | ||
_ClassicGenAdaptor<_Gen> __adapted_gen(__gen); | ||
return std::__sample<_RangeAlgPolicy>( | ||
std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen); | ||
} | ||
|
||
template <input_range _Range, weakly_incrementable _OutIter, class _Gen> | ||
requires (forward_range<_Range> || random_access_iterator<_OutIter>) && | ||
indirectly_copyable<iterator_t<_Range>, _OutIter> && | ||
uniform_random_bit_generator<remove_reference_t<_Gen>> | ||
_LIBCPP_HIDE_FROM_ABI | ||
_OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const { | ||
return (*this)(ranges::begin(__range), ranges::end(__range), | ||
std::move(__out_first), __n, std::forward<_Gen>(__gen)); | ||
} | ||
|
||
}; | ||
|
||
} // namespace __sample | ||
|
||
inline namespace __cpo { | ||
inline constexpr auto sample = __sample::__fn{}; | ||
} // namespace __cpo | ||
} // namespace ranges | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) | ||
|
||
#endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H | ||
#define _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H | ||
|
||
#include <__config> | ||
#include <__functional/invoke.h> | ||
#include <type_traits> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
#if _LIBCPP_STD_VER > 17 | ||
|
||
_LIBCPP_PUSH_MACROS | ||
#include <__undef_macros> | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
// Range versions of random algorithms (e.g. `std::shuffle`) are less constrained than their classic counterparts. | ||
// Range algorithms only require the given generator to satisfy the `std::uniform_random_bit_generator` concept. | ||
// Classic algorithms require the given generator to meet the uniform random bit generator requirements; these | ||
// requirements include satisfying `std::uniform_random_bit_generator` and add a requirement for the generator to | ||
// provide a nested `result_type` typedef (see `[rand.req.urng]`). | ||
// | ||
// To be able to reuse classic implementations, make the given generator meet the classic requirements by wrapping | ||
// it into an adaptor type that forwards all of its interface and adds the required typedef. | ||
template <class _Gen> | ||
class _ClassicGenAdaptor { | ||
private: | ||
// The generator is not required to be copyable or movable, so it has to be stored as a reference. | ||
_Gen& __gen; | ||
|
||
public: | ||
using result_type = invoke_result_t<_Gen&>; | ||
|
||
_LIBCPP_HIDE_FROM_ABI | ||
static constexpr auto min() { return __uncvref_t<_Gen>::min(); } | ||
_LIBCPP_HIDE_FROM_ABI | ||
static constexpr auto max() { return __uncvref_t<_Gen>::max(); } | ||
|
||
_LIBCPP_HIDE_FROM_ABI | ||
constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen(__g) {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI | ||
constexpr auto operator()() const { return __gen(); } | ||
}; | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
_LIBCPP_POP_MACROS | ||
|
||
#endif // _LIBCPP_STD_VER > 17 | ||
|
||
#endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.