unary minus operator on mapnik::value and in expression_grammar

This commit is contained in:
Mickey Rose 2012-05-29 23:45:13 +02:00
parent 109081bef3
commit a6b4bb88ce
4 changed files with 59 additions and 4 deletions

View file

@ -73,6 +73,12 @@ struct evaluate : boost::static_visitor<T1>
template <typename Tag>
value_type operator() (unary_node<Tag> const& x) const
{
typename make_op<Tag>::type func;
return func(boost::apply_visitor(*this, x.expr));
}
value_type operator() (unary_node<tags::logical_not> const& x) const
{
return ! (boost::apply_visitor(evaluate<feature_type,value_type>(feature_),x.expr).to_bool());
}

View file

@ -198,21 +198,26 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
| ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ])
)
;
additive_expr = multiplicative_expr [_val = _1]
>> * ( '+' >> multiplicative_expr[_val += _1]
| '-' >> multiplicative_expr[_val -= _1]
)
;
multiplicative_expr = primary_expr [_val = _1]
>> *( '*' >> primary_expr [_val *= _1]
| '/' >> primary_expr [_val /= _1]
| '%' >> primary_expr [_val %= _1]
multiplicative_expr = unary_expr [_val = _1]
>> *( '*' >> unary_expr [_val *= _1]
| '/' >> unary_expr [_val /= _1]
| '%' >> unary_expr [_val %= _1]
| regex_match_expr[_val = regex_match_(_val, _1)]
| regex_replace_expr(_val) [_val = _1]
)
;
unary_expr = primary_expr [_val = _1]
| '+' >> primary_expr [_val = _1]
| '-' >> primary_expr [_val = -_1]
;
primary_expr = strict_double [_val = _1]
| int_ [_val = _1]
@ -256,6 +261,7 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
rule_type logical_expr;
rule_type additive_expr;
rule_type multiplicative_expr;
rule_type unary_expr;
rule_type not_expr;
rule_type primary_expr;
qi::rule<Iterator, std::string() > regex_match_expr;

View file

@ -40,6 +40,14 @@ namespace mapnik
{
namespace tags {
struct negate
{
static const char* str()
{
return "-";
}
};
struct plus
{
static const char* str()
@ -166,6 +174,7 @@ typedef mapnik::value value_type;
typedef boost::variant <
value_type,
attribute,
boost::recursive_wrapper<unary_node<tags::negate> >,
boost::recursive_wrapper<binary_node<tags::plus> >,
boost::recursive_wrapper<binary_node<tags::minus> >,
boost::recursive_wrapper<binary_node<tags::mult> >,
@ -185,6 +194,7 @@ boost::recursive_wrapper<regex_replace_node>
> expr_node;
template <typename Tag> struct make_op;
template <> struct make_op<tags::negate> { typedef std::negate<value_type> type;};
template <> struct make_op<tags::plus> { typedef std::plus<value_type> type;};
template <> struct make_op<tags::minus> { typedef std::minus<value_type> type;};
template <> struct make_op<tags::mult> { typedef std::multiplies<value_type> type;};
@ -289,6 +299,11 @@ struct function_call
// ops
inline expr_node& operator- (expr_node& expr)
{
return expr = unary_node<tags::negate>(expr);
}
inline expr_node & operator += ( expr_node &left ,const expr_node &right)
{
return left = binary_node<tags::plus>(left,right);

View file

@ -524,6 +524,29 @@ struct mod: public boost::static_visitor<V>
}
};
template <typename V>
struct negate : public boost::static_visitor<V>
{
typedef V value_type;
template <typename T>
value_type operator() (T val) const
{
return -val;
}
value_type operator() (value_null const& val) const
{
return val;
}
value_type operator() (UnicodeString const& ustr) const
{
UnicodeString inplace(ustr);
return inplace.reverse();
}
};
struct to_bool : public boost::static_visitor<bool>
{
bool operator() (bool val) const
@ -763,6 +786,11 @@ public:
return boost::apply_visitor(impl::less_or_equal(),base_,other.base_);
}
value operator- () const
{
return boost::apply_visitor(impl::negate<value>(), base_);
}
value_base const& base() const
{
return base_;