File indexing completed on 2026-10-26 09:34:37
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <type_traits>
0010
0011 #include "corecel/Macros.hh"
0012 #include "corecel/Types.hh"
0013 #include "corecel/math/Algorithms.hh"
0014 #include "corecel/math/NumericLimits.hh"
0015
0016 namespace celeritas
0017 {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 template<class Distribution, class IntType = celeritas::size_type>
0029 class RoundedNonnegDistribution
0030 {
0031 public:
0032
0033
0034 using real_type = typename Distribution::real_type;
0035 using result_type = IntType;
0036
0037
0038 static_assert(std::is_floating_point_v<real_type>);
0039 static_assert(std::is_integral_v<result_type>);
0040
0041 public:
0042
0043 template<class... Args>
0044 inline CELER_FUNCTION explicit RoundedNonnegDistribution(Args&&... args);
0045
0046
0047 template<class Generator>
0048 inline CELER_FUNCTION result_type operator()(Generator& rng);
0049
0050 private:
0051 Distribution sample_;
0052 };
0053
0054
0055
0056
0057
0058
0059
0060 template<class Distribution, class IntType>
0061 template<class... Args>
0062 CELER_FUNCTION
0063 RoundedNonnegDistribution<Distribution, IntType>::RoundedNonnegDistribution(
0064 Args&&... args)
0065 : sample_(celeritas::forward<Args>(args)...)
0066 {
0067 }
0068
0069
0070
0071
0072
0073 template<class Distribution, class IntType>
0074 template<class Generator>
0075 CELER_FUNCTION auto
0076 RoundedNonnegDistribution<Distribution, IntType>::operator()(Generator& rng)
0077 -> result_type
0078 {
0079 real_type value = clamp_to_nonneg(sample_(rng) + real_type{0.5});
0080 CELER_ENSURE(value < static_cast<real_type>(NumericLimits<IntType>::max()));
0081 return static_cast<result_type>(value);
0082 }
0083
0084
0085 }