IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 92e8492a authored by ralfulrich's avatar ralfulrich
Browse files

added more static_asserts to ProcessSequence

parent a8887b0b
No related branches found
No related tags found
No related merge requests found
......@@ -44,8 +44,8 @@ namespace corsika::process {
template <typename TProcess1, typename TProcess2 = NullModel>
class ProcessSequence : public BaseProcess<ProcessSequence<TProcess1, TProcess2>> {
using TProcess1type = typename std::decay<TProcess1>::type;
using TProcess2type = typename std::decay<TProcess2>::type;
using TProcess1type = typename std::decay_t<TProcess1>;
using TProcess2type = typename std::decay_t<TProcess2>;
static bool constexpr t1ProcSeq = is_process_sequence_v<TProcess1type>;
static bool constexpr t2ProcSeq = is_process_sequence_v<TProcess2type>;
......@@ -316,22 +316,22 @@ namespace corsika::process {
**/
template <typename... TProcesses, typename TProcess1>
inline typename std::enable_if<
std::is_base_of<BaseProcess<typename std::decay<TProcess1>::type>,
typename std::decay<TProcess1>::type>::value,
ProcessSequence<TProcess1, decltype(sequence(std::declval<TProcesses>()...))>>::type
inline typename std::enable_if_t<
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess1>>,
typename std::decay_t<TProcess1>>,
ProcessSequence<TProcess1, decltype(sequence(std::declval<TProcesses>()...))>>
sequence(TProcess1&& vA, TProcesses&&... vBs) {
return ProcessSequence<TProcess1, decltype(sequence(std::declval<TProcesses>()...))>(
vA, sequence(std::forward<TProcesses>(vBs)...));
}
template <typename TProcess1, typename TProcess2>
inline typename std::enable_if<
std::is_base_of<BaseProcess<typename std::decay<TProcess1>::type>,
typename std::decay<TProcess1>::type>::value &&
std::is_base_of<BaseProcess<typename std::decay<TProcess2>::type>,
typename std::decay<TProcess2>::type>::value,
ProcessSequence<TProcess1, TProcess2>>::type
inline typename std::enable_if_t<
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess1>>,
typename std::decay_t<TProcess1>> &&
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess2>>,
typename std::decay_t<TProcess2>>,
ProcessSequence<TProcess1, TProcess2>>
sequence(TProcess1&& vA, TProcess2&& vB) {
return ProcessSequence<TProcess1, TProcess2>(vA, vB);
}
......@@ -341,17 +341,48 @@ namespace corsika::process {
* `NullModel`
**/
template <typename TProcess>
inline typename std::enable_if<
std::is_base_of<BaseProcess<typename std::decay<TProcess>::type>,
typename std::decay<TProcess>::type>::value,
ProcessSequence<TProcess, NullModel>>::type
inline typename std::enable_if_t<
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess>>,
typename std::decay_t<TProcess>>,
ProcessSequence<TProcess, NullModel>>
sequence(TProcess&& vA) {
return ProcessSequence<TProcess, NullModel>(vA, NullModel());
}
/// traits marker to identify objectas ProcessSequence
/**
* traits marker to identify objectas ProcessSequence
**/
template <typename TProcess1, typename TProcess2>
struct is_process_sequence<ProcessSequence<TProcess1, TProcess2>> : std::true_type {
// only switch on for BaseProcesses
template <typename std::enable_if_t<
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess1>>,
typename std::decay_t<TProcess1>> &&
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess2>>,
typename std::decay_t<TProcess2>>,
int>>
is_process_sequence() {}
};
/**
* traits marker to identify objects containing any StackProcesses
**/
namespace detail {
// need helper alias to achieve this:
template <typename TProcess1, typename TProcess2,
typename = typename std::enable_if_t<
contains_stack_process_v<TProcess1> ||
std::is_base_of_v<StackProcess<typename std::decay_t<TProcess1>>,
typename std::decay_t<TProcess1>> ||
contains_stack_process_v<TProcess2> ||
std::is_base_of_v<StackProcess<typename std::decay_t<TProcess2>>,
typename std::decay_t<TProcess2>>,
int>>
using enable_if_stack = ProcessSequence<TProcess1, TProcess2>;
} // namespace detail
template <typename TProcess1, typename TProcess2>
struct is_process_sequence<corsika::process::ProcessSequence<TProcess1, TProcess2>>
struct contains_stack_process<detail::enable_if_stack<TProcess1, TProcess2>>
: std::true_type {};
} // namespace corsika::process
......@@ -29,4 +29,13 @@ namespace corsika::process {
template <typename TClass>
bool constexpr is_switch_process_sequence_v = is_switch_process_sequence<TClass>::value;
/**
* A traits marker to identify ProcessSequence that contain a StackProcess
**/
template <typename TClass>
struct contains_stack_process : std::false_type {};
template <typename TClass>
bool constexpr contains_stack_process_v = contains_stack_process<TClass>::value;
} // namespace corsika::process
......@@ -58,17 +58,42 @@ namespace corsika::process {
class SwitchProcessSequence
: public BaseProcess<SwitchProcessSequence<TProcess1, TProcess2, TSelect>> {
using TProcess1type = typename std::decay<TProcess1>::type;
using TProcess2type = typename std::decay<TProcess2>::type;
// static_assert(std::is_base_of_v<!StackProcess<TProcess1>, TProcess1type>, "canot
// use StackProcess in SwitchProcessSequence");
// static_assert(std::is_base_of_v<!StackProcess<TProcess2>, TProcess2type>, "canot
// use StackProcess in SwitchProcessSequence");
using TProcess1type = typename std::decay_t<TProcess1>;
using TProcess2type = typename std::decay_t<TProcess2>;
static bool constexpr t1ProcSeq = is_process_sequence_v<TProcess1type>;
static bool constexpr t2ProcSeq = is_process_sequence_v<TProcess2type>;
// make sure only BaseProcess types TProcess1/2 are passed
static_assert(std::is_base_of_v<BaseProcess<TProcess1type>, TProcess1type>,
"can only use process derived from BaseProcess in "
"SwitchProcessSequence, for Process 1");
static_assert(std::is_base_of_v<BaseProcess<TProcess2type>, TProcess2type>,
"can only use process derived from BaseProcess in "
"SwitchProcessSequence, for Process 2");
// make sure TSelect is a function
static_assert(!std::is_function_v<TSelect>, "TSelect must be a function type");
// make sure none of TProcess1/2 is a StackProcess
static_assert(!std::is_base_of_v<StackProcess<TProcess1type>, TProcess1type>,
"cannot use StackProcess in SwitchProcessSequence, for Process 1");
static_assert(!std::is_base_of_v<StackProcess<TProcess2type>, TProcess2type>,
"cannot use StackProcess in SwitchProcessSequence, for Process 2");
// if TProcess1/2 are already ProcessSequences, make sure they do not contain
// StackProcess
// if constexpr (t1ProcSeq) {
static_assert(!contains_stack_process_v<TProcess1type>,
"cannot use StackProcess in SwitchProcessSequence, remove from "
"ProcessSequence 1");
//}
// if constexpr (t2ProcSeq)
static_assert(!contains_stack_process_v<TProcess2type>,
"cannot use StackProcess in SwitchProcessSequence, remove from "
"ProcessSequence 2");
TSelect select_; // this is a reference, if possible
TProcess1 A_; // this is a reference, if possible
......@@ -83,7 +108,6 @@ namespace corsika::process {
template <typename TParticle, typename TVTNType>
EProcessReturn DoBoundaryCrossing(TParticle& particle, TVTNType const& from,
TVTNType const& to) {
switch (select_(particle)) {
case SwitchResult::First: {
if constexpr (std::is_base_of_v<BoundaryCrossingProcess<TProcess1type>,
......@@ -154,7 +178,6 @@ namespace corsika::process {
template <typename TParticle, typename TTrack>
inline corsika::units::si::LengthType MaxStepLength(TParticle& particle,
TTrack& vTrack) {
switch (select_(particle)) {
case SwitchResult::First: {
if constexpr (std::is_base_of_v<ContinuousProcess<TProcess1type>,
......@@ -215,7 +238,6 @@ namespace corsika::process {
[[maybe_unused]] corsika::units::si::InverseGrammageType lambda_inv_select,
[[maybe_unused]] corsika::units::si::InverseGrammageType lambda_inv_sum =
corsika::units::si::InverseGrammageType::zero()) {
switch (select_(view.parent())) {
case SwitchResult::First: {
if constexpr (t1ProcSeq) {
......@@ -294,7 +316,6 @@ namespace corsika::process {
[[maybe_unused]] corsika::units::si::InverseTimeType decay_inv_select,
[[maybe_unused]] corsika::units::si::InverseTimeType decay_inv_sum =
corsika::units::si::InverseTimeType::zero()) {
switch (select_(view.parent())) {
case SwitchResult::First: {
if constexpr (t1ProcSeq) {
......@@ -347,12 +368,12 @@ namespace corsika::process {
// Both, Processes1 and Processes2, must derive from BaseProcesses
template <typename TProcess1, typename TProcess2, typename TSelect>
inline typename std::enable_if<
std::is_base_of<BaseProcess<typename std::decay<TProcess1>::type>,
typename std::decay<TProcess1>::type>::value &&
std::is_base_of<BaseProcess<typename std::decay<TProcess2>::type>,
typename std::decay<TProcess2>::type>::value,
SwitchProcessSequence<TProcess1, TProcess2, TSelect>>::type
inline typename std::enable_if_t<
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess1>>,
typename std::decay_t<TProcess1>> &&
std::is_base_of_v<BaseProcess<typename std::decay_t<TProcess2>>,
typename std::decay_t<TProcess2>>,
SwitchProcessSequence<TProcess1, TProcess2, TSelect>>
select(TProcess1&& vA, TProcess2&& vB, TSelect selector) {
return SwitchProcessSequence<TProcess1, TProcess2, TSelect>(vA, vB, selector);
}
......
......@@ -266,6 +266,8 @@ TEST_CASE("Process Sequence", "[Process Sequence]") {
auto sequence1 = process::sequence(m1, m2, m3, m4);
CHECK(is_process_sequence_v<decltype(sequence1)> == true);
CHECK(is_process_sequence_v<decltype(m2)> == false);
CHECK(is_switch_process_sequence_v<decltype(sequence1)> == false);
CHECK(is_switch_process_sequence_v<decltype(m2)> == false);
auto sequence2 = process::sequence(m1, m2, m3);
CHECK(is_process_sequence_v<decltype(sequence2)> == true);
......@@ -358,6 +360,16 @@ TEST_CASE("Process Sequence", "[Process Sequence]") {
CHECK(s1.GetCount() == 20);
CHECK(s2.GetCount() == 10);
ContinuousProcess2 cp2(1); // += 0.111
Process2 m2(2); // /= 1.1
auto sequence2 = process::sequence(cp2, m2);
auto sequence3 = process::sequence(cp2, m2, s1);
CHECK(is_process_sequence_v<decltype(sequence2)> == true);
CHECK(is_process_sequence_v<decltype(sequence3)> == true);
CHECK(contains_stack_process_v<decltype(sequence2)> == false);
CHECK(contains_stack_process_v<decltype(sequence3)> == true);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment