re-implement mapnik::value deriving from value_base and update across core

fix mapnik::value conversions in topojson plugin
This commit is contained in:
artemp 2014-09-04 17:10:13 +01:00
parent 0985cc907d
commit 72e2f4446f
12 changed files with 67 additions and 77 deletions

View file

@ -71,7 +71,7 @@ namespace boost { namespace python {
{ {
static PyObject* convert(mapnik::value const& v) static PyObject* convert(mapnik::value const& v)
{ {
return mapnik::util::apply_visitor(value_converter(),v.base()); return mapnik::util::apply_visitor(value_converter(),v);
} }
}; };

View file

@ -70,7 +70,7 @@ struct value_not_null
{ {
bool operator() (feature_kv_iterator::value_type const& kv) const bool operator() (feature_kv_iterator::value_type const& kv) const
{ {
return !util::apply_visitor(mapnik::detail::is_null_visitor(), std::get<1>(kv).base()); return !util::apply_visitor(mapnik::detail::is_null_visitor(), std::get<1>(kv));
} }
}; };

View file

@ -126,15 +126,6 @@ struct utf8
} }
}; };
struct value_base
{
using result_type = mapnik::value_base const&;
mapnik::value_base const& operator() (mapnik::value const& val) const
{
return val.base();
}
};
template <typename OutputIterator> template <typename OutputIterator>
struct escaped_string struct escaped_string
: karma::grammar<OutputIterator, std::string(char const*)> : karma::grammar<OutputIterator, std::string(char const*)>
@ -150,7 +141,7 @@ struct extract_string
result_type operator() (mapnik::value const& val) const result_type operator() (mapnik::value const& val) const
{ {
bool need_quotes = val.base().is<value_unicode_string>(); bool need_quotes = val.is<value_unicode_string>();
return std::make_tuple(val.to_string(), need_quotes); return std::make_tuple(val.to_string(), need_quotes);
} }
}; };
@ -173,7 +164,6 @@ struct feature_generator_grammar:
karma::rule<OutputIterator, mapnik::value_unicode_string()> ustring; karma::rule<OutputIterator, mapnik::value_unicode_string()> ustring;
typename karma::int_generator<mapnik::value_integer,10, false> int__; typename karma::int_generator<mapnik::value_integer,10, false> int__;
boost::phoenix::function<get_id> id_; boost::phoenix::function<get_id> id_;
boost::phoenix::function<value_base> value_base_;
boost::phoenix::function<extract_string> extract_string_; boost::phoenix::function<extract_string> extract_string_;
boost::phoenix::function<utf8> utf8_; boost::phoenix::function<utf8> utf8_;
std::string quote_; std::string quote_;

View file

@ -89,7 +89,7 @@ feature_generator_grammar<OutputIterator>::feature_generator_grammar()
pair = lit('"') pair = lit('"')
<< kstring[_1 = boost::phoenix::at_c<0>(_val)] << lit('"') << kstring[_1 = boost::phoenix::at_c<0>(_val)] << lit('"')
<< lit(':') << lit(':')
<< value[_1 = extract_string_(value_base_(at_c<1>(_val)))] << value[_1 = extract_string_(at_c<1>(_val))]
; ;
value = eps(at_c<1>(_val)) << escaped_string_(quote_.c_str())[_1 = at_c<0>(_val)] value = eps(at_c<1>(_val)) << escaped_string_(quote_.c_str())[_1 = at_c<0>(_val)]

View file

@ -70,7 +70,7 @@ struct put_property
explicit put_property(mapnik::transcoder const& tr) explicit put_property(mapnik::transcoder const& tr)
: tr_(tr) {} : tr_(tr) {}
template <typename T0,typename T1, typename T2> template <typename T0,typename T1, typename T2>
result_type operator() (T0 & feature, T1 const& key, T2 const& val) const result_type operator() (T0 & feature, T1 const& key, T2 && val) const
{ {
feature.put_new(key, mapnik::util::apply_visitor(attribute_value_visitor(tr_),val)); feature.put_new(key, mapnik::util::apply_visitor(attribute_value_visitor(tr_),val));
} }
@ -104,7 +104,7 @@ struct feature_grammar :
qi::rule<Iterator,void(FeatureType &),space_type> properties; qi::rule<Iterator,void(FeatureType &),space_type> properties;
qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),space_type> attributes; qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),space_type> attributes;
qi::rule<Iterator, mapnik::util::variant<value_null,bool,value_integer,value_double,std::string>(), space_type> attribute_value; qi::rule<Iterator, mapnik::util::variant<value_null,value_double,value_integer, bool, std::string>(), space_type> attribute_value;
phoenix::function<put_property> put_property_; phoenix::function<put_property> put_property_;
phoenix::function<extract_geometry> extract_geometry_; phoenix::function<extract_geometry> extract_geometry_;

View file

@ -41,8 +41,10 @@ struct generic_json
qi::int_parser<mapnik::value_integer,10,1,-1> int__; qi::int_parser<mapnik::value_integer,10,1,-1> int__;
qi::rule<Iterator,std::string(), space_type> string_; qi::rule<Iterator,std::string(), space_type> string_;
qi::rule<Iterator,space_type> key_value; qi::rule<Iterator,space_type> key_value;
qi::rule<Iterator,mapnik::util::variant<value_null,bool, qi::rule<Iterator,mapnik::util::variant<value_null,
value_integer,value_double, value_double,
value_integer,
bool,
std::string>(),space_type> number; std::string>(),space_type> number;
qi::rule<Iterator,space_type> object; qi::rule<Iterator,space_type> object;
qi::rule<Iterator,space_type> array; qi::rule<Iterator,space_type> array;

View file

@ -56,6 +56,21 @@ struct where_message
} }
}; };
namespace detail {
template <typename T>
struct value_converter
{
using result_type = T;
template <typename T1>
result_type operator() (T1 const& val) const
{
return static_cast<result_type>(val);
}
};
}
template <typename Iterator> template <typename Iterator>
struct topojson_grammar : qi::grammar<Iterator, space_type, topology()> struct topojson_grammar : qi::grammar<Iterator, space_type, topology()>
@ -69,9 +84,7 @@ private:
qi::int_parser<mapnik::value_integer,10,1,-1> int__; qi::int_parser<mapnik::value_integer,10,1,-1> int__;
qi::rule<Iterator,std::string(), space_type> string_; qi::rule<Iterator,std::string(), space_type> string_;
qi::rule<Iterator,space_type> key_value; qi::rule<Iterator,space_type> key_value;
qi::rule<Iterator,space_type, util::variant<value_null,bool, qi::rule<Iterator,space_type, mapnik::topojson::value()> number;
value_integer,value_double,
std::string>()> number;
qi::rule<Iterator,space_type> object; qi::rule<Iterator,space_type> object;
qi::rule<Iterator,space_type> array; qi::rule<Iterator,space_type> array;
qi::rule<Iterator,space_type> pairs; qi::rule<Iterator,space_type> pairs;
@ -102,7 +115,9 @@ private:
qi::rule<Iterator, space_type, mapnik::topojson::value()> attribute_value; qi::rule<Iterator, space_type, mapnik::topojson::value()> attribute_value;
// id // id
qi::rule<Iterator,space_type> id; qi::rule<Iterator,space_type> id;
// conversions
boost::phoenix::function<detail::value_converter<mapnik::value_integer> > integer_converter;
boost::phoenix::function<detail::value_converter<mapnik::value_double> > double_converter;
// error // error
boost::phoenix::function<where_message> where_message_; boost::phoenix::function<where_message> where_message_;
}; };

View file

@ -49,7 +49,7 @@ topojson_grammar<Iterator>::topojson_grammar()
using qi::fail; using qi::fail;
using qi::on_error; using qi::on_error;
using phoenix::push_back; using phoenix::push_back;
using phoenix::construct;
// generic json types // generic json types
value = object | array | string_ | number value = object | array | string_ | number
; ;
@ -68,11 +68,11 @@ topojson_grammar<Iterator>::topojson_grammar()
>> lit(']') >> lit(']')
; ;
number %= strict_double number = strict_double[_val = double_converter(_1)]
| int__ | int__[_val = integer_converter(_1)]
| lit("true")[_val = true] | lit("true")[_val = true]
| lit("false")[_val = false] | lit("false")[_val = false]
| lit("null") | lit("null")[_val = construct<value_null>()]
; ;
unesc_char.add unesc_char.add

View file

@ -43,7 +43,7 @@ struct coordinate
double y; double y;
}; };
using value = mapnik::util::variant<value_null,bool,value_integer,value_double,std::string>; using value = mapnik::util::variant<value_null,bool,value_double,value_integer,std::string>;
using property = std::tuple<std::string, value >; using property = std::tuple<std::string, value >;
using properties = std::vector<property>; using properties = std::vector<property>;

View file

@ -799,9 +799,8 @@ struct to_expression_string : public util::static_visitor<std::string>
namespace value_adl_barrier { namespace value_adl_barrier {
class value class value : public value_base
{ {
value_base base_;
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&);
friend const value operator*(value const&,value const&); friend const value operator*(value const&,value const&);
@ -810,64 +809,55 @@ class value
public: public:
value () noexcept //-- comment out for VC++11 value () noexcept //-- comment out for VC++11
: base_(value_null()) {} : value_base(value_null()) {}
value (value const& other) = default;
value( value && other) noexcept = default;
template <typename T> template <typename T>
value ( T const& val) value ( T const& val)
: base_(typename detail::mapnik_value_type<T>::type(val)) {} : value_base(typename detail::mapnik_value_type<T>::type(val)) {}
value (value const& other) template <typename T>
: base_(other.base_) {} value ( T && val)
: value_base(std::move(typename detail::mapnik_value_type<T>::type(val))) {}
value & operator=( value const& other) value & operator=( value const& other) = default;
{
if (this == &other)
return *this;
base_ = other.base_;
return *this;
}
value( value && other) noexcept
: base_(std::move(other.base_)) {}
bool operator==(value const& other) const bool operator==(value const& other) const
{ {
return util::apply_visitor(impl::equals(),base_,other.base_); return util::apply_visitor(impl::equals(),*this,other);
} }
bool operator!=(value const& other) const bool operator!=(value const& other) const
{ {
return util::apply_visitor(impl::not_equals(),base_,other.base_); return util::apply_visitor(impl::not_equals(),*this,other);
} }
bool operator>(value const& other) const bool operator>(value const& other) const
{ {
return util::apply_visitor(impl::greater_than(),base_,other.base_); return util::apply_visitor(impl::greater_than(),*this,other);
} }
bool operator>=(value const& other) const bool operator>=(value const& other) const
{ {
return util::apply_visitor(impl::greater_or_equal(),base_,other.base_); return util::apply_visitor(impl::greater_or_equal(),*this,other);
} }
bool operator<(value const& other) const bool operator<(value const& other) const
{ {
return util::apply_visitor(impl::less_than(),base_,other.base_); return util::apply_visitor(impl::less_than(),*this,other);
} }
bool operator<=(value const& other) const bool operator<=(value const& other) const
{ {
return util::apply_visitor(impl::less_or_equal(),base_,other.base_); return util::apply_visitor(impl::less_or_equal(),*this,other);
} }
value operator- () const value operator- () const
{ {
return util::apply_visitor(impl::negate<value>(), base_); return util::apply_visitor(impl::negate<value>(), *this);
}
value_base const& base() const
{
return base_;
} }
bool is_null() const; bool is_null() const;
@ -875,68 +865,67 @@ public:
template <typename T> template <typename T>
T convert() const T convert() const
{ {
return util::apply_visitor(impl::convert<T>(),base_); return util::apply_visitor(impl::convert<T>(),*this);
} }
value_bool to_bool() const value_bool to_bool() const
{ {
return util::apply_visitor(impl::convert<value_bool>(),base_); return util::apply_visitor(impl::convert<value_bool>(),*this);
} }
std::string to_expression_string(char quote = '\'') const std::string to_expression_string(char quote = '\'') const
{ {
return util::apply_visitor(impl::to_expression_string(quote),base_); return util::apply_visitor(impl::to_expression_string(quote),*this);
} }
std::string to_string() const std::string to_string() const
{ {
return util::apply_visitor(impl::convert<std::string>(),base_); return util::apply_visitor(impl::convert<std::string>(),*this);
} }
value_unicode_string to_unicode() const value_unicode_string to_unicode() const
{ {
return util::apply_visitor(impl::to_unicode(),base_); return util::apply_visitor(impl::to_unicode(),*this);
} }
value_double to_double() const value_double to_double() const
{ {
return util::apply_visitor(impl::convert<value_double>(),base_); return util::apply_visitor(impl::convert<value_double>(),*this);
} }
value_integer to_int() const value_integer to_int() const
{ {
return util::apply_visitor(impl::convert<value_integer>(),base_); return util::apply_visitor(impl::convert<value_integer>(),*this);
} }
}; };
inline const value operator+(value const& p1,value const& p2) inline const value operator+(value const& p1,value const& p2)
{ {
return value(util::apply_visitor(impl::add<value>(),p1, p2));
return value(util::apply_visitor(impl::add<value>(),p1.base_, p2.base_));
} }
inline const value operator-(value const& p1,value const& p2) inline const value operator-(value const& p1,value const& p2)
{ {
return value(util::apply_visitor(impl::sub<value>(),p1.base_, p2.base_)); return value(util::apply_visitor(impl::sub<value>(),p1, p2));
} }
inline const value operator*(value const& p1,value const& p2) inline const value operator*(value const& p1,value const& p2)
{ {
return value(util::apply_visitor(impl::mult<value>(),p1.base_, p2.base_)); return value(util::apply_visitor(impl::mult<value>(),p1, p2));
} }
inline const value operator/(value const& p1,value const& p2) inline const value operator/(value const& p1,value const& p2)
{ {
return value(util::apply_visitor(impl::div<value>(),p1.base_, p2.base_)); return value(util::apply_visitor(impl::div<value>(),p1, p2));
} }
inline const value operator%(value const& p1,value const& p2) inline const value operator%(value const& p1,value const& p2)
{ {
return value(util::apply_visitor(impl::mod<value>(),p1.base_, p2.base_)); return value(util::apply_visitor(impl::mod<value>(),p1, p2));
} }
template <typename charT, typename traits> template <typename charT, typename traits>
@ -948,12 +937,6 @@ operator << (std::basic_ostream<charT,traits>& out,
return out; return out;
} }
// hash function
inline std::size_t hash_value(value const& val)
{
return hash_value(val.base());
}
} // namespace value_adl_barrier } // namespace value_adl_barrier
using value_adl_barrier::value; using value_adl_barrier::value;
@ -984,7 +967,7 @@ struct is_null_visitor : public util::static_visitor<bool>
inline bool value::is_null() const inline bool value::is_null() const
{ {
return util::apply_visitor(mapnik::detail::is_null_visitor(), base_); return util::apply_visitor(mapnik::detail::is_null_visitor(), *this);
} }
} // namespace mapnik } // namespace mapnik

View file

@ -199,7 +199,7 @@ struct mapnik_value_type<T, typename std::enable_if<detail::is_value_double<T>::
template <typename T> template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_unicode_string<T>::value>::type> struct mapnik_value_type<T, typename std::enable_if<detail::is_value_unicode_string<T>::value>::type>
{ {
using type = mapnik::value_unicode_string; using type = mapnik::value_unicode_string const&;
}; };
} // namespace detail } // namespace detail

View file

@ -177,7 +177,7 @@ void geojson_datasource::parse_geojson(T const& buffer)
{ {
desc_.add_descriptor(mapnik::attribute_descriptor(std::get<0>(kv), desc_.add_descriptor(mapnik::attribute_descriptor(std::get<0>(kv),
mapnik::util::apply_visitor(attr_value_converter(), mapnik::util::apply_visitor(attr_value_converter(),
std::get<1>(kv).base()))); std::get<1>(kv))));
} }
} }
else else