From 75aa6e94d861753d0976b5a549f8165b4df942b3 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 8 May 2013 16:54:25 +0100 Subject: [PATCH] + expression_optimizer (experimental) at the moment very basic ops are supported e.g ``` expr = 1+1+1 ---> expr = 3 expr = 1+1+[ATTR] ---> 2+[ATTR] expr = [ATTR] + 1 + 1 ---> ([ATTR] + 1) + 1 ### stays unchaged expr = [ATTR] + 1/3.14159 + 1 ---> ([ATTR] + 0.31831) + 1 ``` --- include/mapnik/expression_optimizer.hpp | 125 ++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 include/mapnik/expression_optimizer.hpp diff --git a/include/mapnik/expression_optimizer.hpp b/include/mapnik/expression_optimizer.hpp new file mode 100644 index 000000000..3507a4a36 --- /dev/null +++ b/include/mapnik/expression_optimizer.hpp @@ -0,0 +1,125 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2013 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSION_OPTIMIZER_HPP +#define MAPNIK_EXPRESSION_OPTIMIZER_HPP + +// mapnik +#include +#include +#include + +// boost +#include +#include +#include +#include + +namespace mapnik +{ + + +template +struct optimize : boost::static_visitor< std::tuple > +{ + typedef T node_type; + typedef std::tuple return_type; + + return_type operator() (value const& v) const + { + return std::make_tuple(node_type(v),true); + } + + return_type operator() (attribute const& attr) const + { + return std::make_tuple(node_type(attr),false); + } + + return_type operator() (geometry_type_attribute const& attr) const + { + return return_type(node_type(attr),false); + } + + return_type operator() (binary_node const & x) const + { + return return_type(node_type(x),false); +// return (boost::apply_visitor(optimize(),x.left).to_bool()) + // && (boost::apply_visitor(optimize(),x.right).to_bool()); + } + + return_type operator() (binary_node const & x) const + { + return return_type(node_type(x),false); +// return (boost::apply_visitor(optimize(),x.left).to_bool()) + // || (boost::apply_visitor(optimize(),x.right).to_bool()); + } + + template + return_type operator() (binary_node const& x) const + { + auto left = boost::apply_visitor(optimize(),x.left); + auto right = boost::apply_visitor(optimize(),x.right); + if (std::get<1>(left) && std::get<1>(right)) + { + // evaluate + typename make_op::type operation; + auto lv = boost::get(std::get<0>(left)); + auto rv = boost::get(std::get<0>(right)); + return return_type(node_type(operation(lv,rv)),true); + } + else + return return_type(node_type(binary_node(std::get<0>(left), + std::get<0>(right))),false); + } + + template + return_type operator() (unary_node const& x) const + { + //typename make_op::type func; + //return func(boost::apply_visitor(*this, x.expr)); +// return node_type(x); + return return_type(node_type(x),false); + } + + return_type operator() (unary_node const& x) const + { +// return node_type(x); + return return_type(node_type(x),false); + //return ! (boost::apply_visitor(optimize(),x.expr).to_bool()); + } + + return_type operator() (regex_match_node const& x) const + { + return return_type(node_type(x),false); +// return boost::apply_visitor(optimize(),x.expr); + } + + return_type operator() (regex_replace_node const& x) const + { + return return_type(node_type(x),false); + //return boost::apply_visitor(optimize(),x.expr); + } +}; + +} + +#endif // MAPNIK_EXPRESSION_OPTIMIZER_HPP