Commit a81eb0e4 authored by s_kleplj's avatar s_kleplj
Browse files

optimized to 0.60

parent da28db02
......@@ -4,15 +4,31 @@
#include "macrosol.hpp"
namespace macrosol {
bool macroprocessor_impl::process(
const std::string& s,
std::string& output
) {
const bool is_def = parse(s);
if (is_def) {
define();
return false;
} else {
expand(output);
return true;
}
}
bool macroprocessor_impl::parse(
const std::string& s
) {
parsed.clear();
bool is_def = false;
for (
auto [i, j] = std::tuple{s.cbegin(), s.cend()};;
auto&& [i, j] = std::tuple{s.cbegin(), s.cend()};;
++i
) {
if (j != s.cend()) {
......@@ -38,75 +54,55 @@ bool macroprocessor_impl::process(
}
}
if (is_def) {
auto&& [it, inserted] = words_.try_emplace(
parsed[0],
parsed[0]);
if (inserted) {
const_cast<std::string_view&>(it->first) = it->second.name_;
} else {
it->second.value_.clear();
it->second.length = 0;
}
if (parsed.size() != 1) {
std::vector<word*>* vector = &(it->second.value_);
vector->reserve(parsed.size() - 1);
for (auto i = parsed.cbegin() + 1; i != parsed.cend(); ++i) {
auto&& [it, inserted] = words_.try_emplace(
*i,
*i,
true);
if (inserted) {
const_cast<std::string_view&>(it->first) = it->second.name_;
}
return is_def;
}
vector->emplace_back(&it->second);
}
}
void macroprocessor_impl::define() {
auto&& [it, inserted] = words_.try_emplace(
parsed[0],
parsed[0]);
return false;
if (inserted) {
const_cast<std::string_view&>(it->first) = it->second.name_;
} else {
std::size_t length = 0;
found.clear();
found.reserve(parsed.size());
for (auto&& p : parsed) {
auto it = words_.find(p);
if (it != words_.end()) {
std::size_t w_length = it->second.update_length() + 1;
found.emplace_back(&it->second);
it->second.value_.clear();
it->second.expanded_ = true;
}
if (w_length > 0) {
length += w_length + 1;
}
} else {
found.emplace_back(nullptr);
length += p.size() + 1;
}
}
if (parsed.size() != 1) {
auto vector = &(it->second.value_);
vector->reserve(parsed.size() - 1);
output.reserve(length);
for (auto i = parsed.cbegin() + 1; i != parsed.cend(); ++i) {
auto [it, inserted] = words_.try_emplace(
*i,
*i,
true);
for (std::size_t i = 0; i < parsed.size(); ++i) {
if (found[i] != nullptr) {
found[i]->append_to(output);
} else {
output += parsed[i];
output += ' ';
if (inserted) {
const_cast<std::string_view&>(it->first) = it->second.name_;
}
vector->emplace_back(&it->second);
}
}
}
if (output.size() > 0) {
output.pop_back();
void macroprocessor_impl::expand(
std::string& output
) const {
for (std::size_t i = 0; i < parsed.size(); ++i) {
auto it = words_.find(parsed[i]);
if (it != words_.end()) {
it->second.append_to(output);
} else {
output += parsed[i];
output += ' ';
}
}
return true;
if (output.size() > 0) {
output.pop_back();
}
}
......
......@@ -37,8 +37,7 @@ class view_hasher {
std::size_t operator()(const std::string_view& a) const {
std::size_t ret = 0;
for (std::size_t i = 0; i < strength; ++i) {
ret *= 26;
ret += i < a.size() ? (a[i] | 32) - 'a' : 0;
ret |= i < a.size() ? ((a[i] | 32) - 'a') << (i * 8) : 0;
}
return ret;
......@@ -48,64 +47,42 @@ class view_hasher {
class macroprocessor_impl {
public:
bool process(const std::string& s, std::string& output);
bool parse(const std::string& s);
void define();
void expand(std::string& output) const;
private:
struct word {
word (std::string_view name) :
value_{},
name_{std::string{name}},
length{0}
name_{name},
expanded_{true}
{}
word (std::string_view name, bool) :
value_{},
name_{std::string{name}},
length{name_.size()}
name_{name},
expanded_{false}
{}
void append_to(std::string& output) const {
if (length == 0) {
return;
}
if (value_.size() == 0 && length > 0) {
if (!expanded_) {
output += name_;
output += ' ';
} else {
for (word* w : value_) {
if (w->length > 0) {
w->append_to(output);
}
for (const word* w : value_) {
w->append_to(output);
}
}
}
std::size_t update_length() {
if (value_.size() != 0 || length == 0) {
length = 0;
for (word* w : value_) {
std::size_t w_length = w->update_length();
if (w_length > 0) {
length += w_length + 1;
}
}
if (length > 0) {
--length;
}
}
return length;
}
std::vector<word*> value_;
const std::string name_;
std::size_t length;
std::vector<const word*> value_;
std::string name_;
bool expanded_;
};
std::unordered_map<std::string_view, word, view_hasher<3>> words_;
std::unordered_map<std::string_view, word, view_hasher<4>> words_;
std::vector<std::string_view> parsed;
std::vector<const word*> found;
};
template< typename policy>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment