Skip to content

Commit

Permalink
Completed rework of order_t. Ready to unify comparisons
Browse files Browse the repository at this point in the history
  • Loading branch information
KaruroChori committed Jan 17, 2025
1 parent 8ace8e8 commit 33bc545
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 35 deletions.
24 changes: 12 additions & 12 deletions include/vs-templ.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,33 +124,31 @@ struct preprocessor{
std::array<uint64_t,2> hash(const symbol& ref);

private:
struct order_method_t{
struct order_t{
//TODO: legacy to be removed
enum values{
/*enum values{
UNKNOWN = 0,
ASC,
DESC,
RANDOM,
USE_DOT_EVAL = 16 //For strings, split evaluation based on their dot groups. Valid for all methods.
};
};*/

enum class method_t{
DEFAULT,ASC,DESC,RANDOM
}method;
}method = method_t::DEFAULT;

enum class type_t{
DEFAULT,
STRING,NATURAL_STRING,LEXI_STRING,
INTEGER,
FLOAT
}type;
}type = type_t::DEFAULT;

struct modifiers_t{
bool dot : 1; //It has effect only on strings
bool dot : 1 =false; //It has effect only on strings
}modifiers;

static values from_string(std::string_view str);
};

//Precomputed string to avoid spawning an absurd number of small objects in heap at each cycle.
Expand Down Expand Up @@ -209,21 +207,23 @@ struct preprocessor{

}strings;

order_t order_from_string(std::string_view str);

enum class compare_result{
FAILED_CAST = -3,
NOT_COMPARABLE = -2,
LESS = -1,
EQUAL = 0,
BIGGER = 1,
};

static compare_result compare_symbols(const symbol& a, const symbol& b, order_method_t method);
static compare_result compare_symbols(const symbol& a, const symbol& b, order_t method);

//Transforming a string into a parsed symbol, setting an optional base root or leaving it to a default evaluation.
std::optional<symbol> resolve_expr(const std::string_view& str, const pugi::xml_node* base=nullptr) const;

std::vector<pugi::xml_attribute> prepare_props_data(const pugi::xml_node& base, int limit, int offset, const char *filter, order_method_t::values criterion);
std::vector<pugi::xml_attribute> prepare_props_data(const pugi::xml_node& base, int limit, int offset, const char *filter, order_t criterion);

std::vector<pugi::xml_node> prepare_children_data(const pugi::xml_node& base, int limit, int offset, const char *filter, const std::vector<std::pair<std::string,order_method_t::values>>& criteria);
std::vector<pugi::xml_node> prepare_children_data(const pugi::xml_node& base, int limit, int offset, const char *filter, const std::vector<std::pair<std::string,order_t>>& criteria);

void _parse(std::optional<pugi::xml_node_iterator> stop_at);

Expand Down
50 changes: 27 additions & 23 deletions src/vs-templ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void preprocessor::log(log_t::values type, const std::string& str) const{
logfn(type,str.data(),ctx);
}

preprocessor::compare_result preprocessor::compare_symbols(const symbol& a, const symbol& b, order_method_t method){
preprocessor::compare_result preprocessor::compare_symbols(const symbol& a, const symbol& b, order_t method){
//TODO: Implement
return compare_result::NOT_COMPARABLE;
}
Expand Down Expand Up @@ -138,13 +138,17 @@ std::optional<symbol> preprocessor::resolve_expr(const std::string_view& _str, c
return {};
}

preprocessor::order_method_t::values preprocessor::order_method_t::from_string(std::string_view str){
bool dot_eval=false;
if(str[0]=='.')dot_eval=true;
if((std::string_view(str.begin()+dot_eval, str.end()) == std::string_view("asc")))return (values)((dot_eval?USE_DOT_EVAL:UNKNOWN)|ASC);
else if((std::string_view(str.begin()+dot_eval, str.end()) == std::string_view("desc")))return (values)((dot_eval?USE_DOT_EVAL:UNKNOWN)|DESC);
else if((std::string_view(str.begin()+dot_eval, str.end()) == std::string_view("random")))return (values)((dot_eval?USE_DOT_EVAL:UNKNOWN)|RANDOM);
else return order_method_t::UNKNOWN;
preprocessor::order_t preprocessor::order_from_string(std::string_view str){
order_t tmp;
if(str[0]=='.'){tmp.modifiers.dot=true;}
if((std::string_view(str.begin()+tmp.modifiers.dot, str.end()) == std::string_view("asc"))){tmp.method=order_t::method_t::ASC;}
else if((std::string_view(str.begin()+tmp.modifiers.dot, str.end()) == std::string_view("desc"))){tmp.method=order_t::method_t::DESC;}
else if((std::string_view(str.begin()+tmp.modifiers.dot, str.end()) == std::string_view("random"))){tmp.method=order_t::method_t::RANDOM;}
else{
log(log_t::WARNING,std::format("`{}` is not a valid criterion for comparison",str));
}

return tmp;
}


Expand Down Expand Up @@ -222,14 +226,14 @@ void preprocessor::ns_strings::prepare(const char * ns_prefix){
# undef STRLEN
}

std::vector<pugi::xml_attribute> preprocessor::prepare_props_data(const pugi::xml_node& base, int limit, int offset, const char *filter, order_method_t::values criterion){
std::vector<pugi::xml_attribute> preprocessor::prepare_props_data(const pugi::xml_node& base, int limit, int offset, const char *filter, order_t criterion){
auto cmp_fn = [&](const pugi::xml_attribute& a, const pugi::xml_attribute& b)->int{
if(criterion==order_method_t::ASC){
if(criterion.method==order_t::method_t::ASC){
int cmp = strcmp(a.name(),b.name());
if(cmp==-1)return true;
else return false;
}
else if(criterion==order_method_t::DESC){
else if(criterion.method==order_t::method_t::DESC){
int cmp = strcmp(a.name(),b.name());
if(cmp==1)return true;
else return false;
Expand Down Expand Up @@ -271,21 +275,21 @@ std::vector<pugi::xml_attribute> preprocessor::prepare_props_data(const pugi::xm
return {};
}

std::vector<pugi::xml_node> preprocessor::prepare_children_data(const pugi::xml_node& base, int limit, int offset, const char* filter, const std::vector<std::pair<std::string,order_method_t::values>>& criteria){
std::vector<pugi::xml_node> preprocessor::prepare_children_data(const pugi::xml_node& base, int limit, int offset, const char* filter, const std::vector<std::pair<std::string,order_t>>& criteria){
auto cmp_fn = [&](const pugi::xml_node& a, const pugi::xml_node& b)->int{
for(auto& criterion: criteria){
auto valA = resolve_expr(criterion.first.c_str(),&a);
auto valB = resolve_expr(criterion.first.c_str(),&b);

if(criterion.second==order_method_t::ASC){
if(criterion.second.method==order_t::method_t::ASC){
if(valA<valB)return true;
else if(valA>valB) return false;
}
else if(criterion.second==order_method_t::DESC){
else if(criterion.second.method==order_t::method_t::DESC){
if(valA<valB)return false;
else if(valA>valB) return true;
}
else if(criterion.second==(order_method_t::ASC | order_method_t::USE_DOT_EVAL)){
else if(criterion.second.method==order_t::method_t::ASC && criterion.second.modifiers.dot){
if(valA.has_value() && std::holds_alternative<std::string>(valA.value()) && valB.has_value() && std::holds_alternative<std::string>(valB.value())){
const std::string& strA = std::get<std::string>(valA.value());
const std::string& strB = std::get<std::string>(valB.value());
Expand All @@ -296,7 +300,7 @@ std::vector<pugi::xml_node> preprocessor::prepare_children_data(const pugi::xml_
}
else return false;
}
else if(criterion.second==(order_method_t::DESC | order_method_t::USE_DOT_EVAL)){
else if(criterion.second.method==order_t::method_t::DESC && criterion.second.modifiers.dot){
if(valA.has_value() && std::holds_alternative<std::string>(valA.value()) && valB.has_value() && std::holds_alternative<std::string>(valB.value())){
const std::string& strA = std::get<std::string>(valA.value());
const std::string& strB = std::get<std::string>(valB.value());
Expand All @@ -307,7 +311,7 @@ std::vector<pugi::xml_node> preprocessor::prepare_children_data(const pugi::xml_
}
else return false;
}
else if(criterion.second==order_method_t::RANDOM){
else if(criterion.second.method==order_t::method_t::RANDOM){
std::array<uint64_t,2> hashA = hash(valA.value_or(0)), hashB = hash(valB.value_or(0));
if(hashA<hashB)return true;
else if(hashA>hashB) return false;
Expand Down Expand Up @@ -409,14 +413,14 @@ void preprocessor::_parse(std::optional<pugi::xml_node_iterator> stop_at){
}
}
else{
std::vector<std::pair<std::string,order_method_t::values>> criteria;
std::vector<std::pair<std::string,order_t>> criteria;
//Build criteria
{
auto orders = split_string(_order_by,'|');
int c = 0;
//Apply order directive with wrapping in case not enough cases are specified.
for(auto& i:split_string(_sort_by,'|')){
criteria.emplace_back(i,order_method_t::from_string(orders[c%orders.size()]));
criteria.emplace_back(i,order_from_string(orders[c%orders.size()]));
c++;
}
}
Expand Down Expand Up @@ -487,7 +491,7 @@ void preprocessor::_parse(std::optional<pugi::xml_node_iterator> stop_at){
}
}
else{
auto good_data = prepare_props_data(std::get<const pugi::xml_node>(expr.value()), limit, offset, filter,order_method_t::from_string(_order_by));
auto good_data = prepare_props_data(std::get<const pugi::xml_node>(expr.value()), limit, offset, filter,order_from_string(_order_by));

if(good_data.size()==0){
for(const auto& el: current_template.first->children(strings.EMPTY_TAG)){
Expand Down Expand Up @@ -723,14 +727,14 @@ void preprocessor::_parse(std::optional<pugi::xml_node_iterator> stop_at){
//Do nothing; Maybe warning?
}
else{
std::vector<std::pair<std::string,order_method_t::values>> criteria;
std::vector<std::pair<std::string,order_t>> criteria;
//Build criteria
{
auto orders = split_string(_order_by,'|');
int c = 0;
//Apply order directive with wrapping in case not enough cases are specified.
for(auto& i:split_string(_sort_by,'|')){
criteria.emplace_back(i,order_method_t::from_string(orders[c%orders.size()]));
criteria.emplace_back(i,order_from_string(orders[c%orders.size()]));
c++;
}
}
Expand Down Expand Up @@ -808,7 +812,7 @@ void preprocessor::_parse(std::optional<pugi::xml_node_iterator> stop_at){
//Maybe error?
}
else{
auto good_data = prepare_props_data(std::get<const pugi::xml_node>(expr.value()), limit, offset, filter,order_method_t::from_string(_order_by));
auto good_data = prepare_props_data(std::get<const pugi::xml_node>(expr.value()), limit, offset, filter,order_from_string(_order_by));

if(good_data.size()==0){
//Do nothing; Maybe warning?
Expand Down

0 comments on commit 33bc545

Please sign in to comment.