mirror of
https://github.com/pantor/inja.git
synced 2026-03-20 07:55:58 +00:00
further performance improvements
This commit is contained in:
@@ -38,7 +38,7 @@ PROJECT_NAME = "Inja"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 3.0.0
|
||||
PROJECT_NUMBER = 3.1.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
class JsonNode : public ExpressionNode {
|
||||
public:
|
||||
std::string name;
|
||||
std::string ptr {""};
|
||||
json::json_pointer ptr;
|
||||
|
||||
static std::string convert_dot_to_json_ptr(nonstd::string_view ptr_name) {
|
||||
std::string result;
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
}
|
||||
|
||||
explicit JsonNode(nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name(ptr_name) {
|
||||
ptr = convert_dot_to_json_ptr(ptr_name);
|
||||
ptr = json::json_pointer(convert_dot_to_json_ptr(ptr_name));
|
||||
}
|
||||
|
||||
void accept(NodeVisitor& v) const {
|
||||
@@ -263,9 +263,9 @@ public:
|
||||
|
||||
class ForArrayStatementNode : public ForStatementNode {
|
||||
public:
|
||||
nonstd::string_view value;
|
||||
std::string value;
|
||||
|
||||
explicit ForArrayStatementNode(nonstd::string_view value, size_t pos) : ForStatementNode(pos), value(value) { }
|
||||
explicit ForArrayStatementNode(const std::string& value, size_t pos) : ForStatementNode(pos), value(value) { }
|
||||
|
||||
void accept(NodeVisitor& v) const {
|
||||
v.visit(*this);
|
||||
@@ -274,10 +274,10 @@ public:
|
||||
|
||||
class ForObjectStatementNode : public ForStatementNode {
|
||||
public:
|
||||
nonstd::string_view key;
|
||||
nonstd::string_view value;
|
||||
std::string key;
|
||||
std::string value;
|
||||
|
||||
explicit ForObjectStatementNode(nonstd::string_view key, nonstd::string_view value, size_t pos) : ForStatementNode(pos), key(key), value(value) { }
|
||||
explicit ForObjectStatementNode(const std::string& key, const std::string& value, size_t pos) : ForStatementNode(pos), key(key), value(value) { }
|
||||
|
||||
void accept(NodeVisitor& v) const {
|
||||
v.visit(*this);
|
||||
|
||||
@@ -390,11 +390,11 @@ class Parser {
|
||||
value_token = tok;
|
||||
get_next_token();
|
||||
|
||||
for_statement_node = std::make_shared<ForObjectStatementNode>(key_token.text, value_token.text, tok.text.data() - tmpl.content.c_str());
|
||||
for_statement_node = std::make_shared<ForObjectStatementNode>(static_cast<std::string>(key_token.text), static_cast<std::string>(value_token.text), tok.text.data() - tmpl.content.c_str());
|
||||
|
||||
// Array type
|
||||
} else {
|
||||
for_statement_node = std::make_shared<ForArrayStatementNode>(value_token.text, tok.text.data() - tmpl.content.c_str());
|
||||
for_statement_node = std::make_shared<ForArrayStatementNode>(static_cast<std::string>(value_token.text), tok.text.data() - tmpl.content.c_str());
|
||||
}
|
||||
|
||||
current_block->nodes.emplace_back(for_statement_node);
|
||||
|
||||
@@ -56,7 +56,7 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
void print_json(const json* value) {
|
||||
void print_json(const std::shared_ptr<json> value) {
|
||||
if (value->is_string()) {
|
||||
*output_stream << value->get_ref<const std::string &>();
|
||||
} else {
|
||||
@@ -71,9 +71,8 @@ class Renderer : public NodeVisitor {
|
||||
|
||||
if (json_eval_stack.empty()) {
|
||||
throw_renderer_error("empty expression", expression_list);
|
||||
}
|
||||
|
||||
if (json_eval_stack.size() != 1) {
|
||||
|
||||
} else if (json_eval_stack.size() != 1) {
|
||||
throw_renderer_error("malformed expression", expression_list);
|
||||
}
|
||||
|
||||
@@ -157,17 +156,13 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
void visit(const JsonNode& node) {
|
||||
auto ptr = json::json_pointer(node.ptr);
|
||||
|
||||
try {
|
||||
// First try to evaluate as a loop variable
|
||||
if (json_additional_data.contains(ptr)) {
|
||||
json_eval_stack.push(&json_additional_data.at(ptr));
|
||||
} else {
|
||||
json_eval_stack.push(&json_input->at(ptr));
|
||||
}
|
||||
|
||||
} catch (std::exception &) {
|
||||
if (json_additional_data.contains(node.ptr)) {
|
||||
json_eval_stack.push(&json_additional_data[node.ptr]);
|
||||
|
||||
} else if (json_input->contains(node.ptr)) {
|
||||
json_eval_stack.push(&(*json_input)[node.ptr]);
|
||||
|
||||
} else {
|
||||
// Try to evaluate as a no-argument callback
|
||||
auto function_data = function_storage.find_function(node.name, 0);
|
||||
if (function_data.operation == FunctionStorage::Operation::Callback) {
|
||||
@@ -482,7 +477,7 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
void visit(const ExpressionListNode& node) {
|
||||
print_json(eval_expression_list(node).get());
|
||||
print_json(eval_expression_list(node));
|
||||
}
|
||||
|
||||
void visit(const StatementNode&) { }
|
||||
@@ -501,13 +496,19 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
(*current_loop_data)["is_first"] = true;
|
||||
(*current_loop_data)["is_last"] = (result->size() <= 1);
|
||||
for (auto it = result->begin(); it != result->end(); ++it) {
|
||||
json_additional_data[static_cast<std::string>(node.value)] = *it;
|
||||
|
||||
(*current_loop_data)["index"] = index;
|
||||
(*current_loop_data)["index1"] = index + 1;
|
||||
(*current_loop_data)["is_first"] = (index == 0);
|
||||
(*current_loop_data)["is_last"] = (index == result->size() - 1);
|
||||
if (index == 1) {
|
||||
(*current_loop_data)["is_first"] = false;
|
||||
}
|
||||
if (index == result->size() - 1) {
|
||||
(*current_loop_data)["is_last"] = true;
|
||||
}
|
||||
|
||||
node.body.accept(*this);
|
||||
++index;
|
||||
@@ -533,14 +534,20 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
(*current_loop_data)["is_first"] = true;
|
||||
(*current_loop_data)["is_last"] = (result->size() <= 1);
|
||||
for (auto it = result->begin(); it != result->end(); ++it) {
|
||||
json_additional_data[static_cast<std::string>(node.key)] = it.key();
|
||||
json_additional_data[static_cast<std::string>(node.value)] = it.value();
|
||||
|
||||
(*current_loop_data)["index"] = index;
|
||||
(*current_loop_data)["index1"] = index + 1;
|
||||
(*current_loop_data)["is_first"] = (index == 0);
|
||||
(*current_loop_data)["is_last"] = (index == result->size() - 1);
|
||||
if (index == 1) {
|
||||
(*current_loop_data)["is_first"] = false;
|
||||
}
|
||||
if (index == result->size() - 1) {
|
||||
(*current_loop_data)["is_last"] = true;
|
||||
}
|
||||
|
||||
node.body.accept(*this);
|
||||
++index;
|
||||
|
||||
@@ -2393,7 +2393,7 @@ public:
|
||||
class JsonNode : public ExpressionNode {
|
||||
public:
|
||||
std::string name;
|
||||
std::string ptr {""};
|
||||
json::json_pointer ptr;
|
||||
|
||||
static std::string convert_dot_to_json_ptr(nonstd::string_view ptr_name) {
|
||||
std::string result;
|
||||
@@ -2407,7 +2407,7 @@ public:
|
||||
}
|
||||
|
||||
explicit JsonNode(nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name(ptr_name) {
|
||||
ptr = convert_dot_to_json_ptr(ptr_name);
|
||||
ptr = json::json_pointer(convert_dot_to_json_ptr(ptr_name));
|
||||
}
|
||||
|
||||
void accept(NodeVisitor& v) const {
|
||||
@@ -2548,9 +2548,9 @@ public:
|
||||
|
||||
class ForArrayStatementNode : public ForStatementNode {
|
||||
public:
|
||||
nonstd::string_view value;
|
||||
std::string value;
|
||||
|
||||
explicit ForArrayStatementNode(nonstd::string_view value, size_t pos) : ForStatementNode(pos), value(value) { }
|
||||
explicit ForArrayStatementNode(const std::string& value, size_t pos) : ForStatementNode(pos), value(value) { }
|
||||
|
||||
void accept(NodeVisitor& v) const {
|
||||
v.visit(*this);
|
||||
@@ -2559,10 +2559,10 @@ public:
|
||||
|
||||
class ForObjectStatementNode : public ForStatementNode {
|
||||
public:
|
||||
nonstd::string_view key;
|
||||
nonstd::string_view value;
|
||||
std::string key;
|
||||
std::string value;
|
||||
|
||||
explicit ForObjectStatementNode(nonstd::string_view key, nonstd::string_view value, size_t pos) : ForStatementNode(pos), key(key), value(value) { }
|
||||
explicit ForObjectStatementNode(const std::string& key, const std::string& value, size_t pos) : ForStatementNode(pos), key(key), value(value) { }
|
||||
|
||||
void accept(NodeVisitor& v) const {
|
||||
v.visit(*this);
|
||||
@@ -3102,11 +3102,11 @@ class Parser {
|
||||
value_token = tok;
|
||||
get_next_token();
|
||||
|
||||
for_statement_node = std::make_shared<ForObjectStatementNode>(key_token.text, value_token.text, tok.text.data() - tmpl.content.c_str());
|
||||
for_statement_node = std::make_shared<ForObjectStatementNode>(static_cast<std::string>(key_token.text), static_cast<std::string>(value_token.text), tok.text.data() - tmpl.content.c_str());
|
||||
|
||||
// Array type
|
||||
} else {
|
||||
for_statement_node = std::make_shared<ForArrayStatementNode>(value_token.text, tok.text.data() - tmpl.content.c_str());
|
||||
for_statement_node = std::make_shared<ForArrayStatementNode>(static_cast<std::string>(value_token.text), tok.text.data() - tmpl.content.c_str());
|
||||
}
|
||||
|
||||
current_block->nodes.emplace_back(for_statement_node);
|
||||
@@ -3354,7 +3354,7 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
void print_json(const json* value) {
|
||||
void print_json(const std::shared_ptr<json> value) {
|
||||
if (value->is_string()) {
|
||||
*output_stream << value->get_ref<const std::string &>();
|
||||
} else {
|
||||
@@ -3369,9 +3369,8 @@ class Renderer : public NodeVisitor {
|
||||
|
||||
if (json_eval_stack.empty()) {
|
||||
throw_renderer_error("empty expression", expression_list);
|
||||
}
|
||||
|
||||
if (json_eval_stack.size() != 1) {
|
||||
|
||||
} else if (json_eval_stack.size() != 1) {
|
||||
throw_renderer_error("malformed expression", expression_list);
|
||||
}
|
||||
|
||||
@@ -3455,17 +3454,13 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
void visit(const JsonNode& node) {
|
||||
auto ptr = json::json_pointer(node.ptr);
|
||||
|
||||
try {
|
||||
// First try to evaluate as a loop variable
|
||||
if (json_additional_data.contains(ptr)) {
|
||||
json_eval_stack.push(&json_additional_data.at(ptr));
|
||||
} else {
|
||||
json_eval_stack.push(&json_input->at(ptr));
|
||||
}
|
||||
|
||||
} catch (std::exception &) {
|
||||
if (json_additional_data.contains(node.ptr)) {
|
||||
json_eval_stack.push(&json_additional_data[node.ptr]);
|
||||
|
||||
} else if (json_input->contains(node.ptr)) {
|
||||
json_eval_stack.push(&(*json_input)[node.ptr]);
|
||||
|
||||
} else {
|
||||
// Try to evaluate as a no-argument callback
|
||||
auto function_data = function_storage.find_function(node.name, 0);
|
||||
if (function_data.operation == FunctionStorage::Operation::Callback) {
|
||||
@@ -3780,7 +3775,7 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
void visit(const ExpressionListNode& node) {
|
||||
print_json(eval_expression_list(node).get());
|
||||
print_json(eval_expression_list(node));
|
||||
}
|
||||
|
||||
void visit(const StatementNode&) { }
|
||||
@@ -3799,13 +3794,19 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
(*current_loop_data)["is_first"] = true;
|
||||
(*current_loop_data)["is_last"] = (result->size() <= 1);
|
||||
for (auto it = result->begin(); it != result->end(); ++it) {
|
||||
json_additional_data[static_cast<std::string>(node.value)] = *it;
|
||||
|
||||
(*current_loop_data)["index"] = index;
|
||||
(*current_loop_data)["index1"] = index + 1;
|
||||
(*current_loop_data)["is_first"] = (index == 0);
|
||||
(*current_loop_data)["is_last"] = (index == result->size() - 1);
|
||||
if (index == 1) {
|
||||
(*current_loop_data)["is_first"] = false;
|
||||
}
|
||||
if (index == result->size() - 1) {
|
||||
(*current_loop_data)["is_last"] = true;
|
||||
}
|
||||
|
||||
node.body.accept(*this);
|
||||
++index;
|
||||
@@ -3831,14 +3832,20 @@ class Renderer : public NodeVisitor {
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
(*current_loop_data)["is_first"] = true;
|
||||
(*current_loop_data)["is_last"] = (result->size() <= 1);
|
||||
for (auto it = result->begin(); it != result->end(); ++it) {
|
||||
json_additional_data[static_cast<std::string>(node.key)] = it.key();
|
||||
json_additional_data[static_cast<std::string>(node.value)] = it.value();
|
||||
|
||||
(*current_loop_data)["index"] = index;
|
||||
(*current_loop_data)["index1"] = index + 1;
|
||||
(*current_loop_data)["is_first"] = (index == 0);
|
||||
(*current_loop_data)["is_last"] = (index == result->size() - 1);
|
||||
if (index == 1) {
|
||||
(*current_loop_data)["is_first"] = false;
|
||||
}
|
||||
if (index == result->size() - 1) {
|
||||
(*current_loop_data)["is_last"] = true;
|
||||
}
|
||||
|
||||
node.body.accept(*this);
|
||||
++index;
|
||||
|
||||
Reference in New Issue
Block a user