23 template <
class Element>
class decay;
43 template <
class FillElement,
class FillExpression,
class ArrowSwitch>
45 std::string::const_iterator
const &end,
46 FillElement fill_element,
47 FillExpression fill_expression,
48 ArrowSwitch arrow_switch) {
50 while (tokens::match_token<tokens::space>(sit))
53 if (tokens::match_token<tokens::left_bra>(sit))
55 "Expression starts with another expression", end - sit);
60 if (tokens::match_token<tokens::space>(sit)) {
72 }
else if (tokens::match_token<tokens::left_bra>(sit)) {
81 if (!tokens::match_token<tokens::right_bra>(sit))
83 "Expected closing braces", end - sit);
95 }
else if (tokens::match_token<tokens::right_bra>(sit)) {
104 }
else if (tokens::match_token<tokens::arrow>(sit)) {
130 template <
class Process>
132 typename Process::builder_type
builder) {
137 auto const send = str.
cend();
139 Process p{sit, send, builder};
142 if (tokens::match_token<tokens::right_bra>(sit))
160 template <
class Element>
class reaction;
161 template <
class Element>
class decay;
168 template <
class Element,
template <
class>
class Chain>
170 :
protected std::variant<element_wrapper<Element>, Chain<Element>> {
178 using base_type::base_type;
182 return this->type() == processes::node_type::element;
187 return type() == processes::node_type::reaction;
192 return this->type() == processes::node_type::decay;
196 processes::node_type
type()
const {
198 if (std::holds_alternative<element_type>(*
this))
199 return processes::node_type::element;
201 if constexpr (utils::is_template_specialization_v<chain_type, reaction>)
202 return processes::node_type::reaction;
205 return processes::node_type::decay;
208 "Unexpected internal compile-time error");
213 Element
const &
as_element()
const {
return *as_element_wrapper(); }
217 return std::get<Chain<Element>>(*this);
223 return std::get<element_type>(*this);
228 namespace processes::detail {
236 template <
class Element,
template <
class>
class Chain>
240 auto size = first.size();
242 if (size != second.size())
248 for (
auto i = 0u; i < size; ++i) {
250 for (
auto j = 0u; j < size; ++j) {
256 if (second[j].type() != first[i].type())
260 switch (first[i].type()) {
261 case (processes::node_type::element):
262 if (first[i].as_element() == second[i].as_element())
265 case (processes::node_type::reaction):
266 if (first[i].as_chain() == second[i].as_chain())
269 case (processes::node_type::decay):
270 if (first[i].as_chain() == second[i].as_chain())
273 case (processes::node_type::unknown_node_type):
275 "A node can not be of unknown type (internal error); please " 326 template <
class Element>
class reaction final {
372 return !(*
this == other);
387 template <
class Process>
390 typename Process::builder_type);
408 [&](std::string::const_iterator
const &start) ->
void {
411 auto fill_reaction = [&]() ->
void {
414 auto arrow_switch = [&]() ->
void {
415 if (!m_reactants.size())
419 if (current_set == &m_products)
423 current_set = &m_products;
429 if (!m_reactants.size())
433 if (!m_products.size())
450 template <
class Element>
class decay final {
469 Element
const &
head()
const {
return *(*m_head); }
480 return (*m_head == *other.
m_head) &&
486 return !(*
this == other);
500 decay(std::string::const_iterator &&begin,
502 :
decay{begin, end, builder} {}
504 template <
class Process>
507 typename Process::builder_type);
519 decay(std::string::const_iterator &sit,
522 bool fill_products =
false;
525 [&](std::string::const_iterator
const &start) ->
void {
528 }
else if (fill_products) {
534 auto fill_decay = [&] {
538 }
else if (fill_products) {
539 this->m_products.emplace_back(
decay(sit, end, builder));
544 auto arrow_switch = [&] {
553 fill_products =
true;
561 "No elements have been parsed", end - sit);
563 if (!m_products.size())
580 template <
class Element>
584 return processes::make_process<reaction<Element>>(str,
builder);
592 template <
class Element>
594 return make_reaction_for<Element>(str, element_traits::builder<Element>);
603 template <
class Element>
606 return processes::make_process<decay<Element>>(str,
builder);
615 return make_decay_for<Element>(str, element_traits::builder<Element>);
static constexpr auto dependent_false_v
A false type that can be used with static_assert
Definition: utils.hpp:15
Description of a process where reactants generate a set of products.
Definition: processes.hpp:22
bool is_decay() const
Check if the underlying class is a decay.
Definition: processes.hpp:191
Element m_element
Underlying element.
Definition: processes.hpp:319
Syntax error with an unformatted message.
Definition: exceptions.hpp:69
syntax_error update(std::string const &str)
Definition: exceptions.hpp:77
reaction< Element > make_reaction(std::string const &str)
Create a new reaction.
Definition: processes.hpp:593
element_traits::builder_tpl_t< Element > builder_type
Definition: processes.hpp:454
nodes_type m_products
Products.
Definition: processes.hpp:441
void process_expression(std::string::const_iterator &sit, std::string::const_iterator const &end, FillElement fill_element, FillExpression fill_expression, ArrowSwitch arrow_switch)
Internal function to process an expression.
Definition: processes.hpp:44
Exceptions that can be thrown when running the functions of the package.
Element const & as_element() const
Return the pointer to the underlying object casted to an element.
Definition: processes.hpp:213
Raised when unexpected problems appear, which should be reported as bugs.
Definition: exceptions.hpp:38
Element const & operator*() const
Access the underlying element by reference.
Definition: processes.hpp:313
Description of a process where head particle generate a set of products.
Definition: processes.hpp:23
processes::node_type type() const
Get the node type.
Definition: processes.hpp:196
static constexpr auto builder
Default builder for a given kind of element.
Definition: element_traits.hpp:50
nodes_type m_products
Products.
Definition: processes.hpp:571
Contains macros to define smart enumeration types.
nodes_type const & reactants() const
Get the reactants of the reaction.
Definition: processes.hpp:348
bool operator==(decay< Element > const &other) const
Comparison operator.
Definition: processes.hpp:475
Tokens allowed in a reaction or decay.
std::function< T(std::string const &)> const & builder_tpl_t
General builder type for a given kind of element.
Definition: element_traits.hpp:57
Main namespace of the Reactions package.
Definition: all.hpp:22
static constexpr auto is_template_specialization_v
Definition: utils.hpp:54
static const size_t size
Definition: tokens.hpp:16
bool operator!=(decay< Element > const &other) const
Comparison operator.
Definition: processes.hpp:485
bool operator==(reaction< Element > const &other) const
Compare two reactions.
Definition: processes.hpp:360
Base class for a process node.
Definition: processes.hpp:169
Template for elements of a reaction or decay.
Definition: processes.hpp:21
Process make_process(std::string const &str, typename Process::builder_type builder)
Make a new process (a reaction or a decay)
Definition: processes.hpp:131
bool is_element() const
Check if the underlying class is an element.
Definition: processes.hpp:181
element_type const & as_element_wrapper() const
Return the underlying object casted to a wrapped.
Definition: processes.hpp:222
reaction< Element > make_reaction_for(std::string const &str, typename reaction< Element >::builder_type builder)
Create a new reaction with a custom builder.
Definition: processes.hpp:582
decay< Element > make_decay_for(std::string const &str, typename decay< Element >::builder_type builder)
Create a new decay with a custom builder.
Definition: processes.hpp:604
Element const * operator->() const
Access the underlying element by pointer.
Definition: processes.hpp:315
reaction(std::string::const_iterator &&begin, std::string::const_iterator const &end, builder_type builder)
Constructor from the string iterators.
Definition: processes.hpp:383
nodes_type const & products() const
Get the products of the reaction.
Definition: processes.hpp:351
Element const & head() const
Get the head particle of the decay.
Definition: processes.hpp:469
Utilities to work with element types.
decay(std::string::const_iterator &sit, std::string::const_iterator const &end, builder_type builder)
Constructor from the string iterators.
Definition: processes.hpp:519
std::optional< element_type > m_head
Head particle.
Definition: processes.hpp:569
bool check_nodes(std::vector< node< Element, Chain >> const &first, std::vector< node< Element, Chain >> const &second)
Compare two nodes.
Definition: processes.hpp:237
chain_type const & as_chain() const
Return the pointer to the underlying object casted to a reaction.
Definition: processes.hpp:216
bool operator!=(reaction< Element > const &other) const
Compare two reactions.
Definition: processes.hpp:371
reaction(std::string::const_iterator &sit, std::string::const_iterator const &end, builder_type builder)
Constructor from the string iterators.
Definition: processes.hpp:402
nodes_type const & products() const
Get the products of the decay.
Definition: processes.hpp:472
decay(std::string::const_iterator &&begin, std::string::const_iterator const &end, builder_type builder)
Constructor from the string iterators.
Definition: processes.hpp:500
bool is_reaction() const
Check if the underlying class is a reaction.
Definition: processes.hpp:186
element_traits::builder_tpl_t< Element > builder_type
Underlying element type.
Definition: processes.hpp:331
decay< Element > make_decay(std::string const &str)
Create a new decay.
Definition: processes.hpp:614
nodes_type m_reactants
Reactants.
Definition: processes.hpp:439
element_wrapper(Element &&e)
Constructor given the underlying element.
Definition: processes.hpp:301
REACTIONS_POW_ENUM_WITH_UNKNOWN(node_type, element, reaction, decay)
Node types.
T emplace_back(T... args)