diff --git a/hydra/Random.h b/hydra/Random.h index 4d6dc018d..057ab9375 100644 --- a/hydra/Random.h +++ b/hydra/Random.h @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -551,11 +552,9 @@ sample( Iterable&& output , * @param rng_jump sequence offset for the underlying pseudo-random number generator */ template< typename Engine = hydra::default_random_engine, hydra::detail::Backend BACKEND, typename Iterator, typename FUNCTOR > -typename std::enable_if< hydra::detail::has_rng_formula::value && std::is_convertible< -decltype(std::declval>().Generate( std::declval(), std::declval())), -typename hydra::thrust::iterator_traits::value_type ->::value, void>::type -fill_random(hydra::detail::BackendPolicy const& policy, +requires hydra::detail::HasRngFormula && + hydra::detail::IsRngFormulaConvertible +void fill_random(hydra::detail::BackendPolicy const& policy, Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); /** @@ -570,11 +569,9 @@ fill_random(hydra::detail::BackendPolicy const& policy, * @param rng_jump sequence offset for the underlying pseudo-random number generator */ template< typename Engine =hydra::default_random_engine, typename Iterator, typename FUNCTOR > -typename std::enable_if< hydra::detail::has_rng_formula::value && std::is_convertible< -decltype(std::declval>().Generate( std::declval(), std::declval())), -typename hydra::thrust::iterator_traits::value_type ->::value, void>::type -fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); +requires hydra::detail::HasRngFormula && + hydra::detail::IsRngFormulaConvertible +void fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); /** * \ingroup random @@ -620,8 +617,8 @@ fill_random(Iterable&& iterable, FUNCTOR const& functor, size_t seed=0x254a0afcf * @param rng_jump sequence offset for the underlying pseudo-random number generator */ template< typename Engine = hydra::default_random_engine, hydra::detail::Backend BACKEND, typename Iterator, typename FUNCTOR > -typename std::enable_if< !hydra::detail::has_rng_formula::value , void>::type -fill_random(hydra::detail::BackendPolicy const& policy, +requires (!hydra::detail::HasRngFormula) +void fill_random(hydra::detail::BackendPolicy const& policy, Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); /** @@ -636,8 +633,8 @@ fill_random(hydra::detail::BackendPolicy const& policy, * @param rng_jump sequence offset for the underlying pseudo-random number generator */ template< typename Engine = hydra::default_random_engine, typename Iterator, typename FUNCTOR > -typename std::enable_if< !hydra::detail::has_rng_formula::value , void>::type -fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); +requires (!hydra::detail::HasRngFormula) +void fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); /** * \ingroup random @@ -652,11 +649,9 @@ fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x * @param rng_jump sequence offset for the underlying pseudo-random number generator */ template< typename Engine = hydra::default_random_engine, hydra::detail::Backend BACKEND, typename Iterator, typename FUNCTOR > -typename std::enable_if< !std::is_convertible< -decltype(std::declval>().Generate( std::declval(), std::declval())), -typename std::iterator_traits::value_type ->::value && hydra::detail::has_rng_formula::value, void>::type -fill_random(hydra::detail::BackendPolicy const& policy, +requires hydra::detail::HasRngFormula && + hydra::detail::NotConvertibleToIteratorValue +void fill_random(hydra::detail::BackendPolicy const& policy, Iterator begin, Iterator end, FUNCTOR const& funct, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); /** @@ -671,11 +666,9 @@ fill_random(hydra::detail::BackendPolicy const& policy, * @param rng_jump sequence offset for the underlying pseudo-random number generator */ template< typename Engine = hydra::default_random_engine, typename Iterator, typename FUNCTOR > -typename std::enable_if< !std::is_convertible< -decltype(std::declval>().Generate( std::declval(), std::declval())), -typename std::iterator_traits::value_type ->::value && hydra::detail::has_rng_formula::value, void>::type -fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); +requires hydra::detail::HasRngFormula && + hydra::detail::NotConvertibleToIteratorValue +void fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed=0x254a0afcf7da74a2, size_t rng_jump=0 ); /** * \ingroup random diff --git a/hydra/detail/RandomConcepts.h b/hydra/detail/RandomConcepts.h new file mode 100644 index 000000000..657c333f2 --- /dev/null +++ b/hydra/detail/RandomConcepts.h @@ -0,0 +1,59 @@ +/*---------------------------------------------------------------------------- + * + * Copyright (C) 2016 - 2023 Antonio Augusto Alves Junior + * + * This file is part of Hydra Data Analysis Framework. + * + * Hydra is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hydra is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Hydra. If not, see . + * + *---------------------------------------------------------------------------*/ + +/* + * RandomConcepts.h + * + * Created on: 14/03/2025 + * Author: Davide Brundu + */ + +#ifndef RANDOMCONCEPTS_H_ +#define RANDOMCONCEPTS_H_ + +#include +#include + +namespace hydra { + +namespace detail { + +template +concept HasRngFormula = has_rng_formula::value; + +template +concept IsRngFormulaConvertible = requires (Engine& engine, const FUNCTOR& functor) { + { RngFormula().Generate(engine, functor) } -> std::convertible_to::value_type>; +}; + +template +concept NotConvertibleToIteratorValue = + !std::convertible_to< + decltype(RngFormula().Generate(std::declval(), std::declval())), + typename std::iterator_traits::value_type>; + +} // namespace detail + +} // namespace hydra + + + +#endif /* RANDOMCONCEPTS_H_ */ diff --git a/hydra/detail/RandomFill.inl b/hydra/detail/RandomFill.inl index 6c57d6aef..1c5457b34 100644 --- a/hydra/detail/RandomFill.inl +++ b/hydra/detail/RandomFill.inl @@ -37,7 +37,6 @@ #define RANDOMFILL_INL_ - namespace hydra{ /** @@ -47,12 +46,10 @@ namespace hydra{ * @param end ending of the range storing the generated values * @param functor distribution to be sampled */ - template< typename Engine, hydra::detail::Backend BACKEND, typename Iterator, typename FUNCTOR > - typename std::enable_if< hydra::detail::has_rng_formula::value && std::is_convertible< - decltype(std::declval>().Generate( std::declval(), std::declval())), - typename hydra::thrust::iterator_traits::value_type - >::value, void>::type - fill_random(hydra::detail::BackendPolicy const& policy, + template + requires hydra::detail::HasRngFormula && + hydra::detail::IsRngFormulaConvertible + void fill_random(hydra::detail::BackendPolicy const& policy, Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed, size_t rng_jump) { using hydra::thrust::system::detail::generic::select_system; @@ -63,7 +60,7 @@ namespace hydra{ typedef typename hydra::thrust::detail::remove_reference< decltype(select_system( system, _policy ))>::type common_system_type; - + hydra::thrust::tabulate( common_system_type(), begin, end, detail::Sampler(functor, seed, rng_jump) ); } @@ -75,11 +72,9 @@ namespace hydra{ * @param functor distribution to be sampled */ template< typename Engine, typename Iterator, typename FUNCTOR > - typename std::enable_if< hydra::detail::has_rng_formula::value && std::is_convertible< - decltype(std::declval>().Generate( std::declval(), std::declval())), - typename hydra::thrust::iterator_traits::value_type - >::value, void>::type - fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed, size_t rng_jump) + requires hydra::detail::HasRngFormula && + hydra::detail::IsRngFormulaConvertible + void fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed, size_t rng_jump) { using hydra::thrust::system::detail::generic::select_system; typedef typename hydra::thrust::iterator_system::type system_t; @@ -123,8 +118,8 @@ namespace hydra{ * @brief Fall back function if RngFormula is not implemented for the requested functor */ template< typename Engine, hydra::detail::Backend BACKEND, typename Iterator, typename FUNCTOR > - typename std::enable_if< !hydra::detail::has_rng_formula::value , void>::type - fill_random(hydra::detail::BackendPolicy const& policy, + requires (!hydra::detail::HasRngFormula) + void fill_random(hydra::detail::BackendPolicy const& policy, Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed, size_t rng_jump) { @@ -134,13 +129,13 @@ namespace hydra{ " which will deploy different strategy \n.") } - + /** * @brief Fall back function if RngFormula is not implemented for the requested functor */ template< typename Engine, typename Iterator, typename FUNCTOR > - typename std::enable_if< !hydra::detail::has_rng_formula::value , void>::type - fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed, size_t rng_jump) + requires (!hydra::detail::HasRngFormula) + void fill_random(Iterator begin, Iterator end, FUNCTOR const& functor, size_t seed, size_t rng_jump) { HYDRA_STATIC_ASSERT( int(std::is_class::value) ==-1 , @@ -149,16 +144,14 @@ namespace hydra{ " which will deploy different strategy ") } - + /** * @brief Fall back function if RngFormula::Generate() return value is not convertible to functor return value */ template< typename Engine, hydra::detail::Backend BACKEND, typename Iterator, typename FUNCTOR > - typename std::enable_if< !std::is_convertible< - decltype(std::declval>().Generate( std::declval(), std::declval())), - typename std::iterator_traits::value_type - >::value && hydra::detail::has_rng_formula::value, void>::type - fill_random(hydra::detail::BackendPolicy const& policy, + requires hydra::detail::HasRngFormula && + hydra::detail::NotConvertibleToIteratorValue + void fill_random(hydra::detail::BackendPolicy const& policy, Iterator begin, Iterator end, FUNCTOR const& funct, size_t seed, size_t rng_jump) { HYDRA_STATIC_ASSERT( int(std::is_class::value) ==-1 , @@ -169,16 +162,14 @@ namespace hydra{ * @brief Fall back function if RngFormula::Generate() return value is not convertible to functor return value */ template< typename Engine, typename Iterator, typename FUNCTOR > - typename std::enable_if< !std::is_convertible< - decltype(std::declval>().Generate( std::declval(), std::declval())), - typename std::iterator_traits::value_type - >::value && hydra::detail::has_rng_formula::value, void>::type - fill_random(Iterator begin, Iterator end, FUNCTOR const& funct, size_t seed, size_t rng_jump) + requires hydra::detail::HasRngFormula && + hydra::detail::NotConvertibleToIteratorValue + void fill_random(Iterator begin, Iterator end, FUNCTOR const& funct, size_t seed, size_t rng_jump) { HYDRA_STATIC_ASSERT( int(std::is_class::value) ==-1 , " Generated objects can't be stored in this container. " ) } - + /** * @brief Fall back function if the argument is not an Iterable or if it is not convertible to the Functor return value */