query stripper is implemented with the template metaprogramming

This commit is contained in:
Marko Budiselic 2016-02-04 02:45:12 +01:00
parent 3e5f2de6c2
commit 499469aec2
4 changed files with 63 additions and 7 deletions

Binary file not shown.

View File

@ -21,6 +21,10 @@ using std::endl;
class QueryEngine class QueryEngine
{ {
public: public:
QueryEngine()
{
}
QueryResult execute(const std::string& query) QueryResult execute(const std::string& query)
{ {
auto stripped = stripper.strip(query); auto stripped = stripper.strip(query);
@ -35,7 +39,7 @@ public:
private: private:
// TODO: use IoC or something similar // TODO: use IoC or something similar
QueryStripper stripper; QueryStripper<int, int, int> stripper{TK_INT, TK_FLOAT, TK_STR};
QueryTraverser traverser; QueryTraverser traverser;
CodeGenerator generator; CodeGenerator generator;
CodeCompiler compiler; CodeCompiler compiler;

View File

@ -1,27 +1,30 @@
#pragma once #pragma once
#include <string> #include <string>
#include <regex> #include <tuple>
#include <utility>
#include "cypher/tokenizer/cypher_lexer.hpp"
#include "cypher/cypher.h" #include "cypher/cypher.h"
#include "cypher/tokenizer/cypher_lexer.hpp"
#include "utils/variadic/variadic.hpp"
template<typename ...Ts>
class QueryStripper class QueryStripper
{ {
public: public:
// TODO: extract parameters QueryStripper(Ts&&... strip_types)
: strip_types(std::make_tuple(std::forward<Ts>(strip_types)...)) {}
std::string strip(const std::string& query) std::string strip(const std::string& query)
{ {
auto tokenizer = lexer.tokenize(query); auto tokenizer = lexer.tokenize(query);
std::string stripped = ""; std::string stripped = "";
int counter = 0; int counter = 0;
constexpr auto size = std::tuple_size<decltype(strip_types)>::value;
while (auto token = tokenizer.lookup()) while (auto token = tokenizer.lookup())
{ {
// TODO: do this more generic via template metaprogramming if (_or(token.id, strip_types, std::make_index_sequence<size>{})) {
if (token.id == TK_STR || token.id == TK_INT ||
token.id == TK_FLOAT) {
stripped += "@" + std::to_string(counter++); stripped += "@" + std::to_string(counter++);
} else { } else {
stripped += token.value; stripped += token.value;
@ -31,5 +34,13 @@ public:
} }
private: private:
std::tuple<Ts...> strip_types;
CypherLexer lexer; CypherLexer lexer;
template<typename Value, typename Tuple, std::size_t ...index>
bool _or(Value&& value, Tuple&& tuple, std::index_sequence<index...>)
{
return or_vargs(std::forward<Value>(value),
std::get<index>(std::forward<Tuple>(tuple))...);
}
}; };

View File

@ -0,0 +1,41 @@
#pragma once
#include <iostream>
// variadic argument printer
template<class Head>
void _print_vargs(std::ostream& s, Head&& head)
{
s << std::forward<Head>(head);
}
template<class Head, class ...Tail>
void _print_vargs(std::ostream& s, Head&& head, Tail&& ...tail)
{
s << std::forward<Head>(head);
_print_vargs(s, std::forward<Tail>(tail)...);
}
template<class ...Args>
void print_vargs(Args&&... args)
{
_print_vargs(std::cout, std::forward<Args>(args)...);
}
// value equality with any of variadic argument
// example: value == varg[0] OR value == varg[1] OR ...
template<class Value, class Head>
bool _or_vargs(Value&& value, Head&& head)
{
return value == head;
}
template<class Value, class Head, class ...Tail>
bool _or_vargs(Value&& value, Head&& head, Tail&& ...tail)
{
return value == head || _or_vargs(std::forward<Value>(value), tail...);
}
template<class Value, class ...Array>
bool or_vargs(Value&& value, Array&&... array)
{
return _or_vargs(std::forward<Value>(value), std::forward<Array>(array)...);
}