161cfbce3SDimitry Andric //===----------------------------------------------------------------------===// 261cfbce3SDimitry Andric // 361cfbce3SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 461cfbce3SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 561cfbce3SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 661cfbce3SDimitry Andric // 761cfbce3SDimitry Andric //===----------------------------------------------------------------------===// 861cfbce3SDimitry Andric 961cfbce3SDimitry Andric #ifndef _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H 1061cfbce3SDimitry Andric #define _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H 1161cfbce3SDimitry Andric 1261cfbce3SDimitry Andric #include <__config> 1361cfbce3SDimitry Andric #include <__functional/invoke.h> 1406c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h> 1561cfbce3SDimitry Andric 1661cfbce3SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1761cfbce3SDimitry Andric # pragma GCC system_header 1861cfbce3SDimitry Andric #endif 1961cfbce3SDimitry Andric 2006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 2161cfbce3SDimitry Andric 2261cfbce3SDimitry Andric _LIBCPP_PUSH_MACROS 2361cfbce3SDimitry Andric # include <__undef_macros> 2461cfbce3SDimitry Andric 2561cfbce3SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 2661cfbce3SDimitry Andric 2761cfbce3SDimitry Andric // Range versions of random algorithms (e.g. `std::shuffle`) are less constrained than their classic counterparts. 2861cfbce3SDimitry Andric // Range algorithms only require the given generator to satisfy the `std::uniform_random_bit_generator` concept. 2961cfbce3SDimitry Andric // Classic algorithms require the given generator to meet the uniform random bit generator requirements; these 3061cfbce3SDimitry Andric // requirements include satisfying `std::uniform_random_bit_generator` and add a requirement for the generator to 3161cfbce3SDimitry Andric // provide a nested `result_type` typedef (see `[rand.req.urng]`). 3261cfbce3SDimitry Andric // 3361cfbce3SDimitry Andric // To be able to reuse classic implementations, make the given generator meet the classic requirements by wrapping 3461cfbce3SDimitry Andric // it into an adaptor type that forwards all of its interface and adds the required typedef. 3561cfbce3SDimitry Andric template <class _Gen> 3661cfbce3SDimitry Andric class _ClassicGenAdaptor { 3761cfbce3SDimitry Andric private: 3861cfbce3SDimitry Andric // The generator is not required to be copyable or movable, so it has to be stored as a reference. 39bdd1243dSDimitry Andric _Gen& __gen_; 4061cfbce3SDimitry Andric 4161cfbce3SDimitry Andric public: 4261cfbce3SDimitry Andric using result_type = invoke_result_t<_Gen&>; 4361cfbce3SDimitry Andric min()44*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } max()45*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); } 4661cfbce3SDimitry Andric _ClassicGenAdaptor(_Gen & __g)47*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {} 4861cfbce3SDimitry Andric operator()49*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const { return __gen_(); } 5061cfbce3SDimitry Andric }; 5161cfbce3SDimitry Andric 5261cfbce3SDimitry Andric _LIBCPP_END_NAMESPACE_STD 5361cfbce3SDimitry Andric 5461cfbce3SDimitry Andric _LIBCPP_POP_MACROS 5561cfbce3SDimitry Andric 5606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 5761cfbce3SDimitry Andric 5861cfbce3SDimitry Andric #endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H 59