Add a modulus operator to the filter language.

This commit is contained in:
Tom Hughes 2009-02-10 15:46:54 +00:00
parent ca0502eaaf
commit abe24475d8
3 changed files with 61 additions and 1 deletions

View file

@ -436,7 +436,8 @@ namespace mapnik
;
term = factor
>> *((L'*' >> factor) [compose_expression<FeatureT,mapnik::mult<value> >(self.exprs)]
| (L'/' >> factor) [compose_expression<FeatureT,mapnik::div<value> >(self.exprs)]);
| (L'/' >> factor) [compose_expression<FeatureT,mapnik::div<value> >(self.exprs)]
| (L'%' >> factor) [compose_expression<FeatureT,mapnik::mod<value> >(self.exprs)]);
expression = term >> *((L'+' >> term) [compose_expression<FeatureT,mapnik::add<value> >(self.exprs)]
| (L'-' >> term) [compose_expression<FeatureT,mapnik::sub<value> >(self.exprs)]);

View file

@ -80,6 +80,19 @@ namespace mapnik
}
};
template <typename T>
struct mod
{
T operator () (T const& left, T const& right)
{
return left % right;
}
static std::string to_string()
{
return "%";
}
};
template <typename FeatureT,typename Op>
struct math_expr_b : public expression<FeatureT>
{

View file

@ -36,6 +36,7 @@
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
// uci
#include <unicode/unistr.h>
#include <unicode/ustring.h>
@ -434,6 +435,44 @@ namespace mapnik {
return lhs / rhs;
}
};
template <typename V>
struct mod: public boost::static_visitor<V>
{
typedef V value_type;
template <typename T1, typename T2>
value_type operator() (T1 const& lhs, T2 const&) const
{
return lhs;
}
template <typename T>
value_type operator() (T lhs, T rhs) const
{
return lhs % rhs;
}
value_type operator() (UnicodeString const& lhs,
UnicodeString const&) const
{
return lhs;
}
value_type operator() (double lhs, int rhs) const
{
return fmod(lhs, rhs);
}
value_type operator() (int lhs, double rhs) const
{
return fmod(lhs, rhs);
}
value_type operator() (double lhs, double rhs) const
{
return fmod(lhs, rhs);
}
};
struct to_bool : public boost::static_visitor<bool>
{
@ -553,6 +592,7 @@ namespace mapnik {
friend const value operator-(value const&,value const&);
friend const value operator*(value const&,value const&);
friend const value operator/(value const&,value const&);
friend const value operator%(value const&,value const&);
public:
value ()
@ -641,6 +681,12 @@ namespace mapnik {
return value(boost::apply_visitor(impl::div<value>(),p1.base_, p2.base_));
}
inline const value operator%(value const& p1,value const& p2)
{
return value(boost::apply_visitor(impl::mod<value>(),p1.base_, p2.base_));
}
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,