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)
{
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
{
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>
struct escaped_string
: karma::grammar<OutputIterator, std::string(char const*)>
@ -150,7 +141,7 @@ struct extract_string
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);
}
};
@ -173,7 +164,6 @@ struct feature_generator_grammar:
karma::rule<OutputIterator, mapnik::value_unicode_string()> ustring;
typename karma::int_generator<mapnik::value_integer,10, false> int__;
boost::phoenix::function<get_id> id_;
boost::phoenix::function<value_base> value_base_;
boost::phoenix::function<extract_string> extract_string_;
boost::phoenix::function<utf8> utf8_;
std::string quote_;

View file

@ -89,7 +89,7 @@ feature_generator_grammar<OutputIterator>::feature_generator_grammar()
pair = lit('"')
<< kstring[_1 = boost::phoenix::at_c<0>(_val)] << 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)]

View file

@ -70,7 +70,7 @@ struct put_property
explicit put_property(mapnik::transcoder const& tr)
: tr_(tr) {}
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));
}
@ -104,7 +104,7 @@ struct feature_grammar :
qi::rule<Iterator,void(FeatureType &),space_type> properties;
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<extract_geometry> extract_geometry_;

View file

@ -41,8 +41,10 @@ struct generic_json
qi::int_parser<mapnik::value_integer,10,1,-1> int__;
qi::rule<Iterator,std::string(), space_type> string_;
qi::rule<Iterator,space_type> key_value;
qi::rule<Iterator,mapnik::util::variant<value_null,bool,
value_integer,value_double,
qi::rule<Iterator,mapnik::util::variant<value_null,
value_double,
value_integer,
bool,
std::string>(),space_type> number;
qi::rule<Iterator,space_type> object;
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>
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::rule<Iterator,std::string(), space_type> string_;
qi::rule<Iterator,space_type> key_value;
qi::rule<Iterator,space_type, util::variant<value_null,bool,
value_integer,value_double,
std::string>()> number;
qi::rule<Iterator,space_type, mapnik::topojson::value()> number;
qi::rule<Iterator,space_type> object;
qi::rule<Iterator,space_type> array;
qi::rule<Iterator,space_type> pairs;
@ -102,7 +115,9 @@ private:
qi::rule<Iterator, space_type, mapnik::topojson::value()> attribute_value;
// 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
boost::phoenix::function<where_message> where_message_;
};

View file

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

View file

@ -43,7 +43,7 @@ struct coordinate
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 properties = std::vector<property>;

View file

@ -799,9 +799,8 @@ struct to_expression_string : public util::static_visitor<std::string>
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&);
@ -810,64 +809,55 @@ class value
public:
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>
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)
: base_(other.base_) {}
template <typename T>
value ( T && val)
: value_base(std::move(typename detail::mapnik_value_type<T>::type(val))) {}
value & operator=( value const& other)
{
if (this == &other)
return *this;
base_ = other.base_;
return *this;
}
value( value && other) noexcept
: base_(std::move(other.base_)) {}
value & operator=( value const& other) = default;
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
{
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
{
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
{
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
{
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
{
return util::apply_visitor(impl::less_or_equal(),base_,other.base_);
return util::apply_visitor(impl::less_or_equal(),*this,other);
}
value operator- () const
{
return util::apply_visitor(impl::negate<value>(), base_);
}
value_base const& base() const
{
return base_;
return util::apply_visitor(impl::negate<value>(), *this);
}
bool is_null() const;
@ -875,68 +865,67 @@ public:
template <typename T>
T convert() const
{
return util::apply_visitor(impl::convert<T>(),base_);
return util::apply_visitor(impl::convert<T>(),*this);
}
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
{
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
{
return util::apply_visitor(impl::convert<std::string>(),base_);
return util::apply_visitor(impl::convert<std::string>(),*this);
}
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
{
return util::apply_visitor(impl::convert<value_double>(),base_);
return util::apply_visitor(impl::convert<value_double>(),*this);
}
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)
{
return value(util::apply_visitor(impl::add<value>(),p1.base_, p2.base_));
return value(util::apply_visitor(impl::add<value>(),p1, 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)
{
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)
{
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)
{
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>
@ -948,12 +937,6 @@ operator << (std::basic_ostream<charT,traits>& out,
return out;
}
// hash function
inline std::size_t hash_value(value const& val)
{
return hash_value(val.base());
}
} // namespace value_adl_barrier
using value_adl_barrier::value;
@ -984,7 +967,7 @@ struct is_null_visitor : public util::static_visitor<bool>
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

View file

@ -199,7 +199,7 @@ struct mapnik_value_type<T, typename std::enable_if<detail::is_value_double<T>::
template <typename T>
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

View file

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