From fec83fa975f49cf878a0d7d2fadd4f6ffed6dcf5 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 26 Jan 2017 15:36:12 -0800 Subject: [PATCH] Eliminate moved_ref Use real rvalue references instead --- src/common.h | 9 --------- src/parse_execution.cpp | 4 ++-- src/parse_execution.h | 2 +- src/parse_tree.cpp | 8 ++------ src/parse_tree.h | 6 ++++-- src/parser.cpp | 10 +++++----- src/parser.h | 4 +--- src/reader.cpp | 2 +- 8 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/common.h b/src/common.h index 536f56aa3..fbd32edf4 100644 --- a/src/common.h +++ b/src/common.h @@ -479,15 +479,6 @@ inline wcstring to_string(const int &x) { return to_string(static_cast(x)); } -// A hackish thing to simulate rvalue references in C++98. The idea is that you can define a -// constructor to take a moved_ref and then swap() out of it. -template -struct moved_ref { - T &val; - - explicit moved_ref(T &v) : val(v) {} -}; - wchar_t **make_null_terminated_array(const wcstring_list_t &lst); char **make_null_terminated_array(const std::vector &lst); diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 252f8d689..feac256d4 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -75,10 +75,10 @@ static wcstring profiling_cmd_name_for_redirectable_block(const parse_node_t &no return result; } -parse_execution_context_t::parse_execution_context_t(moved_ref t, +parse_execution_context_t::parse_execution_context_t(parse_node_tree_t t, const wcstring &s, parser_t *p, int initial_eval_level) - : tree(t), + : tree(std::move(t)), src(s), parser(p), eval_level(initial_eval_level), diff --git a/src/parse_execution.h b/src/parse_execution.h index 23d27e506..7e6867fd7 100644 --- a/src/parse_execution.h +++ b/src/parse_execution.h @@ -127,7 +127,7 @@ class parse_execution_context_t { int line_offset_of_character_at_offset(size_t char_idx); public: - parse_execution_context_t(moved_ref t, const wcstring &s, parser_t *p, + parse_execution_context_t(parse_node_tree_t t, const wcstring &s, parser_t *p, int initial_eval_level); /// Returns the current eval level. diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index f95ea1aa3..121ffc513 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -603,15 +603,11 @@ void parse_ll_t::determine_node_ranges(void) { void parse_ll_t::acquire_output(parse_node_tree_t *output, parse_error_list_t *errors) { if (output != NULL) { - output->swap(this->nodes); + *output = std::move(this->nodes); } - this->nodes.clear(); - if (errors != NULL) { - errors->swap(this->errors); + *errors = std::move(this->errors); } - this->errors.clear(); - this->symbol_stack.clear(); } void parse_ll_t::parse_error(parse_token_t token, parse_error_code_t code, const wchar_t *fmt, diff --git a/src/parse_tree.h b/src/parse_tree.h index 0582fc947..7b994fbd6 100644 --- a/src/parse_tree.h +++ b/src/parse_tree.h @@ -140,8 +140,10 @@ class parse_node_t { class parse_node_tree_t : public std::vector { public: parse_node_tree_t() {} - - parse_node_tree_t(moved_ref t) { this->swap(t.val); } + parse_node_tree_t(parse_node_tree_t &&) = default; + parse_node_tree_t &operator=(parse_node_tree_t &&) = default; + parse_node_tree_t(const parse_node_tree_t &) = delete; // no copying + parse_node_tree_t &operator=(const parse_node_tree_t &) = delete; // no copying // Get the node corresponding to a child of the given node, or NULL if there is no such child. // If expected_type is provided, assert that the node has that type. diff --git a/src/parser.cpp b/src/parser.cpp index b1169a64b..586bb8c5f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -593,15 +593,14 @@ int parser_t::eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t fwprintf(stderr, L"%ls\n", backtrace_and_desc.c_str()); return 1; } - return this->eval_acquiring_tree(cmd, io, block_type, moved_ref(tree)); + return this->eval(cmd, io, block_type, std::move(tree)); } -int parser_t::eval_acquiring_tree(const wcstring &cmd, const io_chain_t &io, - enum block_type_t block_type, moved_ref tree) { +int parser_t::eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type, parse_node_tree_t tree) { CHECK_BLOCK(1); assert(block_type == TOP || block_type == SUBST); - if (tree.val.empty()) { + if (tree.empty()) { return 0; } @@ -613,7 +612,8 @@ int parser_t::eval_acquiring_tree(const wcstring &cmd, const io_chain_t &io, (execution_contexts.empty() ? -1 : execution_contexts.back()->current_eval_level()); // Append to the execution context stack. - execution_contexts.push_back(make_unique(tree, cmd, this, exec_eval_level)); + execution_contexts.push_back(make_unique(std::move(tree), cmd, + this, exec_eval_level)); const parse_execution_context_t *ctx = execution_contexts.back().get(); // Execute the first node. diff --git a/src/parser.h b/src/parser.h index 3385526e1..f28d0c3f7 100644 --- a/src/parser.h +++ b/src/parser.h @@ -244,9 +244,7 @@ class parser_t { int eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type); /// Evaluate the expressions contained in cmd, which has been parsed into the given parse tree. - /// This takes ownership of the tree. - int eval_acquiring_tree(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type, - moved_ref t); + int eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t block_type, parse_node_tree_t t); /// Evaluates a block node at the given node offset in the topmost execution context. int eval_block_node(node_offset_t node_idx, const io_chain_t &io, enum block_type_t block_type); diff --git a/src/reader.cpp b/src/reader.cpp index 957da8fa3..33021d25e 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -3305,7 +3305,7 @@ static int read_ni(int fd, const io_chain_t &io) { parse_error_list_t errors; parse_node_tree_t tree; if (!parse_util_detect_errors(str, &errors, false /* do not accept incomplete */, &tree)) { - parser.eval_acquiring_tree(str, io, TOP, moved_ref(tree)); + parser.eval(str, io, TOP, std::move(tree)); } else { wcstring sb; parser.get_backtrace(str, errors, &sb);