From 6b9d7d8b38f17c7ca0b77c288d05292facc5c464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Tue, 5 Sep 2023 10:48:39 +0200 Subject: [PATCH 1/8] Stop calling copy constructor repeatedly --- include/mata/parser/inter-aut.hh | 6 +++-- src/inter-aut.cc | 39 +++++++++++++++----------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/include/mata/parser/inter-aut.hh b/include/mata/parser/inter-aut.hh index ebf481a2b..4c02b7419 100644 --- a/include/mata/parser/inter-aut.hh +++ b/include/mata/parser/inter-aut.hh @@ -125,10 +125,12 @@ struct FormulaGraph { FormulaGraph() = default; FormulaGraph(const FormulaNode& n) : node(n), children() {} + FormulaGraph(FormulaNode&& n) : node(std::move(n)), children() {} FormulaGraph(const FormulaGraph& g) : node(g.node), children(g.children) {} + FormulaGraph(FormulaGraph&& g) : node(std::move(g.node)), children(std::move(g.children)) {} - FormulaGraph& operator=(const mata::FormulaGraph& other) = default; - FormulaGraph& operator=(mata::FormulaGraph&& other) noexcept = default; + FormulaGraph& operator=(const mata::FormulaGraph&) = default; + FormulaGraph& operator=(mata::FormulaGraph&&) noexcept = default; std::unordered_set collect_node_names() const; void print_tree(std::ostream& os) const; diff --git a/src/inter-aut.cc b/src/inter-aut.cc index 57f7c0ec2..5b4e31a83 100644 --- a/src/inter-aut.cc +++ b/src/inter-aut.cc @@ -265,31 +265,30 @@ namespace { * @param postfix A postfix representation of transition formula * @return A parsed graph */ - mata::FormulaGraph postfix_to_graph(const std::vector &postfix) - { - std::vector opstack; - - for (const auto& node : postfix) { - mata::FormulaGraph gr(node); + mata::FormulaGraph postfix_to_graph(std::vector postfix) { + std::vector opstack{}; + opstack.reserve(4); + for (mata::FormulaNode& node: postfix) { + mata::FormulaGraph gr(std::move(node)); switch (node.type) { case mata::FormulaNode::Type::OPERAND: - opstack.push_back(gr); + opstack.emplace_back(std::move(gr)); break; case mata::FormulaNode::Type::OPERATOR: switch (node.operator_type) { case mata::FormulaNode::OperatorType::NEG: assert(!opstack.empty()); - gr.children.push_back(opstack.back()); + gr.children.emplace_back(std::move(opstack.back())); opstack.pop_back(); - opstack.push_back(gr); + opstack.emplace_back(std::move(gr)); break; default: assert(opstack.size() > 1); - gr.children.push_back(opstack.back()); + gr.children.emplace_back(std::move(opstack.back())); opstack.pop_back(); - gr.children.insert(gr.children.begin(), opstack.back()); + gr.children.emplace(gr.children.cbegin(), std::move(opstack.back())); opstack.pop_back(); - opstack.push_back(gr); + opstack.emplace_back(std::move(gr)); } break; default: assert(false && "Unknown type of node"); @@ -297,9 +296,8 @@ namespace { } assert(opstack.size() == 1); - - return opstack.back(); - } + return std::move(opstack[0]); +} /** * Function adds disjunction operators to a postfix form when there are no operators at all. @@ -383,14 +381,15 @@ namespace { aut.initial_enumerated = true; postfix = add_disjunction_implicitly(postfix); } - aut.initial_formula = postfix_to_graph(postfix); + aut.initial_formula = postfix_to_graph(std::move(postfix)); } else if (key.find("Final") != std::string::npos) { auto postfix = infix_to_postfix(aut, keypair.second); if (no_operators(postfix)) { postfix = add_disjunction_implicitly(postfix); aut.final_enumerated = true; } - aut.final_formula = postfix_to_graph(postfix); + + aut.final_formula = postfix_to_graph(std::move(postfix));; } } @@ -438,7 +437,7 @@ size_t mata::IntermediateAut::get_number_of_disjuncts() const void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const std::vector &tokens) { assert(tokens.size() > 1); // transition formula has at least two items - const mata::FormulaNode lhs = create_node(aut, tokens[0]); + mata::FormulaNode lhs = create_node(aut, tokens[0]); const std::vector rhs(tokens.begin()+1, tokens.end()); std::vector postfix; @@ -471,9 +470,7 @@ void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const s assert(node.is_rightpar() || node.name != ")"); } #endif // #ifndef NDEBUG. - const mata::FormulaGraph graph = postfix_to_graph(postfix); - - aut.transitions.emplace_back(lhs, graph); + aut.transitions.emplace_back(std::move(lhs), postfix_to_graph(std::move(postfix))); } std::unordered_set mata::FormulaGraph::collect_node_names() const From 7623c06cc82ef0dd0cad26464e8716fe860a846b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Tue, 5 Sep 2023 13:05:03 +0200 Subject: [PATCH 2/8] Use deque to allow efficient insert to the front --- include/mata/parser/inter-aut.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mata/parser/inter-aut.hh b/include/mata/parser/inter-aut.hh index 4c02b7419..d5306b2ff 100644 --- a/include/mata/parser/inter-aut.hh +++ b/include/mata/parser/inter-aut.hh @@ -121,7 +121,7 @@ public: */ struct FormulaGraph { FormulaNode node{}; - std::vector children{}; + std::deque children{}; FormulaGraph() = default; FormulaGraph(const FormulaNode& n) : node(n), children() {} From 59f0e6bcb86ce8e0dc04cde8b88d8c00e24728fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Tue, 5 Sep 2023 13:49:12 +0200 Subject: [PATCH 3/8] Optimize working with intermediate automaton --- src/inter-aut.cc | 106 ++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 57 deletions(-) diff --git a/src/inter-aut.cc b/src/inter-aut.cc index 5b4e31a83..c9d989bf4 100644 --- a/src/inter-aut.cc +++ b/src/inter-aut.cc @@ -92,13 +92,9 @@ namespace { return std::find(vec.begin(), vec.end(), item) != vec.end(); } - bool no_operators(const std::vector nodes) + bool no_operators(const std::vector& nodes) { - for (const auto& node : nodes) - if (node.is_operator()) - return false; - - return true; + return std::ranges::all_of(nodes, [](const mata::FormulaNode& node){ return !node.is_operator();}); } std::string serialize_graph(const mata::FormulaGraph& graph) @@ -128,58 +124,57 @@ namespace { return lhs + " " + graph.node.raw + " " + rhs; } - mata::FormulaNode create_node(const mata::IntermediateAut &mata, const std::string &token) - { + mata::FormulaNode create_node(const mata::IntermediateAut &mata, const std::string &token) { if (is_logical_operator(token[0])) { switch (token[0]) { case '&': - return mata::FormulaNode{ mata::FormulaNode::Type::OPERATOR, token, token, - mata::FormulaNode::OperatorType::AND}; + return { mata::FormulaNode::Type::OPERATOR, token, token, + mata::FormulaNode::OperatorType::AND }; case '|': - return mata::FormulaNode{ mata::FormulaNode::Type::OPERATOR, token, token, - mata::FormulaNode::OperatorType::OR}; + return { mata::FormulaNode::Type::OPERATOR, token, token, + mata::FormulaNode::OperatorType::OR }; case '!': - return mata::FormulaNode{ mata::FormulaNode::Type::OPERATOR, token, token, - mata::FormulaNode::OperatorType::NEG}; + return { mata::FormulaNode::Type::OPERATOR, token, token, + mata::FormulaNode::OperatorType::NEG }; default: assert(false); } } else if (token == "(") { - return mata::FormulaNode{ mata::FormulaNode::Type::LEFT_PARENTHESIS, token}; + return { mata::FormulaNode::Type::LEFT_PARENTHESIS, token}; } else if (token == ")") { - return mata::FormulaNode{ mata::FormulaNode::Type::RIGHT_PARENTHESIS, token}; + return { mata::FormulaNode::Type::RIGHT_PARENTHESIS, token}; } else if (token == "true") { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::SYMBOL}; } else if (token == "false") { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::SYMBOL}; } else if (is_naming_enum(mata.state_naming) && contains(mata.states_names, token)) { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::STATE}; } else if (is_naming_enum(mata.node_naming) && contains(mata.nodes_names, token)) { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::NODE}; } else if (is_naming_enum(mata.symbol_naming) && contains(mata.symbols_names, token)) { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::SYMBOL}; } else if (is_naming_marker(mata.state_naming) && token[0] == 'q') { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token.substr(1), + return { mata::FormulaNode::Type::OPERAND, token, token.substr(1), mata::FormulaNode::OperandType::STATE}; } else if (is_naming_marker(mata.node_naming) && token[0] == 'n') { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token.substr(1), + return { mata::FormulaNode::Type::OPERAND, token, token.substr(1), mata::FormulaNode::OperandType::NODE}; } else if (is_naming_marker(mata.symbol_naming) && token[0] == 'a') { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token.substr(1), + return { mata::FormulaNode::Type::OPERAND, token, token.substr(1), mata::FormulaNode::OperandType::SYMBOL}; } else if (is_naming_auto(mata.state_naming)) { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::STATE}; } else if (is_naming_auto(mata.node_naming)) { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::NODE}; } else if (is_naming_auto(mata.symbol_naming)) { - return mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, token, token, + return { mata::FormulaNode::Type::OPERAND, token, token, mata::FormulaNode::OperandType::SYMBOL}; } @@ -215,14 +210,14 @@ namespace { mata::FormulaNode node = create_node(aut, token); switch (node.type) { case mata::FormulaNode::Type::OPERAND: - output.push_back(node); + output.emplace_back(std::move(node)); break; case mata::FormulaNode::Type::LEFT_PARENTHESIS: - opstack.push_back(node); + opstack.emplace_back(std::move(node)); break; case mata::FormulaNode::Type::RIGHT_PARENTHESIS: while (!opstack.back().is_leftpar()) { - output.push_back(opstack.back()); + output.emplace_back(std::move(opstack.back())); opstack.pop_back(); } opstack.pop_back(); @@ -234,18 +229,18 @@ namespace { if (opstack[j_size_t].is_leftpar()) break; if (lower_precedence(node.operator_type, opstack[j_size_t].operator_type)) { - output.push_back(opstack[j_size_t]); + output.emplace_back(std::move(opstack[j_size_t])); opstack.erase(opstack.begin()+j); } } - opstack.push_back(node); + opstack.emplace_back(std::move(node)); break; default: assert(false); } } while (!opstack.empty()) { - output.push_back(opstack.back()); + output.push_back(std::move(opstack.back())); opstack.pop_back(); } @@ -270,12 +265,12 @@ namespace { opstack.reserve(4); for (mata::FormulaNode& node: postfix) { mata::FormulaGraph gr(std::move(node)); - switch (node.type) { + switch (gr.node.type) { case mata::FormulaNode::Type::OPERAND: opstack.emplace_back(std::move(gr)); break; case mata::FormulaNode::Type::OPERATOR: - switch (node.operator_type) { + switch (gr.node.operator_type) { case mata::FormulaNode::OperatorType::NEG: assert(!opstack.empty()); gr.children.emplace_back(std::move(opstack.back())); @@ -286,7 +281,7 @@ namespace { assert(opstack.size() > 1); gr.children.emplace_back(std::move(opstack.back())); opstack.pop_back(); - gr.children.emplace(gr.children.cbegin(), std::move(opstack.back())); + gr.children.emplace_front(std::move(opstack.back())); opstack.pop_back(); opstack.emplace_back(std::move(gr)); } @@ -306,7 +301,7 @@ namespace { * @param postfix Postfix to which operators are eventually added * @return A postfix with eventually added operators */ - std::vector add_disjunction_implicitly(const std::vector &postfix) + std::vector add_disjunction_implicitly(std::vector postfix) { if (postfix.size() == 1) // no need to add operators return postfix; @@ -320,14 +315,14 @@ namespace { if (postfix.size() >= 2) { res.push_back(postfix[0]); res.push_back(postfix[1]); - res.push_back(mata::FormulaNode( - mata::FormulaNode::Type::OPERATOR, "|", "|", mata::FormulaNode::OperatorType::OR)); + res.emplace_back( + mata::FormulaNode::Type::OPERATOR, "|", "|", mata::FormulaNode::OperatorType::OR); } for (size_t i = 2; i < postfix.size(); ++i) { res.push_back(postfix[i]); - res.push_back(mata::FormulaNode( - mata::FormulaNode::Type::OPERATOR, "|", "|", mata::FormulaNode::OperatorType::OR)); + res.emplace_back( + mata::FormulaNode::Type::OPERATOR, "|", "|", mata::FormulaNode::OperatorType::OR); } return res; @@ -340,8 +335,7 @@ namespace { * @param section A section of input MATA format * @return Parsed InterAutomata representing an automaton from input. */ - mata::IntermediateAut mf_to_aut(const mata::parser::ParsedSection §ion) - { + mata::IntermediateAut mf_to_aut(const mata::parser::ParsedSection& section) { mata::IntermediateAut aut; if (section.type.find("NFA") != std::string::npos) { @@ -379,13 +373,13 @@ namespace { auto postfix = infix_to_postfix(aut, keypair.second); if (no_operators(postfix)) { aut.initial_enumerated = true; - postfix = add_disjunction_implicitly(postfix); + postfix = add_disjunction_implicitly(std::move(postfix)); } aut.initial_formula = postfix_to_graph(std::move(postfix)); } else if (key.find("Final") != std::string::npos) { auto postfix = infix_to_postfix(aut, keypair.second); if (no_operators(postfix)) { - postfix = add_disjunction_implicitly(postfix); + postfix = add_disjunction_implicitly(std::move(postfix)); aut.final_enumerated = true; } @@ -434,7 +428,7 @@ size_t mata::IntermediateAut::get_number_of_disjuncts() const * @param aut Automaton to which transition will be added. * @param tokens Series of tokens representing transition formula */ -void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const std::vector &tokens) +void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const std::vector& tokens) { assert(tokens.size() > 1); // transition formula has at least two items mata::FormulaNode lhs = create_node(aut, tokens[0]); @@ -448,18 +442,16 @@ void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const s // symbol and state naming and put conjunction to transition if (aut.alphabet_type != mata::IntermediateAut::AlphabetType::BITVECTOR) { assert(rhs.size() == 2); - postfix.push_back(mata::FormulaNode{ mata::FormulaNode::Type::OPERAND, rhs[0], rhs[0], - mata::FormulaNode::OperandType::SYMBOL}); - postfix.push_back(create_node(aut,rhs[1])); + postfix.emplace_back(mata::FormulaNode::Type::OPERAND, rhs[0], rhs[0], mata::FormulaNode::OperandType::SYMBOL); + postfix.emplace_back(create_node(aut,rhs[1])); } else if (aut.alphabet_type == mata::IntermediateAut::AlphabetType::BITVECTOR) { // this is a case where rhs state not separated by conjunction from rest of trans postfix = infix_to_postfix(aut, std::vector(rhs.begin(), rhs.end()-1)); - postfix.push_back(create_node(aut,rhs.back())); + postfix.emplace_back(create_node(aut,rhs.back())); } else assert(false && "Unknown NFA type"); - postfix.push_back(mata::FormulaNode( - mata::FormulaNode::Type::OPERATOR, "&", "&", mata::FormulaNode::OperatorType::AND)); + postfix.emplace_back(mata::FormulaNode::Type::OPERATOR, "&", "&", mata::FormulaNode::OperatorType::AND); } else postfix = infix_to_postfix(aut, rhs); @@ -478,7 +470,7 @@ std::unordered_set mata::FormulaGraph::collect_node_names() const std::unordered_set res; std::vector stack; - stack.push_back(reinterpret_cast(&(this->node))); + stack.emplace_back(reinterpret_cast(&(this->node))); while (!stack.empty()) { const FormulaGraph* g = stack.back(); assert(g != nullptr); @@ -524,7 +516,7 @@ std::vector mata::IntermediateAut::parse_from_mf(const ma std::vector result; result.reserve(parsed.size()); - for (const auto& parsed_section : parsed) { + for (const parser::ParsedSection& parsed_section: parsed) { if (parsed_section.type.find("FA") == std::string::npos) { continue; } @@ -550,16 +542,16 @@ void mata::IntermediateAut::add_transition(const FormulaNode& lhs, const Formula { FormulaNode conjunction(FormulaNode::Type::OPERATOR, "&", "&", FormulaNode::OperatorType::AND); FormulaGraph graph(conjunction); - graph.children.push_back(FormulaGraph(symbol)); + graph.children.emplace_back(symbol); graph.children.push_back(rhs); - this->transitions.push_back(std::pair(lhs, graph)); + this->transitions.emplace_back(lhs, std::move(graph)); } void mata::IntermediateAut::add_transition(const FormulaNode& lhs, const FormulaNode& rhs) { assert(rhs.is_operand()); FormulaGraph graph(rhs); - this->transitions.push_back(std::pair(lhs, graph)); + this->transitions.emplace_back(lhs, std::move(graph)); } void mata::IntermediateAut::print_transitions_trees(std::ostream& os) const From c97ca4201b423eb68a6ae995883068eebddf2ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Wed, 6 Sep 2023 12:45:09 +0200 Subject: [PATCH 4/8] Remove unnecessary consts --- src/inter-aut.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/inter-aut.cc b/src/inter-aut.cc index c9d989bf4..c4bf39988 100644 --- a/src/inter-aut.cc +++ b/src/inter-aut.cc @@ -202,11 +202,11 @@ namespace { * @return A postfix notation for input */ std::vector infix_to_postfix( - const mata::IntermediateAut &aut, const std::vector &tokens) { + const mata::IntermediateAut &aut, const std::vector& tokens) { std::vector opstack; std::vector output; - for (const auto& token : tokens) { + for (const std::string& token: tokens) { mata::FormulaNode node = create_node(aut, token); switch (node.type) { case mata::FormulaNode::Type::OPERAND: @@ -432,7 +432,7 @@ void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const s { assert(tokens.size() > 1); // transition formula has at least two items mata::FormulaNode lhs = create_node(aut, tokens[0]); - const std::vector rhs(tokens.begin()+1, tokens.end()); + std::vector rhs(tokens.begin()+1, tokens.end()); std::vector postfix; @@ -443,11 +443,13 @@ void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const s if (aut.alphabet_type != mata::IntermediateAut::AlphabetType::BITVECTOR) { assert(rhs.size() == 2); postfix.emplace_back(mata::FormulaNode::Type::OPERAND, rhs[0], rhs[0], mata::FormulaNode::OperandType::SYMBOL); - postfix.emplace_back(create_node(aut,rhs[1])); + postfix.emplace_back(create_node(aut, rhs[1])); } else if (aut.alphabet_type == mata::IntermediateAut::AlphabetType::BITVECTOR) { - // this is a case where rhs state not separated by conjunction from rest of trans - postfix = infix_to_postfix(aut, std::vector(rhs.begin(), rhs.end()-1)); - postfix.emplace_back(create_node(aut,rhs.back())); + // This is a case where rhs state is not separated by a conjunction from the rest of the transitions. + std::string last_token{ rhs.back() }; + rhs.pop_back(); + postfix = infix_to_postfix(aut, rhs); + postfix.emplace_back(create_node(aut, last_token)); } else assert(false && "Unknown NFA type"); @@ -456,7 +458,7 @@ void mata::IntermediateAut::parse_transition(mata::IntermediateAut &aut, const s postfix = infix_to_postfix(aut, rhs); #ifndef NDEBUG - for (const auto& node : postfix) { + for (const auto& node: postfix) { assert(node.is_operator() || (node.name != "!" && node.name != "&" && node.name != "|")); assert(node.is_leftpar() || node.name != "("); assert(node.is_rightpar() || node.name != ")"); From 253b62d09fcb969114e0c9558665a27d302b8ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Wed, 6 Sep 2023 12:47:18 +0200 Subject: [PATCH 5/8] Optimize code using moves and views --- src/parser.cc | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/parser.cc b/src/parser.cc index 464de638c..78d000ed6 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -63,12 +63,10 @@ bool is_logical_operator(char ch) * * The function assumes that the stream does not span lines */ -std::string get_token_from_line(std::istream& input, bool* quoted) -{ // {{{ +std::string get_token_from_line(std::istream& input, bool* quoted) { assert(nullptr != quoted); - enum class TokenizerState - { + enum class TokenizerState { INIT, UNQUOTED, QUOTED, @@ -199,35 +197,35 @@ std::vector> tokenize_line(const std::string& line) return result; } // tokenize_line(string) }}} -std::vector> split_tokens(const std::vector>& tokens) -{ // {{{ +std::vector> split_tokens(std::vector> tokens) { std::vector> result; for (const auto& token : tokens) { if (token.second) { // is quoted? - result.push_back(token); + result.push_back(std::move(token)); continue; } - const std::string& token_string = token.first; + const std::string_view token_string = token.first; size_t last_operator = 0; - const size_t size = token_string.size(); - for (size_t i = 0; i < size; ++i) { + for (size_t i = 0, token_string_size{ token_string.size() }; i < token_string_size; ++i) { if (is_logical_operator(token_string[i])) { - const std::string token_candidate = token_string.substr(last_operator, i - last_operator); + const std::string_view token_candidate = token_string.substr(last_operator, i - last_operator); // there is token before logical operator (this is case of binary operators, e.g., a&b) - if (!token_candidate.empty()) + if (!token_candidate.empty()) { result.emplace_back(token_candidate, false); + } result.emplace_back(std::string(1,token_string[i]), false); - last_operator = i+1; + last_operator = i + 1; } } - const size_t length = token_string.length(); + const size_t length{ token_string.length() }; if (last_operator == 0) { - result.push_back(token); - } else if (last_operator != length){ // operator was not last, we need parse rest of token - result.emplace_back(token_string.substr(last_operator, length-last_operator), false); } + result.emplace_back(std::move(token)); + } else if (last_operator != length) { // operator was not last, we need parse rest of token + result.emplace_back(token_string.substr(last_operator, length-last_operator), false); + } } return result; @@ -351,7 +349,7 @@ ParsedSection mata::parser::parse_mf_section( continue; } - token_line = split_tokens(token_line); + token_line = split_tokens(std::move(token_line)); const std::string& maybe_key = token_line[0].first; const bool& quoted = token_line[0].second; From 7cd3a6f97e93173016d7e28bfec1c80ea1a7d7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Fri, 8 Sep 2023 11:10:09 +0200 Subject: [PATCH 6/8] Add move constructor --- include/mata/parser/inter-aut.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/mata/parser/inter-aut.hh b/include/mata/parser/inter-aut.hh index d5306b2ff..f1e9b3b07 100644 --- a/include/mata/parser/inter-aut.hh +++ b/include/mata/parser/inter-aut.hh @@ -108,6 +108,8 @@ public: FormulaNode(const FormulaNode& n) : type(n.type), raw(n.raw), name(n.name), operator_type(n.operator_type), operand_type(n.operand_type) {} + FormulaNode(FormulaNode&&) = default; + FormulaNode& operator=(const FormulaNode& other) = default; FormulaNode& operator=(FormulaNode&& other) = default; }; From 7220826d151b25697e166fa7d9e3168a526b1285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Fri, 8 Sep 2023 13:48:32 +0200 Subject: [PATCH 7/8] Refactor to never push to front --- include/mata/parser/inter-aut.hh | 2 +- src/inter-aut.cc | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/mata/parser/inter-aut.hh b/include/mata/parser/inter-aut.hh index f1e9b3b07..f9635de88 100644 --- a/include/mata/parser/inter-aut.hh +++ b/include/mata/parser/inter-aut.hh @@ -123,7 +123,7 @@ public: */ struct FormulaGraph { FormulaNode node{}; - std::deque children{}; + std::vector children{}; FormulaGraph() = default; FormulaGraph(const FormulaNode& n) : node(n), children() {} diff --git a/src/inter-aut.cc b/src/inter-aut.cc index c4bf39988..81b9c8aa6 100644 --- a/src/inter-aut.cc +++ b/src/inter-aut.cc @@ -279,10 +279,11 @@ namespace { break; default: assert(opstack.size() > 1); - gr.children.emplace_back(std::move(opstack.back())); + mata::FormulaGraph second_child{ std::move(opstack.back()) }; opstack.pop_back(); - gr.children.emplace_front(std::move(opstack.back())); + gr.children.emplace_back(std::move(opstack.back())); opstack.pop_back(); + gr.children.emplace_back(std::move(second_child)); opstack.emplace_back(std::move(gr)); } break; From c86e0b40018b685114a386f2a2ce6c06647fafc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Chocholat=C3=BD?= Date: Fri, 8 Sep 2023 13:53:21 +0200 Subject: [PATCH 8/8] Comment out Clang unsupported std::ranges::all_of() function --- src/inter-aut.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/inter-aut.cc b/src/inter-aut.cc index 81b9c8aa6..f5953b33c 100644 --- a/src/inter-aut.cc +++ b/src/inter-aut.cc @@ -92,9 +92,15 @@ namespace { return std::find(vec.begin(), vec.end(), item) != vec.end(); } - bool no_operators(const std::vector& nodes) - { - return std::ranges::all_of(nodes, [](const mata::FormulaNode& node){ return !node.is_operator();}); + bool no_operators(const std::vector& nodes) { + // Refactor using all_of() when Clang adds support for it. + // return std::ranges::all_of(nodes, [](const mata::FormulaNode& node){ return !node.is_operator();}); + for (const auto& node: nodes) { + if (node.is_operator()) { + return false; + } + } + return true; } std::string serialize_graph(const mata::FormulaGraph& graph) @@ -179,7 +185,6 @@ namespace { } throw std::runtime_error("Unknown token " + token); - assert(false); } /**