/***************************************************************************** * * This file is part of Mapnik (c++ mapping toolkit) * * Copyright (C) 2011 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_NODE_HPP #define MAPNIK_EXPRESSION_NODE_HPP // mapnik #include #include // boost #include #include #include #if defined(BOOST_REGEX_HAS_ICU) #include #endif #include namespace mapnik { namespace tags { struct plus { static const char* str() { return "+"; } }; struct minus { static const char* str() { return "-"; } }; struct mult { static const char* str() { return "*"; } }; struct div { static const char* str() { return "/"; } }; struct mod { static const char* str() { return "%"; } }; struct less { static const char* str() { return "<"; } }; struct less_equal { static const char* str() { return "<="; } }; struct greater { static const char* str() { return ">"; } }; struct greater_equal { static const char* str() { return ">="; } }; struct equal_to { static const char* str() { return "="; } }; struct not_equal_to { static const char* str() { return "!="; } }; struct logical_not { static const char* str() { return "not "; } }; struct logical_and { static const char* str() { return " and "; } }; struct logical_or { static const char* str() { return " or "; } }; } // end operation tags template struct binary_node; template struct unary_node; struct regex_match_node; struct regex_replace_node; typedef mapnik::value value_type; typedef boost::variant < value_type, attribute, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper >, boost::recursive_wrapper, boost::recursive_wrapper > expr_node; template struct make_op; template <> struct make_op { typedef std::plus type;}; template <> struct make_op { typedef std::minus type;}; template <> struct make_op { typedef std::multiplies type;}; template <> struct make_op { typedef std::divides type;}; template <> struct make_op { typedef std::modulus type;}; template <> struct make_op { typedef std::less type;}; template <> struct make_op { typedef std::less_equal type;}; template <> struct make_op { typedef std::greater type;}; template <> struct make_op { typedef std::greater_equal type;}; template <> struct make_op { typedef std::equal_to type;}; template <> struct make_op { typedef std::not_equal_to type;}; template <> struct make_op { typedef std::logical_not type;}; template <> struct make_op { typedef std::logical_and type;}; template <> struct make_op { typedef std::logical_or type;}; template struct unary_node { unary_node (expr_node const& a) : expr(a) {} static const char* type() { return Tag::str(); } expr_node expr; }; template struct binary_node { binary_node(expr_node const& a, expr_node const& b) : left(a), right(b) {} static const char* type() { return Tag::str(); } expr_node left,right; }; #if defined(BOOST_REGEX_HAS_ICU) struct regex_match_node { regex_match_node (expr_node const& a, UnicodeString const& ustr) : expr(a), pattern(boost::make_u32regex(ustr)) {} expr_node expr; boost::u32regex pattern; }; struct regex_replace_node { regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f) : expr(a), pattern(boost::make_u32regex(ustr)), format(f) {} expr_node expr; boost::u32regex pattern; UnicodeString format; }; #else struct regex_match_node { regex_match_node (expr_node const& a, std::string const& str) : expr(a), pattern(str) {} expr_node expr; boost::regex pattern; }; struct regex_replace_node { regex_replace_node (expr_node const& a, std::string const& str, std::string const& f) : expr(a), pattern(str), format(f) {} expr_node expr; boost::regex pattern; std::string format; }; #endif struct function_call { template explicit function_call (expr_node const a, Fun f) : expr(a), call_(f) {} expr_node expr; boost::function call_; }; // ops inline expr_node & operator += ( expr_node &left ,const expr_node &right) { return left = binary_node(left,right); } inline expr_node & operator -= ( expr_node &left ,const expr_node &right) { return left = binary_node(left,right); } inline expr_node & operator *= ( expr_node &left ,const expr_node &right) { return left = binary_node(left,right); } inline expr_node & operator /= ( expr_node &left ,const expr_node &right) { return left = binary_node(left,right); } inline expr_node & operator %= ( expr_node &left ,const expr_node &right) { return left = binary_node(left,right); } inline expr_node & operator < ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } inline expr_node & operator <= ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } inline expr_node & operator > ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } inline expr_node & operator >= ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } inline expr_node & operator == ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } inline expr_node & operator != ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } inline expr_node & operator ! (expr_node & expr) { return expr = unary_node(expr); } inline expr_node & operator && ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } inline expr_node & operator || ( expr_node &left, expr_node const& right) { return left = binary_node(left,right); } } #endif //MAPNIK_EXPRESSION_NODE_HPP