diff --git a/include/inja/parser.hpp b/include/inja/parser.hpp index 410f5db..dbf8846 100644 --- a/include/inja/parser.hpp +++ b/include/inja/parser.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include "config.hpp" diff --git a/include/inja/renderer.hpp b/include/inja/renderer.hpp index 4e8f803..2e369c4 100644 --- a/include/inja/renderer.hpp +++ b/include/inja/renderer.hpp @@ -22,16 +22,16 @@ class Renderer : public NodeVisitor { using Op = FunctionStorage::Operation; const RenderConfig config; - const TemplateStorage &template_storage; - const FunctionStorage &function_storage; + const TemplateStorage& template_storage; + const FunctionStorage& function_storage; - const Template *current_template; + const Template* current_template; size_t current_level {0}; std::vector template_stack; std::vector block_statement_stack; - const json *data_input; - std::ostream *output_stream; + const json* data_input; + std::ostream* output_stream; json additional_data; json* current_loop_data = &additional_data["loop"]; @@ -42,7 +42,7 @@ class Renderer : public NodeVisitor { bool break_rendering {false}; - bool truthy(const json* data) const { + static bool truthy(const json* data) { if (data->is_boolean()) { return data->get(); } else if (data->is_number()) { @@ -93,11 +93,17 @@ class Renderer : public NodeVisitor { return std::make_shared(*result); } - void throw_renderer_error(const std::string &message, const AstNode& node) { + void throw_renderer_error(const std::string& message, const AstNode& node) { SourceLocation loc = get_source_location(current_template->content, node.pos); INJA_THROW(RenderError(message, loc)); } + void make_result(const json&& result) { + auto result_ptr = std::make_shared(result); + data_tmp_stack.push_back(result_ptr); + data_eval_stack.push(result_ptr.get()); + } + template std::array get_arguments(const FunctionNode& node) { if (node.arguments.size() < N_start + N) { @@ -201,130 +207,91 @@ class Renderer : public NodeVisitor { } void visit(const FunctionNode& node) { - std::shared_ptr result_ptr; - switch (node.operation) { case Op::Not: { const auto args = get_arguments<1>(node); - result_ptr = std::make_shared(!truthy(args[0])); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(!truthy(args[0])); } break; case Op::And: { - result_ptr = std::make_shared(truthy(get_arguments<1, 0>(node)[0]) && truthy(get_arguments<1, 1>(node)[0])); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(truthy(get_arguments<1, 0>(node)[0]) && truthy(get_arguments<1, 1>(node)[0])); } break; case Op::Or: { - result_ptr = std::make_shared(truthy(get_arguments<1, 0>(node)[0]) || truthy(get_arguments<1, 1>(node)[0])); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(truthy(get_arguments<1, 0>(node)[0]) || truthy(get_arguments<1, 1>(node)[0])); } break; case Op::In: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(std::find(args[1]->begin(), args[1]->end(), *args[0]) != args[1]->end()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::find(args[1]->begin(), args[1]->end(), *args[0]) != args[1]->end()); } break; case Op::Equal: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] == *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] == *args[1]); } break; case Op::NotEqual: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] != *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] != *args[1]); } break; case Op::Greater: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] > *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] > *args[1]); } break; case Op::GreaterEqual: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] >= *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] >= *args[1]); } break; case Op::Less: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] < *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] < *args[1]); } break; case Op::LessEqual: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] <= *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] <= *args[1]); } break; case Op::Add: { const auto args = get_arguments<2>(node); if (args[0]->is_string() && args[1]->is_string()) { - result_ptr = std::make_shared(args[0]->get_ref() + args[1]->get_ref()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get_ref() + args[1]->get_ref()); } else if (args[0]->is_number_integer() && args[1]->is_number_integer()) { - result_ptr = std::make_shared(args[0]->get() + args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() + args[1]->get()); } else { - result_ptr = std::make_shared(args[0]->get() + args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() + args[1]->get()); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Subtract: { const auto args = get_arguments<2>(node); if (args[0]->is_number_integer() && args[1]->is_number_integer()) { - result_ptr = std::make_shared(args[0]->get() - args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() - args[1]->get()); } else { - result_ptr = std::make_shared(args[0]->get() - args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() - args[1]->get()); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Multiplication: { const auto args = get_arguments<2>(node); if (args[0]->is_number_integer() && args[1]->is_number_integer()) { - result_ptr = std::make_shared(args[0]->get() * args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() * args[1]->get()); } else { - result_ptr = std::make_shared(args[0]->get() * args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() * args[1]->get()); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Division: { const auto args = get_arguments<2>(node); if (args[1]->get() == 0) { throw_renderer_error("division by zero", node); } - result_ptr = std::make_shared(args[0]->get() / args[1]->get()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(args[0]->get() / args[1]->get()); } break; case Op::Power: { const auto args = get_arguments<2>(node); if (args[0]->is_number_integer() && args[1]->get() >= 0) { int result = static_cast(std::pow(args[0]->get(), args[1]->get())); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); + make_result(result); } else { double result = std::pow(args[0]->get(), args[1]->get()); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); + make_result(result); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Modulo: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(args[0]->get() % args[1]->get()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(args[0]->get() % args[1]->get()); } break; case Op::AtId: { const auto container = get_arguments<1, 0, false>(node)[0]; @@ -352,41 +319,29 @@ class Renderer : public NodeVisitor { case Op::DivisibleBy: { const auto args = get_arguments<2>(node); const int divisor = args[1]->get(); - result_ptr = std::make_shared((divisor != 0) && (args[0]->get() % divisor == 0)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result((divisor != 0) && (args[0]->get() % divisor == 0)); } break; case Op::Even: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->get() % 2 == 0); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->get() % 2 == 0); } break; case Op::Exists: { auto &&name = get_arguments<1>(node)[0]->get_ref(); - result_ptr = std::make_shared(data_input->contains(json::json_pointer(DataNode::convert_dot_to_ptr(name)))); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(data_input->contains(json::json_pointer(DataNode::convert_dot_to_ptr(name)))); } break; case Op::ExistsInObject: { const auto args = get_arguments<2>(node); auto &&name = args[1]->get_ref(); - result_ptr = std::make_shared(args[0]->find(name) != args[0]->end()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(args[0]->find(name) != args[0]->end()); } break; case Op::First: { const auto result = &get_arguments<1>(node)[0]->front(); data_eval_stack.push(result); } break; case Op::Float: { - result_ptr = std::make_shared(std::stod(get_arguments<1>(node)[0]->get_ref())); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::stod(get_arguments<1>(node)[0]->get_ref())); } break; case Op::Int: { - result_ptr = std::make_shared(std::stoi(get_arguments<1>(node)[0]->get_ref())); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::stoi(get_arguments<1>(node)[0]->get_ref())); } break; case Op::Last: { const auto result = &get_arguments<1>(node)[0]->back(); @@ -395,19 +350,15 @@ class Renderer : public NodeVisitor { case Op::Length: { const auto val = get_arguments<1>(node)[0]; if (val->is_string()) { - result_ptr = std::make_shared(val->get_ref().length()); + make_result(val->get_ref().length()); } else { - result_ptr = std::make_shared(val->size()); + make_result(val->size()); } - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); } break; case Op::Lower: { std::string result = get_arguments<1>(node)[0]->get(); std::transform(result.begin(), result.end(), result.begin(), ::tolower); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::move(result)); } break; case Op::Max: { const auto args = get_arguments<1>(node); @@ -420,31 +371,25 @@ class Renderer : public NodeVisitor { data_eval_stack.push(&(*result)); } break; case Op::Odd: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->get() % 2 != 0); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->get() % 2 != 0); } break; case Op::Range: { std::vector result(get_arguments<1>(node)[0]->get()); std::iota(result.begin(), result.end(), 0); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::move(result)); } break; case Op::Round: { const auto args = get_arguments<2>(node); const int precision = args[1]->get(); const double result = std::round(args[0]->get() * std::pow(10.0, precision)) / std::pow(10.0, precision); - if(0==precision){ - result_ptr = std::make_shared(int(result)); - }else{ - result_ptr = std::make_shared(std::move(result)); + if (precision == 0) { + make_result(int(result)); + } else { + make_result(result); } - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); } break; case Op::Sort: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->get>()); + auto result_ptr = std::make_shared(get_arguments<1>(node)[0]->get>()); std::sort(result_ptr->begin(), result_ptr->end()); data_tmp_stack.push_back(result_ptr); data_eval_stack.push(result_ptr.get()); @@ -452,50 +397,32 @@ class Renderer : public NodeVisitor { case Op::Upper: { std::string result = get_arguments<1>(node)[0]->get(); std::transform(result.begin(), result.end(), result.begin(), ::toupper); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::move(result)); } break; case Op::IsBoolean: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_boolean()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_boolean()); } break; case Op::IsNumber: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_number()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_number()); } break; case Op::IsInteger: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_number_integer()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_number_integer()); } break; case Op::IsFloat: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_number_float()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_number_float()); } break; case Op::IsObject: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_object()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_object()); } break; case Op::IsArray: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_array()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_array()); } break; case Op::IsString: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_string()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_string()); } break; case Op::Callback: { auto args = get_argument_vector(node); - result_ptr = std::make_shared(node.callback(args)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(node.callback(args)); } break; case Op::Super: { const auto args = get_argument_vector(node); @@ -512,8 +439,8 @@ class Renderer : public NodeVisitor { } const auto current_block_statement = block_statement_stack.back(); - const Template *new_template = template_stack.at(level); - const Template *old_template = current_template; + const Template* new_template = template_stack.at(level); + const Template* old_template = current_template; const auto block_it = new_template->block_storage.find(current_block_statement->name); if (block_it != new_template->block_storage.end()) { current_template = new_template; @@ -524,9 +451,7 @@ class Renderer : public NodeVisitor { } else { throw_renderer_error("could not find block with name '" + current_block_statement->name + "'", node); } - result_ptr = std::make_shared(nullptr); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(nullptr); } break; case Op::Join: { const auto args = get_arguments<2>(node); @@ -542,9 +467,7 @@ class Renderer : public NodeVisitor { } sep = separator; } - result_ptr = std::make_shared(os.str()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(os.str()); } break; case Op::ParenLeft: case Op::ParenRight: @@ -691,10 +614,10 @@ class Renderer : public NodeVisitor { } public: - Renderer(const RenderConfig& config, const TemplateStorage &template_storage, const FunctionStorage &function_storage) + Renderer(const RenderConfig& config, const TemplateStorage& template_storage, const FunctionStorage& function_storage) : config(config), template_storage(template_storage), function_storage(function_storage) { } - void render_to(std::ostream &os, const Template &tmpl, const json &data, json *loop_data = nullptr) { + void render_to(std::ostream& os, const Template& tmpl, const json& data, json* loop_data = nullptr) { output_stream = &os; current_template = &tmpl; data_input = &data; diff --git a/single_include/inja/inja.hpp b/single_include/inja/inja.hpp index 775a719..d8fb413 100644 --- a/single_include/inja/inja.hpp +++ b/single_include/inja/inja.hpp @@ -904,7 +904,6 @@ struct RenderConfig { #include #include #include -#include #include // #include "config.hpp" @@ -2119,16 +2118,16 @@ class Renderer : public NodeVisitor { using Op = FunctionStorage::Operation; const RenderConfig config; - const TemplateStorage &template_storage; - const FunctionStorage &function_storage; + const TemplateStorage& template_storage; + const FunctionStorage& function_storage; - const Template *current_template; + const Template* current_template; size_t current_level {0}; std::vector template_stack; std::vector block_statement_stack; - const json *data_input; - std::ostream *output_stream; + const json* data_input; + std::ostream* output_stream; json additional_data; json* current_loop_data = &additional_data["loop"]; @@ -2139,7 +2138,7 @@ class Renderer : public NodeVisitor { bool break_rendering {false}; - bool truthy(const json* data) const { + static bool truthy(const json* data) { if (data->is_boolean()) { return data->get(); } else if (data->is_number()) { @@ -2190,11 +2189,17 @@ class Renderer : public NodeVisitor { return std::make_shared(*result); } - void throw_renderer_error(const std::string &message, const AstNode& node) { + void throw_renderer_error(const std::string& message, const AstNode& node) { SourceLocation loc = get_source_location(current_template->content, node.pos); INJA_THROW(RenderError(message, loc)); } + void make_result(const json&& result) { + auto result_ptr = std::make_shared(result); + data_tmp_stack.push_back(result_ptr); + data_eval_stack.push(result_ptr.get()); + } + template std::array get_arguments(const FunctionNode& node) { if (node.arguments.size() < N_start + N) { @@ -2298,130 +2303,91 @@ class Renderer : public NodeVisitor { } void visit(const FunctionNode& node) { - std::shared_ptr result_ptr; - switch (node.operation) { case Op::Not: { const auto args = get_arguments<1>(node); - result_ptr = std::make_shared(!truthy(args[0])); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(!truthy(args[0])); } break; case Op::And: { - result_ptr = std::make_shared(truthy(get_arguments<1, 0>(node)[0]) && truthy(get_arguments<1, 1>(node)[0])); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(truthy(get_arguments<1, 0>(node)[0]) && truthy(get_arguments<1, 1>(node)[0])); } break; case Op::Or: { - result_ptr = std::make_shared(truthy(get_arguments<1, 0>(node)[0]) || truthy(get_arguments<1, 1>(node)[0])); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(truthy(get_arguments<1, 0>(node)[0]) || truthy(get_arguments<1, 1>(node)[0])); } break; case Op::In: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(std::find(args[1]->begin(), args[1]->end(), *args[0]) != args[1]->end()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::find(args[1]->begin(), args[1]->end(), *args[0]) != args[1]->end()); } break; case Op::Equal: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] == *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] == *args[1]); } break; case Op::NotEqual: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] != *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] != *args[1]); } break; case Op::Greater: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] > *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] > *args[1]); } break; case Op::GreaterEqual: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] >= *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] >= *args[1]); } break; case Op::Less: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] < *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] < *args[1]); } break; case Op::LessEqual: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(*args[0] <= *args[1]); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(*args[0] <= *args[1]); } break; case Op::Add: { const auto args = get_arguments<2>(node); if (args[0]->is_string() && args[1]->is_string()) { - result_ptr = std::make_shared(args[0]->get_ref() + args[1]->get_ref()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get_ref() + args[1]->get_ref()); } else if (args[0]->is_number_integer() && args[1]->is_number_integer()) { - result_ptr = std::make_shared(args[0]->get() + args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() + args[1]->get()); } else { - result_ptr = std::make_shared(args[0]->get() + args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() + args[1]->get()); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Subtract: { const auto args = get_arguments<2>(node); if (args[0]->is_number_integer() && args[1]->is_number_integer()) { - result_ptr = std::make_shared(args[0]->get() - args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() - args[1]->get()); } else { - result_ptr = std::make_shared(args[0]->get() - args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() - args[1]->get()); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Multiplication: { const auto args = get_arguments<2>(node); if (args[0]->is_number_integer() && args[1]->is_number_integer()) { - result_ptr = std::make_shared(args[0]->get() * args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() * args[1]->get()); } else { - result_ptr = std::make_shared(args[0]->get() * args[1]->get()); - data_tmp_stack.push_back(result_ptr); + make_result(args[0]->get() * args[1]->get()); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Division: { const auto args = get_arguments<2>(node); if (args[1]->get() == 0) { throw_renderer_error("division by zero", node); } - result_ptr = std::make_shared(args[0]->get() / args[1]->get()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(args[0]->get() / args[1]->get()); } break; case Op::Power: { const auto args = get_arguments<2>(node); if (args[0]->is_number_integer() && args[1]->get() >= 0) { int result = static_cast(std::pow(args[0]->get(), args[1]->get())); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); + make_result(result); } else { double result = std::pow(args[0]->get(), args[1]->get()); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); + make_result(result); } - data_eval_stack.push(result_ptr.get()); } break; case Op::Modulo: { const auto args = get_arguments<2>(node); - result_ptr = std::make_shared(args[0]->get() % args[1]->get()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(args[0]->get() % args[1]->get()); } break; case Op::AtId: { const auto container = get_arguments<1, 0, false>(node)[0]; @@ -2449,41 +2415,29 @@ class Renderer : public NodeVisitor { case Op::DivisibleBy: { const auto args = get_arguments<2>(node); const int divisor = args[1]->get(); - result_ptr = std::make_shared((divisor != 0) && (args[0]->get() % divisor == 0)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result((divisor != 0) && (args[0]->get() % divisor == 0)); } break; case Op::Even: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->get() % 2 == 0); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->get() % 2 == 0); } break; case Op::Exists: { auto &&name = get_arguments<1>(node)[0]->get_ref(); - result_ptr = std::make_shared(data_input->contains(json::json_pointer(DataNode::convert_dot_to_ptr(name)))); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(data_input->contains(json::json_pointer(DataNode::convert_dot_to_ptr(name)))); } break; case Op::ExistsInObject: { const auto args = get_arguments<2>(node); auto &&name = args[1]->get_ref(); - result_ptr = std::make_shared(args[0]->find(name) != args[0]->end()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(args[0]->find(name) != args[0]->end()); } break; case Op::First: { const auto result = &get_arguments<1>(node)[0]->front(); data_eval_stack.push(result); } break; case Op::Float: { - result_ptr = std::make_shared(std::stod(get_arguments<1>(node)[0]->get_ref())); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::stod(get_arguments<1>(node)[0]->get_ref())); } break; case Op::Int: { - result_ptr = std::make_shared(std::stoi(get_arguments<1>(node)[0]->get_ref())); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::stoi(get_arguments<1>(node)[0]->get_ref())); } break; case Op::Last: { const auto result = &get_arguments<1>(node)[0]->back(); @@ -2492,19 +2446,15 @@ class Renderer : public NodeVisitor { case Op::Length: { const auto val = get_arguments<1>(node)[0]; if (val->is_string()) { - result_ptr = std::make_shared(val->get_ref().length()); + make_result(val->get_ref().length()); } else { - result_ptr = std::make_shared(val->size()); + make_result(val->size()); } - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); } break; case Op::Lower: { std::string result = get_arguments<1>(node)[0]->get(); std::transform(result.begin(), result.end(), result.begin(), ::tolower); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::move(result)); } break; case Op::Max: { const auto args = get_arguments<1>(node); @@ -2517,31 +2467,25 @@ class Renderer : public NodeVisitor { data_eval_stack.push(&(*result)); } break; case Op::Odd: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->get() % 2 != 0); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->get() % 2 != 0); } break; case Op::Range: { std::vector result(get_arguments<1>(node)[0]->get()); std::iota(result.begin(), result.end(), 0); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::move(result)); } break; case Op::Round: { const auto args = get_arguments<2>(node); const int precision = args[1]->get(); const double result = std::round(args[0]->get() * std::pow(10.0, precision)) / std::pow(10.0, precision); - if(0==precision){ - result_ptr = std::make_shared(int(result)); - }else{ - result_ptr = std::make_shared(std::move(result)); + if (precision == 0) { + make_result(int(result)); + } else { + make_result(result); } - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); } break; case Op::Sort: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->get>()); + auto result_ptr = std::make_shared(get_arguments<1>(node)[0]->get>()); std::sort(result_ptr->begin(), result_ptr->end()); data_tmp_stack.push_back(result_ptr); data_eval_stack.push(result_ptr.get()); @@ -2549,50 +2493,32 @@ class Renderer : public NodeVisitor { case Op::Upper: { std::string result = get_arguments<1>(node)[0]->get(); std::transform(result.begin(), result.end(), result.begin(), ::toupper); - result_ptr = std::make_shared(std::move(result)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(std::move(result)); } break; case Op::IsBoolean: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_boolean()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_boolean()); } break; case Op::IsNumber: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_number()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_number()); } break; case Op::IsInteger: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_number_integer()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_number_integer()); } break; case Op::IsFloat: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_number_float()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_number_float()); } break; case Op::IsObject: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_object()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_object()); } break; case Op::IsArray: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_array()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_array()); } break; case Op::IsString: { - result_ptr = std::make_shared(get_arguments<1>(node)[0]->is_string()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(get_arguments<1>(node)[0]->is_string()); } break; case Op::Callback: { auto args = get_argument_vector(node); - result_ptr = std::make_shared(node.callback(args)); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(node.callback(args)); } break; case Op::Super: { const auto args = get_argument_vector(node); @@ -2609,8 +2535,8 @@ class Renderer : public NodeVisitor { } const auto current_block_statement = block_statement_stack.back(); - const Template *new_template = template_stack.at(level); - const Template *old_template = current_template; + const Template* new_template = template_stack.at(level); + const Template* old_template = current_template; const auto block_it = new_template->block_storage.find(current_block_statement->name); if (block_it != new_template->block_storage.end()) { current_template = new_template; @@ -2621,9 +2547,7 @@ class Renderer : public NodeVisitor { } else { throw_renderer_error("could not find block with name '" + current_block_statement->name + "'", node); } - result_ptr = std::make_shared(nullptr); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(nullptr); } break; case Op::Join: { const auto args = get_arguments<2>(node); @@ -2639,9 +2563,7 @@ class Renderer : public NodeVisitor { } sep = separator; } - result_ptr = std::make_shared(os.str()); - data_tmp_stack.push_back(result_ptr); - data_eval_stack.push(result_ptr.get()); + make_result(os.str()); } break; case Op::ParenLeft: case Op::ParenRight: @@ -2788,10 +2710,10 @@ class Renderer : public NodeVisitor { } public: - Renderer(const RenderConfig& config, const TemplateStorage &template_storage, const FunctionStorage &function_storage) + Renderer(const RenderConfig& config, const TemplateStorage& template_storage, const FunctionStorage& function_storage) : config(config), template_storage(template_storage), function_storage(function_storage) { } - void render_to(std::ostream &os, const Template &tmpl, const json &data, json *loop_data = nullptr) { + void render_to(std::ostream& os, const Template& tmpl, const json& data, json* loop_data = nullptr) { output_stream = &os; current_template = &tmpl; data_input = &data;