optimizations

This commit is contained in:
Daniel Sipka 2015-04-15 16:13:23 +02:00
parent bb21e64a51
commit 48fbaeb3c9
5 changed files with 49 additions and 37 deletions

View file

@ -96,7 +96,8 @@ void render_context::tokenize(const std::string& t, std::vector<token>& toks) {
if (*it == delim_end[del_pos] && ++del_pos == delim_end.size()) { if (*it == delim_end[del_pos] && ++del_pos == delim_end.size()) {
pstate = parse_state::start; pstate = parse_state::start;
toks.push_back({false, false, ws_only, {tok_start, tok_end}}); toks.push_back({false, false, ws_only, {tok_start, tok_end}});
toks.push_back({true, false, false, {tok_end, it + 1}}); toks.push_back({true, false, false,
{tok_end +delim_start.size(), it - delim_end.size() +1}});
ws_only = true; ws_only = true;
tok_start = it + 1; tok_start = it + 1;
} else { } else {

View file

@ -14,7 +14,7 @@ std::string state::in_section::render(render_context& ctx, const token& token) {
switch(token.token_type()) { switch(token.token_type()) {
case token::type::section_close: case token::type::section_close:
if(token.content() == section_name && skipped_openings == 0) { if(token.content() == section_name && skipped_openings == 0) {
auto section_node = ctx.get_node(section_name); auto& section_node = ctx.get_node(section_name);
std::string out; std::string out;
if (!boost::apply_visitor(visitor::is_node_empty(), section_node)) if (!boost::apply_visitor(visitor::is_node_empty(), section_node))
out = boost::apply_visitor( out = boost::apply_visitor(

View file

@ -26,7 +26,7 @@ std::string state::outside_section::render(
} }
case token::type::comment: break; case token::type::comment: break;
case token::type::text: case token::type::text:
return token.raw(); return token.content();
case token::type::partial: case token::type::partial:
return ctx.render_partial(token.content()); return ctx.render_partial(token.content());
case token::type::section_close: break; case token::type::section_close: break;

View file

@ -1,36 +1,48 @@
#include "token.hpp" #include "token.hpp"
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/predicate.hpp>
using namespace mstch; using namespace mstch;
std::tuple<int,int,token::type> token::token_info(const std::string& inside) { token::type token::token_info(char c) {
switch (inside.at(0)) { switch (c) {
case '>': return std::make_tuple(1, 0, type::partial); case '>': return type::partial;
case '^': return std::make_tuple(1, 0, type::inverted_section_open); case '^': return type::inverted_section_open;
case '/': return std::make_tuple(1, 0, type::section_close); case '/': return type::section_close;
case '&': return std::make_tuple(1, 0, type::unescaped_variable); case '&': return type::unescaped_variable;
case '#': return std::make_tuple(1, 0, type::section_open); case '#': return type::section_open;
case '!': return std::make_tuple(1, 0, type::comment); case '!': return type::comment;
case '{': default: return type::variable;
if (inside.at(inside.size() - 1) == '}')
return std::make_tuple(1, 1, type::unescaped_variable);
default: return std::make_tuple(0, 0, type::variable);
} }
} }
token::token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val): token::token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val):
raw_val(raw_val), eol(eol), ws_only(ws_only), marked(false) eol(eol), ws_only(ws_only), marked(false)
{ {
if(is_tag) { if(is_tag) {
std::string inside{raw_val.substr(2, raw_val.size() - 4)}; auto content_begin = raw_val.begin(), content_end = raw_val.end();
boost::trim(inside); parse_state state = parse_state::prews;
if (inside.size() > 0) { if(*content_begin == '{' && *(content_end - 1) == '}') {
int lpad, rpad; state = parse_state::postws;
std::tie(lpad, rpad, type_val) = token_info(inside); type_val = type::unescaped_variable;
content_val = inside.substr(lpad, inside.size() - lpad - rpad); ++content_begin;
boost::trim(content_val); --content_end;
} }
for(auto it = content_begin; it != content_end;) {
if(state == parse_state::prews && *it != ' ') {
state = parse_state::postws;
if((type_val = token_info(*it++)) == type::variable) {
state = parse_state::content;
content_begin = it -1;
}
} else if(state == parse_state::postws && *it != ' ') {
content_begin = it++;
state = parse_state::content;
} else if(state == parse_state::content && *it == ' ') {
content_end = it;
} else {
++it;
}
}
content_val = {content_begin, content_end};
} else { } else {
type_val = type::text; type_val = type::text;
content_val = raw_val; content_val = raw_val;

View file

@ -13,19 +13,18 @@ namespace mstch {
token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val); token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val);
type token_type() const { return type_val; }; type token_type() const { return type_val; };
const std::string& content() const { return content_val; }; const std::string& content() const { return content_val; };
const std::string& raw() const { return raw_val; };
bool is_eol() const { return eol; } bool is_eol() const { return eol; }
bool is_ws_only() const { return ws_only; } bool is_ws_only() const { return ws_only; }
bool is_marked() const { return marked; } bool is_marked() const { return marked; }
void mark() { marked = true; }; void mark() { marked = true; };
private: private:
enum class parse_state { prews, postws, content };
type type_val; type type_val;
std::string content_val; std::string content_val;
std::string raw_val;
bool eol; bool eol;
bool ws_only; bool ws_only;
bool marked; bool marked;
std::tuple<int,int,type> token_info(const std::string& inside); type token_info(char c);
}; };
} }