Forked from
Air Shower Physics / corsika
3128 commits behind the upstream repository.
-
ralfulrich authoredralfulrich authored
ProcessSequence.h 12.64 KiB
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#ifndef _include_ProcessSequence_h_
#define _include_ProcessSequence_h_
#include <corsika/process/BaseProcess.h>
#include <corsika/process/BoundaryCrossingProcess.h>
#include <corsika/process/ContinuousProcess.h>
#include <corsika/process/DecayProcess.h>
#include <corsika/process/InteractionProcess.h>
#include <corsika/process/ProcessReturn.h>
#include <corsika/process/SecondariesProcess.h>
#include <corsika/process/StackProcess.h>
#include <corsika/units/PhysicalUnits.h>
#include <cmath>
#include <limits>
#include <type_traits>
namespace corsika::process {
/**
\class ProcessSequence
A compile time static list of processes. The compiler will
generate a new type based on template logic containing all the
elements.
\comment Using CRTP pattern,
https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
*/
// define a marker (trait class) to tag any class that qualifies as "Process" for the
// "ProcessSequence"
std::false_type is_process_impl(...);
template <class T>
using is_process = decltype(is_process_impl(std::declval<T*>()));
// this is a marker to track which BaseProcess is also a ProcessSequence
template <typename T>
struct is_process_sequence : std::false_type {};
template <typename T>
bool constexpr is_process_sequence_v = is_process_sequence<T>::value;
namespace switch_process {
template <typename A, typename B>
class SwitchProcess; // fwd-decl.
}
// to detect SwitchProcesses inside the ProcessSequence
template <typename T>
struct is_switch_process : std::false_type {};
template <typename T>
bool constexpr is_switch_process_v = is_switch_process<T>::value;
template <typename A, typename B>
struct is_process_sequence<switch_process::SwitchProcess<A, B>> : std::true_type {};
/**
T1 and T2 are both references if possible (lvalue), otherwise