diff options
Diffstat (limited to 'libcxx/include/__random')
37 files changed, 190 insertions, 73 deletions
diff --git a/libcxx/include/__random/bernoulli_distribution.h b/libcxx/include/__random/bernoulli_distribution.h index 60ae5eae7033..e97d53f5a421 100644 --- a/libcxx/include/__random/bernoulli_distribution.h +++ b/libcxx/include/__random/bernoulli_distribution.h @@ -10,11 +10,12 @@ #define _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <iosfwd> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -103,6 +104,7 @@ inline bernoulli_distribution::result_type bernoulli_distribution::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); uniform_real_distribution<double> __gen; return __gen(__g) < __p.p(); } diff --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h index 9662de8befd9..d0e8f3034939 100644 --- a/libcxx/include/__random/binomial_distribution.h +++ b/libcxx/include/__random/binomial_distribution.h @@ -10,12 +10,13 @@ #define _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -26,6 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _IntType = int> class _LIBCPP_TEMPLATE_VIS binomial_distribution { + static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char"); public: // types typedef _IntType result_type; @@ -146,6 +148,7 @@ template<class _URNG> _IntType binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); if (__pr.__t_ == 0 || __pr.__p_ == 0) return 0; if (__pr.__p_ == 1) diff --git a/libcxx/include/__random/cauchy_distribution.h b/libcxx/include/__random/cauchy_distribution.h index 6661e00bf939..5bc44ee8dd4c 100644 --- a/libcxx/include/__random/cauchy_distribution.h +++ b/libcxx/include/__random/cauchy_distribution.h @@ -10,13 +10,14 @@ #define _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -116,6 +117,7 @@ inline _RealType cauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); uniform_real_distribution<result_type> __gen; // purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite return __p.a() + __p.b() * _VSTD::tan(3.1415926535897932384626433832795 * __gen(__g)); diff --git a/libcxx/include/__random/chi_squared_distribution.h b/libcxx/include/__random/chi_squared_distribution.h index 2aa0762a520c..b98488c20d28 100644 --- a/libcxx/include/__random/chi_squared_distribution.h +++ b/libcxx/include/__random/chi_squared_distribution.h @@ -15,7 +15,7 @@ #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/clamp_to_integral.h b/libcxx/include/__random/clamp_to_integral.h index dd5d2b0186e4..7d44ff9cfcad 100644 --- a/libcxx/include/__random/clamp_to_integral.h +++ b/libcxx/include/__random/clamp_to_integral.h @@ -15,7 +15,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/default_random_engine.h b/libcxx/include/__random/default_random_engine.h index 61c5cf9c7142..89792f4f0d43 100644 --- a/libcxx/include/__random/default_random_engine.h +++ b/libcxx/include/__random/default_random_engine.h @@ -13,7 +13,7 @@ #include <__random/linear_congruential_engine.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__random/discard_block_engine.h b/libcxx/include/__random/discard_block_engine.h index 335715211884..c58d66b58869 100644 --- a/libcxx/include/__random/discard_block_engine.h +++ b/libcxx/include/__random/discard_block_engine.h @@ -17,7 +17,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/discrete_distribution.h b/libcxx/include/__random/discrete_distribution.h index dc9881a92c38..d899e72d87f9 100644 --- a/libcxx/include/__random/discrete_distribution.h +++ b/libcxx/include/__random/discrete_distribution.h @@ -11,6 +11,7 @@ #include <__algorithm/upper_bound.h> #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <cstddef> #include <iosfwd> @@ -18,7 +19,7 @@ #include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -29,6 +30,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _IntType = int> class _LIBCPP_TEMPLATE_VIS discrete_distribution { + static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char"); public: // types typedef _IntType result_type; @@ -211,6 +213,7 @@ template<class _URNG> _IntType discrete_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); uniform_real_distribution<double> __gen; return static_cast<_IntType>( _VSTD::upper_bound(__p.__p_.begin(), __p.__p_.end(), __gen(__g)) - diff --git a/libcxx/include/__random/exponential_distribution.h b/libcxx/include/__random/exponential_distribution.h index 9e555f0c1075..1c9e9e0d9ef1 100644 --- a/libcxx/include/__random/exponential_distribution.h +++ b/libcxx/include/__random/exponential_distribution.h @@ -11,13 +11,14 @@ #include <__config> #include <__random/generate_canonical.h> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -109,6 +110,7 @@ template<class _URNG> _RealType exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); return -_VSTD::log ( result_type(1) - diff --git a/libcxx/include/__random/extreme_value_distribution.h b/libcxx/include/__random/extreme_value_distribution.h index 0e200f91d7ff..ba30aa5b88c3 100644 --- a/libcxx/include/__random/extreme_value_distribution.h +++ b/libcxx/include/__random/extreme_value_distribution.h @@ -10,13 +10,14 @@ #define _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -116,6 +117,7 @@ template<class _URNG> _RealType extreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); return __p.a() - __p.b() * _VSTD::log(-_VSTD::log(1-uniform_real_distribution<result_type>()(__g))); } diff --git a/libcxx/include/__random/fisher_f_distribution.h b/libcxx/include/__random/fisher_f_distribution.h index bf64d33a645a..60c7f28c0bb0 100644 --- a/libcxx/include/__random/fisher_f_distribution.h +++ b/libcxx/include/__random/fisher_f_distribution.h @@ -11,11 +11,12 @@ #include <__config> #include <__random/gamma_distribution.h> +#include <__random/is_valid.h> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -114,6 +115,7 @@ template<class _URNG> _RealType fisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); gamma_distribution<result_type> __gdm(__p.m() * result_type(.5)); gamma_distribution<result_type> __gdn(__p.n() * result_type(.5)); return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g)); diff --git a/libcxx/include/__random/gamma_distribution.h b/libcxx/include/__random/gamma_distribution.h index 34167e463528..986d79b67aa3 100644 --- a/libcxx/include/__random/gamma_distribution.h +++ b/libcxx/include/__random/gamma_distribution.h @@ -11,13 +11,14 @@ #include <__config> #include <__random/exponential_distribution.h> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -117,6 +118,7 @@ template<class _URNG> _RealType gamma_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); result_type __a = __p.alpha(); uniform_real_distribution<result_type> __gen(0, 1); exponential_distribution<result_type> __egen; diff --git a/libcxx/include/__random/generate_canonical.h b/libcxx/include/__random/generate_canonical.h index 46c3b2980952..84efa7803c94 100644 --- a/libcxx/include/__random/generate_canonical.h +++ b/libcxx/include/__random/generate_canonical.h @@ -16,7 +16,7 @@ #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/geometric_distribution.h b/libcxx/include/__random/geometric_distribution.h index 174914eaed2e..8e1be522e0e3 100644 --- a/libcxx/include/__random/geometric_distribution.h +++ b/libcxx/include/__random/geometric_distribution.h @@ -10,12 +10,13 @@ #define _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H #include <__config> +#include <__random/is_valid.h> #include <__random/negative_binomial_distribution.h> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -26,6 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _IntType = int> class _LIBCPP_TEMPLATE_VIS geometric_distribution { + static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char"); public: // types typedef _IntType result_type; diff --git a/libcxx/include/__random/independent_bits_engine.h b/libcxx/include/__random/independent_bits_engine.h index f0e8c654246b..e80d6eec49cb 100644 --- a/libcxx/include/__random/independent_bits_engine.h +++ b/libcxx/include/__random/independent_bits_engine.h @@ -18,7 +18,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/is_seed_sequence.h b/libcxx/include/__random/is_seed_sequence.h index 46b1d719ddfb..a6832f51c1ee 100644 --- a/libcxx/include/__random/is_seed_sequence.h +++ b/libcxx/include/__random/is_seed_sequence.h @@ -13,7 +13,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__random/is_valid.h b/libcxx/include/__random/is_valid.h new file mode 100644 index 000000000000..d41bfa45ea70 --- /dev/null +++ b/libcxx/include/__random/is_valid.h @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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___RANDOM_IS_VALID_H +#define _LIBCPP___RANDOM_IS_VALID_H + +#include <__config> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [rand.req.genl]/1.5: +// The effect of instantiating a template that has a template type parameter +// named IntType is undefined unless the corresponding template argument is +// cv-unqualified and is one of short, int, long, long long, unsigned short, +// unsigned int, unsigned long, or unsigned long long. + +template<class> struct __libcpp_random_is_valid_inttype : false_type {}; +template<> struct __libcpp_random_is_valid_inttype<short> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<int> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<long> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<long long> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<unsigned short> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<unsigned int> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<unsigned long> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<unsigned long long> : true_type {}; + +#ifndef _LIBCPP_HAS_NO_INT128 +template<> struct __libcpp_random_is_valid_inttype<__int128_t> : true_type {}; +template<> struct __libcpp_random_is_valid_inttype<__uint128_t> : true_type {}; +#endif // _LIBCPP_HAS_NO_INT128 + +// [rand.req.urng]/3: +// A class G meets the uniform random bit generator requirements if G models +// uniform_random_bit_generator, invoke_result_t<G&> is an unsigned integer type, +// and G provides a nested typedef-name result_type that denotes the same type +// as invoke_result_t<G&>. +// (In particular, reject URNGs with signed result_types; our distributions cannot +// handle such generator types.) + +template<class, class = void> struct __libcpp_random_is_valid_urng : false_type {}; +template<class _Gp> struct __libcpp_random_is_valid_urng<_Gp, __enable_if_t< + is_unsigned<typename _Gp::result_type>::value && + _IsSame<decltype(declval<_Gp&>()()), typename _Gp::result_type>::value +> > : true_type {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANDOM_IS_VALID_H diff --git a/libcxx/include/__random/knuth_b.h b/libcxx/include/__random/knuth_b.h index ade853884dd3..f5b31cb64fa4 100644 --- a/libcxx/include/__random/knuth_b.h +++ b/libcxx/include/__random/knuth_b.h @@ -14,7 +14,7 @@ #include <__random/shuffle_order_engine.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__random/linear_congruential_engine.h b/libcxx/include/__random/linear_congruential_engine.h index 64c9f584114c..42b40813e0ac 100644 --- a/libcxx/include/__random/linear_congruential_engine.h +++ b/libcxx/include/__random/linear_congruential_engine.h @@ -16,7 +16,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -218,8 +218,8 @@ private: static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters"); static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type"); public: - static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u; - static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u; + static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u : 0u; + static _LIBCPP_CONSTEXPR const result_type _Max = __m - _UIntType(1u); static_assert(_Min < _Max, "linear_congruential_engine invalid parameters"); // engine characteristics diff --git a/libcxx/include/__random/log2.h b/libcxx/include/__random/log2.h index 3d9640c1f787..b077d211cefa 100644 --- a/libcxx/include/__random/log2.h +++ b/libcxx/include/__random/log2.h @@ -14,7 +14,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__random/lognormal_distribution.h b/libcxx/include/__random/lognormal_distribution.h index 8fadb5a1e66a..048d7dade9eb 100644 --- a/libcxx/include/__random/lognormal_distribution.h +++ b/libcxx/include/__random/lognormal_distribution.h @@ -16,7 +16,7 @@ #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/mersenne_twister_engine.h b/libcxx/include/__random/mersenne_twister_engine.h index 121ffae37ec0..8bceac05dce9 100644 --- a/libcxx/include/__random/mersenne_twister_engine.h +++ b/libcxx/include/__random/mersenne_twister_engine.h @@ -20,7 +20,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/negative_binomial_distribution.h b/libcxx/include/__random/negative_binomial_distribution.h index 7329bac2ff85..72ce88ea74ba 100644 --- a/libcxx/include/__random/negative_binomial_distribution.h +++ b/libcxx/include/__random/negative_binomial_distribution.h @@ -12,12 +12,13 @@ #include <__config> #include <__random/bernoulli_distribution.h> #include <__random/gamma_distribution.h> +#include <__random/is_valid.h> #include <__random/poisson_distribution.h> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -28,6 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _IntType = int> class _LIBCPP_TEMPLATE_VIS negative_binomial_distribution { + static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char"); public: // types typedef _IntType result_type; @@ -116,6 +118,7 @@ template<class _URNG> _IntType negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); result_type __k = __pr.k(); double __p = __pr.p(); if (__k <= 21 * __p) diff --git a/libcxx/include/__random/normal_distribution.h b/libcxx/include/__random/normal_distribution.h index b460ffb7ea9d..0431df927200 100644 --- a/libcxx/include/__random/normal_distribution.h +++ b/libcxx/include/__random/normal_distribution.h @@ -10,13 +10,14 @@ #define _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -131,6 +132,7 @@ template<class _URNG> _RealType normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); result_type _Up; if (_V_hot_) { diff --git a/libcxx/include/__random/piecewise_constant_distribution.h b/libcxx/include/__random/piecewise_constant_distribution.h index ece20d1a1d6e..a33ab0720062 100644 --- a/libcxx/include/__random/piecewise_constant_distribution.h +++ b/libcxx/include/__random/piecewise_constant_distribution.h @@ -11,13 +11,14 @@ #include <__algorithm/upper_bound.h> #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <iosfwd> #include <numeric> #include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -284,6 +285,7 @@ template<class _URNG> _RealType piecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); typedef uniform_real_distribution<result_type> _Gen; result_type __u = _Gen()(__g); ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(), diff --git a/libcxx/include/__random/piecewise_linear_distribution.h b/libcxx/include/__random/piecewise_linear_distribution.h index b2ba164d0707..e69ce9444072 100644 --- a/libcxx/include/__random/piecewise_linear_distribution.h +++ b/libcxx/include/__random/piecewise_linear_distribution.h @@ -11,13 +11,14 @@ #include <__algorithm/upper_bound.h> #include <__config> +#include <__random/is_valid.h> #include <__random/uniform_real_distribution.h> #include <iosfwd> #include <numeric> #include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -289,6 +290,7 @@ template<class _URNG> _RealType piecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); typedef uniform_real_distribution<result_type> _Gen; result_type __u = _Gen()(__g); ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(), diff --git a/libcxx/include/__random/poisson_distribution.h b/libcxx/include/__random/poisson_distribution.h index d157e8f230ef..7730923ad6ca 100644 --- a/libcxx/include/__random/poisson_distribution.h +++ b/libcxx/include/__random/poisson_distribution.h @@ -12,6 +12,7 @@ #include <__config> #include <__random/clamp_to_integral.h> #include <__random/exponential_distribution.h> +#include <__random/is_valid.h> #include <__random/normal_distribution.h> #include <__random/uniform_real_distribution.h> #include <cmath> @@ -19,7 +20,7 @@ #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -30,6 +31,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _IntType = int> class _LIBCPP_TEMPLATE_VIS poisson_distribution { + static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char"); public: // types typedef _IntType result_type; @@ -157,6 +159,7 @@ template<class _URNG> _IntType poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); double __tx; uniform_real_distribution<double> __urd; if (__pr.__mean_ < 10) diff --git a/libcxx/include/__random/random_device.h b/libcxx/include/__random/random_device.h index ef11977f9b77..e82b437a3b54 100644 --- a/libcxx/include/__random/random_device.h +++ b/libcxx/include/__random/random_device.h @@ -13,7 +13,7 @@ #include <string> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -28,10 +28,8 @@ class _LIBCPP_TYPE_VIS random_device #ifdef _LIBCPP_USING_DEV_RANDOM int __f_; #elif !defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT) -# if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wunused-private-field" -# endif + _LIBCPP_DIAGNOSTIC_PUSH + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field") // Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now // use `arc4random()` as of this comment. In order to avoid breaking the ABI, we @@ -42,9 +40,7 @@ class _LIBCPP_TYPE_VIS random_device // ... vendors can add workarounds here if they switch to a different representation ... -# if defined(__clang__) -# pragma clang diagnostic pop -# endif + _LIBCPP_DIAGNOSTIC_POP #endif public: diff --git a/libcxx/include/__random/ranlux.h b/libcxx/include/__random/ranlux.h index 0b415928df4d..e44cece39dfc 100644 --- a/libcxx/include/__random/ranlux.h +++ b/libcxx/include/__random/ranlux.h @@ -15,7 +15,7 @@ #include <cstdint> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__random/seed_seq.h b/libcxx/include/__random/seed_seq.h index 1a0877995650..330537fa0023 100644 --- a/libcxx/include/__random/seed_seq.h +++ b/libcxx/include/__random/seed_seq.h @@ -17,7 +17,7 @@ #include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -109,39 +109,63 @@ seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last) __first[__q] += __r; __first[0] = __r; } + // Initialize indexing terms used with if statements as an optimization to + // avoid calculating modulo n on every loop iteration for each term. + size_t __kmodn = 0; // __k % __n + size_t __k1modn = __n - 1; // (__k - 1) % __n + size_t __kpmodn = __p % __n; // (__k + __p) % __n + size_t __kqmodn = __q % __n; // (__k + __q) % __n + for (size_t __k = 1; __k <= __s; ++__k) { - const size_t __kmodn = __k % __n; - const size_t __kpmodn = (__k + __p) % __n; - result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] - ^ __first[(__k - 1) % __n]); - __first[__kpmodn] += __r; - __r += __kmodn + __v_[__k-1]; - __first[(__k + __q) % __n] += __r; - __first[__kmodn] = __r; + if (++__kmodn == __n) + __kmodn = 0; + if (++__k1modn == __n) + __k1modn = 0; + if (++__kpmodn == __n) + __kpmodn = 0; + if (++__kqmodn == __n) + __kqmodn = 0; + + result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] ^ __first[__k1modn]); + __first[__kpmodn] += __r; + __r += __kmodn + __v_[__k - 1]; + __first[__kqmodn] += __r; + __first[__kmodn] = __r; } for (size_t __k = __s + 1; __k < __m; ++__k) { - const size_t __kmodn = __k % __n; - const size_t __kpmodn = (__k + __p) % __n; - result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] - ^ __first[(__k - 1) % __n]); - __first[__kpmodn] += __r; - __r += __kmodn; - __first[(__k + __q) % __n] += __r; - __first[__kmodn] = __r; + if (++__kmodn == __n) + __kmodn = 0; + if (++__k1modn == __n) + __k1modn = 0; + if (++__kpmodn == __n) + __kpmodn = 0; + if (++__kqmodn == __n) + __kqmodn = 0; + + result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] ^ __first[__k1modn]); + __first[__kpmodn] += __r; + __r += __kmodn; + __first[__kqmodn] += __r; + __first[__kmodn] = __r; } for (size_t __k = __m; __k < __m + __n; ++__k) { - const size_t __kmodn = __k % __n; - const size_t __kpmodn = (__k + __p) % __n; - result_type __r = 1566083941 * _Tp(__first[__kmodn] + - __first[__kpmodn] + - __first[(__k - 1) % __n]); - __first[__kpmodn] ^= __r; - __r -= __kmodn; - __first[(__k + __q) % __n] ^= __r; - __first[__kmodn] = __r; + if (++__kmodn == __n) + __kmodn = 0; + if (++__k1modn == __n) + __k1modn = 0; + if (++__kpmodn == __n) + __kpmodn = 0; + if (++__kqmodn == __n) + __kqmodn = 0; + + result_type __r = 1566083941 * _Tp(__first[__kmodn] + __first[__kpmodn] + __first[__k1modn]); + __first[__kpmodn] ^= __r; + __r -= __kmodn; + __first[__kqmodn] ^= __r; + __first[__kmodn] = __r; } } } diff --git a/libcxx/include/__random/shuffle_order_engine.h b/libcxx/include/__random/shuffle_order_engine.h index 7a5735dd7933..c2f76f609ae5 100644 --- a/libcxx/include/__random/shuffle_order_engine.h +++ b/libcxx/include/__random/shuffle_order_engine.h @@ -18,7 +18,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/student_t_distribution.h b/libcxx/include/__random/student_t_distribution.h index 0cf911e4cd76..9e95f97cefab 100644 --- a/libcxx/include/__random/student_t_distribution.h +++ b/libcxx/include/__random/student_t_distribution.h @@ -11,13 +11,14 @@ #include <__config> #include <__random/gamma_distribution.h> +#include <__random/is_valid.h> #include <__random/normal_distribution.h> #include <cmath> #include <iosfwd> #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -111,6 +112,7 @@ template<class _URNG> _RealType student_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); gamma_distribution<result_type> __gd(__p.n() * .5, 2); return __nd_(__g) * _VSTD::sqrt(__p.n()/__gd(__g)); } diff --git a/libcxx/include/__random/subtract_with_carry_engine.h b/libcxx/include/__random/subtract_with_carry_engine.h index 073f84dccff6..fdbe2d2e9be3 100644 --- a/libcxx/include/__random/subtract_with_carry_engine.h +++ b/libcxx/include/__random/subtract_with_carry_engine.h @@ -21,7 +21,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/__random/uniform_int_distribution.h b/libcxx/include/__random/uniform_int_distribution.h index 55b4761637f0..dd0a7e4e4982 100644 --- a/libcxx/include/__random/uniform_int_distribution.h +++ b/libcxx/include/__random/uniform_int_distribution.h @@ -11,6 +11,7 @@ #include <__bits> #include <__config> +#include <__random/is_valid.h> #include <__random/log2.h> #include <bit> #include <cstddef> @@ -20,7 +21,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -155,9 +156,10 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type) return _Sp; } -template<class _IntType = int> // __int128_t is also supported as an extension here +template<class _IntType = int> class uniform_int_distribution { + static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be an integer type larger than char"); public: // types typedef _IntType result_type; @@ -230,6 +232,7 @@ typename uniform_int_distribution<_IntType>::result_type uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t), uint32_t, typename make_unsigned<result_type>::type>::type _UIntType; const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); diff --git a/libcxx/include/__random/uniform_random_bit_generator.h b/libcxx/include/__random/uniform_random_bit_generator.h index 7b2f0df868d7..84a30b0ebe16 100644 --- a/libcxx/include/__random/uniform_random_bit_generator.h +++ b/libcxx/include/__random/uniform_random_bit_generator.h @@ -16,7 +16,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 // [rand.req.urng] template<class _Gen> @@ -36,7 +36,7 @@ concept uniform_random_bit_generator = requires bool_constant<(_Gen::min() < _Gen::max())>::value; }; -#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__random/uniform_real_distribution.h b/libcxx/include/__random/uniform_real_distribution.h index 967e4e26fd0c..7d2ecda732fe 100644 --- a/libcxx/include/__random/uniform_real_distribution.h +++ b/libcxx/include/__random/uniform_real_distribution.h @@ -11,12 +11,13 @@ #include <__config> #include <__random/generate_canonical.h> +#include <__random/is_valid.h> #include <iosfwd> #include <limits> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -115,6 +116,7 @@ inline typename uniform_real_distribution<_RealType>::result_type uniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { + static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); return (__p.b() - __p.a()) * _VSTD::generate_canonical<_RealType, numeric_limits<_RealType>::digits>(__g) + __p.a(); diff --git a/libcxx/include/__random/weibull_distribution.h b/libcxx/include/__random/weibull_distribution.h index 4c5e4e8fff1c..85bae65096cb 100644 --- a/libcxx/include/__random/weibull_distribution.h +++ b/libcxx/include/__random/weibull_distribution.h @@ -16,7 +16,7 @@ #include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS |
