// selection_node.hpp // Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef LEXERTL_SELECTION_NODE_HPP #define LEXERTL_SELECTION_NODE_HPP #include "node.hpp" namespace lexertl { namespace detail { template class basic_selection_node : public basic_node { public: using node = basic_node; using bool_stack = typename node::bool_stack; using const_node_stack = typename node::const_node_stack; using node_ptr_vector = typename node::node_ptr_vector; using node_stack = typename node::node_stack; using node_type = typename node::node_type; basic_selection_node(observer_ptr left_, observer_ptr right_) : node(left_->nullable() || right_->nullable()), _left(left_), _right(right_) { _left->append_firstpos(node::_firstpos); _right->append_firstpos(node::_firstpos); _left->append_lastpos(node::_lastpos); _right->append_lastpos(node::_lastpos); } virtual ~basic_selection_node() override { } virtual node_type what_type() const override { return node::SELECTION; } virtual bool traverse(const_node_stack &node_stack_, bool_stack &perform_op_stack_) const override { perform_op_stack_.push(true); switch (_right->what_type()) { case node::SEQUENCE: case node::SELECTION: case node::ITERATION: perform_op_stack_.push(false); break; default: break; } node_stack_.push(_right); node_stack_.push(_left); return true; } private: observer_ptr _left; observer_ptr _right; virtual void copy_node(node_ptr_vector &node_ptr_vector_, node_stack &new_node_stack_, bool_stack &perform_op_stack_, bool &down_) const override { if (perform_op_stack_.top()) { observer_ptr rhs_ = new_node_stack_.top(); new_node_stack_.pop(); observer_ptr lhs_ = new_node_stack_.top(); node_ptr_vector_.emplace_back (std::make_unique(lhs_, rhs_)); new_node_stack_.top() = node_ptr_vector_.back().get(); } else { down_ = true; } perform_op_stack_.pop(); } // No copy construction. basic_selection_node(const basic_selection_node &) = delete; // No assignment. const basic_selection_node &operator = (const basic_selection_node &) = delete; }; } } #endif