xref: /freebsd/contrib/llvm-project/libcxx/include/__random/is_valid.h (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
181ad6265SDimitry Andric //===----------------------------------------------------------------------===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric 
981ad6265SDimitry Andric #ifndef _LIBCPP___RANDOM_IS_VALID_H
1081ad6265SDimitry Andric #define _LIBCPP___RANDOM_IS_VALID_H
1181ad6265SDimitry Andric 
1281ad6265SDimitry Andric #include <__config>
1306c3fb27SDimitry Andric #include <__type_traits/enable_if.h>
1406c3fb27SDimitry Andric #include <__type_traits/integral_constant.h>
1506c3fb27SDimitry Andric #include <__type_traits/is_same.h>
1606c3fb27SDimitry Andric #include <__type_traits/is_unsigned.h>
1706c3fb27SDimitry Andric #include <__utility/declval.h>
18fcaf7f86SDimitry Andric #include <cstdint>
1981ad6265SDimitry Andric 
2081ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2181ad6265SDimitry Andric #  pragma GCC system_header
2281ad6265SDimitry Andric #endif
2381ad6265SDimitry Andric 
2481ad6265SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
2581ad6265SDimitry Andric 
265f757f3fSDimitry Andric // [rand.req.genl]/1.4:
275f757f3fSDimitry Andric // The effect of instantiating a template that has a template type parameter
285f757f3fSDimitry Andric // named RealType is undefined unless the corresponding template argument is
295f757f3fSDimitry Andric // cv-unqualified and is one of float, double, or long double.
305f757f3fSDimitry Andric 
315f757f3fSDimitry Andric template <class>
325f757f3fSDimitry Andric struct __libcpp_random_is_valid_realtype : false_type {};
335f757f3fSDimitry Andric template <>
345f757f3fSDimitry Andric struct __libcpp_random_is_valid_realtype<float> : true_type {};
355f757f3fSDimitry Andric template <>
365f757f3fSDimitry Andric struct __libcpp_random_is_valid_realtype<double> : true_type {};
375f757f3fSDimitry Andric template <>
385f757f3fSDimitry Andric struct __libcpp_random_is_valid_realtype<long double> : true_type {};
395f757f3fSDimitry Andric 
4081ad6265SDimitry Andric // [rand.req.genl]/1.5:
4181ad6265SDimitry Andric // The effect of instantiating a template that has a template type parameter
4281ad6265SDimitry Andric // named IntType is undefined unless the corresponding template argument is
4381ad6265SDimitry Andric // cv-unqualified and is one of short, int, long, long long, unsigned short,
4481ad6265SDimitry Andric // unsigned int, unsigned long, or unsigned long long.
4581ad6265SDimitry Andric 
46*cb14a3feSDimitry Andric template <class>
47*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype : false_type {};
48*cb14a3feSDimitry Andric template <>
49*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<int8_t> : true_type {}; // extension
50*cb14a3feSDimitry Andric template <>
51*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<short> : true_type {};
52*cb14a3feSDimitry Andric template <>
53*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<int> : true_type {};
54*cb14a3feSDimitry Andric template <>
55*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<long> : true_type {};
56*cb14a3feSDimitry Andric template <>
57*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<long long> : true_type {};
58*cb14a3feSDimitry Andric template <>
59*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<uint8_t> : true_type {}; // extension
60*cb14a3feSDimitry Andric template <>
61*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<unsigned short> : true_type {};
62*cb14a3feSDimitry Andric template <>
63*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<unsigned int> : true_type {};
64*cb14a3feSDimitry Andric template <>
65*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<unsigned long> : true_type {};
66*cb14a3feSDimitry Andric template <>
67*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<unsigned long long> : true_type {};
6881ad6265SDimitry Andric 
6981ad6265SDimitry Andric #ifndef _LIBCPP_HAS_NO_INT128
70*cb14a3feSDimitry Andric template <>
71*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<__int128_t> : true_type {}; // extension
72*cb14a3feSDimitry Andric template <>
73*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_inttype<__uint128_t> : true_type {}; // extension
7481ad6265SDimitry Andric #endif                                                               // _LIBCPP_HAS_NO_INT128
7581ad6265SDimitry Andric 
7681ad6265SDimitry Andric // [rand.req.urng]/3:
7781ad6265SDimitry Andric // A class G meets the uniform random bit generator requirements if G models
7881ad6265SDimitry Andric // uniform_random_bit_generator, invoke_result_t<G&> is an unsigned integer type,
7981ad6265SDimitry Andric // and G provides a nested typedef-name result_type that denotes the same type
8081ad6265SDimitry Andric // as invoke_result_t<G&>.
8181ad6265SDimitry Andric // (In particular, reject URNGs with signed result_types; our distributions cannot
8281ad6265SDimitry Andric // handle such generator types.)
8381ad6265SDimitry Andric 
84*cb14a3feSDimitry Andric template <class, class = void>
85*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_urng : false_type {};
86*cb14a3feSDimitry Andric template <class _Gp>
87*cb14a3feSDimitry Andric struct __libcpp_random_is_valid_urng<
88*cb14a3feSDimitry Andric     _Gp,
89*cb14a3feSDimitry Andric     __enable_if_t< is_unsigned<typename _Gp::result_type>::value &&
90*cb14a3feSDimitry Andric                    _IsSame<decltype(std::declval<_Gp&>()()), typename _Gp::result_type>::value > > : true_type {};
9181ad6265SDimitry Andric 
9281ad6265SDimitry Andric _LIBCPP_END_NAMESPACE_STD
9381ad6265SDimitry Andric 
9481ad6265SDimitry Andric #endif // _LIBCPP___RANDOM_IS_VALID_H
95