use mapnik_value_type promotion traits for better type mapping

in symbolizer and params + move mapnik_value_type traits to
value_types.hpp
This commit is contained in:
artemp 2014-08-13 10:22:43 +01:00
parent 1d02eb0d1d
commit 6972bc30d2
6 changed files with 136 additions and 90 deletions

View file

@ -172,7 +172,7 @@ void export_symbolizer()
{
using namespace boost::python;
//implicitly_convertible<mapnik::value_bool, mapnik::symbolizer_base::value_type>();
implicitly_convertible<mapnik::value_bool, mapnik::symbolizer_base::value_type>();
implicitly_convertible<mapnik::value_integer, mapnik::symbolizer_base::value_type>();
implicitly_convertible<mapnik::value_double, mapnik::symbolizer_base::value_type>();
implicitly_convertible<std::string, mapnik::symbolizer_base::value_type>();

View file

@ -85,7 +85,6 @@ namespace boost { namespace python {
};
}
}
}}
#endif // MAPNIK_PYTHON_BINDING_VALUE_CONVERTER_INCLUDED

View file

@ -40,7 +40,29 @@ namespace mapnik
// fwd declare
class boolean_type;
using value_holder = util::variant<value_null,value_integer,value_double,std::string>;
using value_holder_base = util::variant<value_null,value_integer,value_double,std::string>;
struct value_holder : value_holder_base
{
// default
value_holder()
: value_holder_base() {}
// copy
value_holder(const char* val)
: value_holder_base(val) {}
template <typename T>
value_holder(T const& obj)
: value_holder_base(typename detail::mapnik_value_type<T>::type(obj))
{}
// move
template <typename T>
value_holder(T && obj) noexcept
: value_holder_base(std::move(obj)) {}
};
using parameter = std::pair<std::string, value_holder>;
using param_map = std::map<std::string, value_holder>;

View file

@ -88,9 +88,9 @@ using dash_array = std::vector<std::pair<double,double> >;
class text_placements;
using text_placements_ptr = std::shared_ptr<text_placements>;
struct MAPNIK_DECL symbolizer_base
{
using value_type = util::variant<value_bool,
namespace detail {
using value_base_type = util::variant<value_bool,
value_integer,
enumeration_wrapper,
value_double,
@ -103,6 +103,31 @@ struct MAPNIK_DECL symbolizer_base
dash_array,
raster_colorizer_ptr,
group_symbolizer_properties_ptr>;
struct strict_value : value_base_type
{
// default ctor
strict_value()
: value_base_type() {}
// copy ctor
strict_value(const char* val)
: value_base_type(val) {}
template <typename T>
strict_value(T const& obj)
: value_base_type(typename detail::mapnik_value_type<T>::type(obj))
{}
// move ctor
template <typename T>
strict_value(T && obj) noexcept
: value_base_type(std::move(obj)) {}
};
}
struct MAPNIK_DECL symbolizer_base
{
using value_type = detail::strict_value;
using key_type = mapnik::keys;
using cont_type = std::map<key_type, value_type>;
cont_type properties;

View file

@ -793,88 +793,6 @@ struct to_expression_string : public util::static_visitor<std::string>
namespace value_adl_barrier {
namespace detail {
template <typename T>
struct is_value_bool
{
bool value = std::is_same<T, bool>::value;
};
template <typename T>
struct is_value_integer
{
bool value = std::is_integral<T>::value && !std::is_same<T, bool>::value;
};
template <typename T>
struct is_value_double
{
bool value = std::is_floating_point<T>::value;
};
template <typename T>
struct is_value_unicode_string
{
bool value = std::is_same<T,mapnik::value_unicode_string>::value;
};
template <typename T>
struct is_value_string
{
bool value = std::is_same<T,std::string>::value;
};
template <typename T>
struct is_value_null
{
bool value = std::is_same<T, value_null>::value;
};
} // namespace detail
template <typename T, class Enable = void>
struct mapnik_value_type
{
using type = T;
};
// value_null
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_null<T>::value>::type>
{
using type = mapnik::value_null;
};
// value_bool
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_bool<T>::value>::type>
{
using type = mapnik::value_bool;
};
// value_integer
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_integer<T>::value>::type>
{
using type = mapnik::value_integer;
};
// value_double
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_double<T>::value>::type>
{
using type = mapnik::value_double;
};
// value_unicode_string
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;
};
class value
{
value_base base_;
@ -890,7 +808,7 @@ public:
template <typename T>
value ( T const& val)
: base_(typename mapnik_value_type<T>::type(val)) {}
: base_(typename detail::mapnik_value_type<T>::type(val)) {}
value (value const& other)
: base_(other.base_) {}

View file

@ -30,6 +30,7 @@
#include <unicode/uversion.h> // for U_NAMESPACE_QUALIFIER
// stl
#include <type_traits>
#include <iosfwd>
#include <cstddef>
@ -121,6 +122,87 @@ inline std::istream& operator>> ( std::istream & s, value_null & )
}
namespace detail {
// to mapnik::value_type conversions traits
template <typename T>
struct is_value_bool
{
bool value = std::is_same<T, bool>::value;
};
template <typename T>
struct is_value_integer
{
bool value = std::is_integral<T>::value && !std::is_same<T, bool>::value;
};
template <typename T>
struct is_value_double
{
bool value = std::is_floating_point<T>::value;
};
template <typename T>
struct is_value_unicode_string
{
bool value = std::is_same<T,mapnik::value_unicode_string>::value;
};
template <typename T>
struct is_value_string
{
bool value = std::is_same<T,std::string>::value;
};
template <typename T>
struct is_value_null
{
bool value = std::is_same<T, value_null>::value;
};
template <typename T, class Enable = void>
struct mapnik_value_type
{
using type = T;
};
// value_null
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_null<T>::value>::type>
{
using type = mapnik::value_null;
};
// value_bool
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_bool<T>::value>::type>
{
using type = mapnik::value_bool;
};
// value_integer
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_integer<T>::value>::type>
{
using type = mapnik::value_integer;
};
// value_double
template <typename T>
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_double<T>::value>::type>
{
using type = mapnik::value_double;
};
// value_unicode_string
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;
};
} // namespace detail
} // namespace mapnik
#endif // MAPNIK_VALUE_TYPES_HPP