diff --git a/include/llmr/map/filter_expression.hpp b/include/llmr/map/filter_expression.hpp new file mode 100644 index 000000000..d536a5a34 --- /dev/null +++ b/include/llmr/map/filter_expression.hpp @@ -0,0 +1,102 @@ +#ifndef LLMR_MAP_FILTER_EXPRESSION +#define LLMR_MAP_FILTER_EXPRESSION + +#include +#include + +#include +#include + +namespace llmr { + +enum class FilterOperator { + Equal, + NotEqual +}; + +enum class ExpressionOperator { + Or, + And +}; + + +inline FilterOperator filterOperatorType(const std::string &op) { + if (op == "!=" || op == "not") { + return FilterOperator::NotEqual; + } else if (op == "==" || op == "eq") { + return FilterOperator::Equal; + } else { + fprintf(stderr, "[WARNING] filter operator '%s' unrecognized\n", op.c_str()); + return FilterOperator::Equal; + } +} + +inline ExpressionOperator expressionOperatorType(const std::string &op) { + if (op == "&&" || op == "and") { + return ExpressionOperator::And; + } else if (op == "||" || op == "or") { + return ExpressionOperator::Or; + } else { + fprintf(stderr, "[WARNING] expression operator '%s' unrecognized\n", op.c_str()); + return ExpressionOperator::Or; + } +} + + + +class PropertyExpression; + +class PropertyFilter { +public: + inline PropertyFilter(const std::string &field, FilterOperator op, const Value &value) : field(field), op(op), value(value) {}; + inline PropertyFilter(PropertyFilter &&filter) + : field(std::move(filter.field)), + op(filter.op), + value(std::move(filter.value)) { + } + + // Returns true if the filter passes, even if the key is missing. + inline bool isMissingFieldOkay() const { + switch (op) { + case FilterOperator::NotEqual: + return true; + default: + return false; + } + } + + inline bool compare(const Value &other) const { + switch (op) { + case FilterOperator::NotEqual: + return !util::relaxed_equal(value)(other); + default: + return util::relaxed_equal(value)(other); + } + } + +public: + std::string field; + FilterOperator op = FilterOperator::Equal; + Value value; +}; + +typedef util::variant> PropertyFilterExpression; + + +class PropertyExpression { +public: + inline PropertyExpression() {} + inline PropertyExpression(PropertyExpression &&expression) + : op(expression.op), + operands(std::move(expression.operands)) { + } + +public: + ExpressionOperator op = ExpressionOperator::Or; + std::vector operands; +}; + + +} + +#endif diff --git a/include/llmr/util/recursive_wrapper.hpp b/include/llmr/util/recursive_wrapper.hpp new file mode 100644 index 000000000..557b576c0 --- /dev/null +++ b/include/llmr/util/recursive_wrapper.hpp @@ -0,0 +1,132 @@ +#ifndef LLMR_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP +#define LLMR_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP + +#include + +namespace llmr { + +namespace util { + +template +class recursive_wrapper +{ +public: + + typedef T type; + +private: + + T* p_; + +public: + + ~recursive_wrapper(); + recursive_wrapper(); + + recursive_wrapper(recursive_wrapper const& operand); + recursive_wrapper(T const& operand); + recursive_wrapper(recursive_wrapper&& operand); + recursive_wrapper(T&& operand); + +private: + + void assign(const T& rhs); + +public: + + recursive_wrapper& operator=(const recursive_wrapper& rhs) + { + assign( rhs.get() ); + return *this; + } + + recursive_wrapper& operator=(const T& rhs) + { + assign( rhs ); + return *this; + } + + void swap(recursive_wrapper& operand) noexcept + { + T* temp = operand.p_; + operand.p_ = p_; + p_ = temp; + } + + + recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept + { + swap(rhs); + return *this; + } + + recursive_wrapper& operator=(T&& rhs) + { + get() = std::move(rhs); + return *this; + } + + +public: + + T& get() { return *get_pointer(); } + const T& get() const { return *get_pointer(); } + + T* get_pointer() { return p_; } + const T* get_pointer() const { return p_; } + +}; + +template +recursive_wrapper::~recursive_wrapper() +{ + delete p_; +} + +template +recursive_wrapper::recursive_wrapper() + : p_(new T) +{ +} + +template +recursive_wrapper::recursive_wrapper(recursive_wrapper const& operand) + : p_(new T( operand.get() )) +{ +} + +template +recursive_wrapper::recursive_wrapper(T const& operand) + : p_(new T(operand)) +{ +} + +template +recursive_wrapper::recursive_wrapper(recursive_wrapper&& operand) + : p_(new T( std::move(operand.get()) )) +{ +} + +template +recursive_wrapper::recursive_wrapper(T&& operand) + : p_(new T( std::move(operand) )) +{ +} + +template +void recursive_wrapper::assign(const T& rhs) +{ + this->get() = rhs; +} + +template +inline void swap(recursive_wrapper& lhs, recursive_wrapper& rhs) noexcept +{ + lhs.swap(rhs); +} + +} + +} + +#endif // LLMR_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP