update variant to the latest version

This commit is contained in:
artemp 2015-01-07 10:51:59 +01:00
parent b0b89e76d1
commit b28aadcf41

View file

@ -35,7 +35,8 @@
#include <string>
#include "recursive_wrapper.hpp"
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector.hpp> // spirit support
#ifdef _MSC_VER
// http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
@ -59,7 +60,19 @@
// translates to 100
#define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION)
namespace mapnik { namespace util { namespace detail {
namespace mapnik { namespace util {
// static visitor
template <typename R = void>
struct static_visitor
{
using result_type = R;
protected:
static_visitor() {}
~static_visitor() {}
};
namespace detail {
static constexpr std::size_t invalid_value = std::size_t(-1);
@ -134,18 +147,38 @@ struct select_type<0, T, Types...>
using type = T;
};
} // namespace detail
// static visitor
template <typename R = void>
struct static_visitor
template <typename T, typename R = void>
struct enable_if_type { using type = R; };
template <typename F, typename V, typename Enable = void>
struct result_of_unary_visit
{
using result_type = R;
protected:
static_visitor() {}
~static_visitor() {}
using type = typename std::result_of<F(V&)>::type;
};
template <typename F, typename V>
struct result_of_unary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
{
using type = typename F::result_type;
};
template <typename F, typename V, class Enable = void>
struct result_of_binary_visit
{
using type = typename std::result_of<F(V&,V&)>::type;
};
template <typename F, typename V>
struct result_of_binary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
{
using type = typename F::result_type;
};
} // namespace detail
template <std::size_t arg1, std::size_t ... others>
struct static_max;
@ -244,13 +277,13 @@ struct unwrapper<recursive_wrapper<T>>
};
template <typename F, typename V, typename...Types>
template <typename F, typename V, typename R, typename...Types>
struct dispatcher;
template <typename F, typename V, typename T, typename...Types>
struct dispatcher<F, V, T, Types...>
template <typename F, typename V, typename R, typename T, typename...Types>
struct dispatcher<F, V, R, T, Types...>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const& v, F f)
{
if (v.get_type_index() == sizeof...(Types))
@ -259,7 +292,7 @@ struct dispatcher<F, V, T, Types...>
}
else
{
return dispatcher<F, V, Types...>::apply_const(v, f);
return dispatcher<F, V, R, Types...>::apply_const(v, f);
}
}
@ -271,15 +304,15 @@ struct dispatcher<F, V, T, Types...>
}
else
{
return dispatcher<F, V, Types...>::apply(v, f);
return dispatcher<F, V, R, Types...>::apply(v, f);
}
}
};
template<typename F, typename V>
struct dispatcher<F, V>
template<typename F, typename V, typename R>
struct dispatcher<F, V, R>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const&, F)
{
throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name());
@ -292,13 +325,13 @@ struct dispatcher<F, V>
};
template <typename F, typename V, typename T, typename...Types>
template <typename F, typename V, typename R, typename T, typename...Types>
struct binary_dispatcher_rhs;
template <typename F, typename V, typename T0, typename T1, typename...Types>
struct binary_dispatcher_rhs<F, V, T0, T1, Types...>
template <typename F, typename V, typename R, typename T0, typename T1, typename...Types>
struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
{
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
@ -308,7 +341,7 @@ struct binary_dispatcher_rhs<F, V, T0, T1, Types...>
}
else
{
return binary_dispatcher_rhs<F, V, T0, Types...>::apply_const(lhs, rhs, f);
return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, f);
}
}
@ -321,16 +354,16 @@ struct binary_dispatcher_rhs<F, V, T0, T1, Types...>
}
else
{
return binary_dispatcher_rhs<F, V, T0, Types...>::apply(lhs, rhs, f);
return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply(lhs, rhs, f);
}
}
};
template<typename F, typename V, typename T>
struct binary_dispatcher_rhs<F, V, T>
template<typename F, typename V, typename R, typename T>
struct binary_dispatcher_rhs<F, V, R, T>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
{
throw std::runtime_error("binary dispatch: FAIL");
@ -342,13 +375,13 @@ struct binary_dispatcher_rhs<F, V, T>
};
template <typename F, typename V, typename T, typename...Types>
template <typename F, typename V, typename R, typename T, typename...Types>
struct binary_dispatcher_lhs;
template <typename F, typename V, typename T0, typename T1, typename...Types>
struct binary_dispatcher_lhs<F, V, T0, T1, Types...>
template <typename F, typename V, typename R, typename T0, typename T1, typename...Types>
struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
{
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
@ -357,7 +390,7 @@ struct binary_dispatcher_lhs<F, V, T0, T1, Types...>
}
else
{
return binary_dispatcher_lhs<F, V, T0, Types...>::apply_const(lhs, rhs, f);
return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, f);
}
}
@ -369,16 +402,16 @@ struct binary_dispatcher_lhs<F, V, T0, T1, Types...>
}
else
{
return binary_dispatcher_lhs<F, V, T0, Types...>::apply(lhs, rhs, f);
return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply(lhs, rhs, f);
}
}
};
template<typename F, typename V, typename T>
struct binary_dispatcher_lhs<F, V, T>
template<typename F, typename V, typename R, typename T>
struct binary_dispatcher_lhs<F, V, R, T>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
{
throw std::runtime_error("binary dispatch: FAIL");
@ -390,13 +423,13 @@ struct binary_dispatcher_lhs<F, V, T>
}
};
template <typename F, typename V, typename...Types>
template <typename F, typename V, typename R, typename...Types>
struct binary_dispatcher;
template <typename F, typename V, typename T, typename...Types>
struct binary_dispatcher<F, V, T, Types...>
template <typename F, typename V, typename R, typename T, typename...Types>
struct binary_dispatcher<F, V, R, T, Types...>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const& v0, V const& v1, F f)
{
if (v0.get_type_index() == sizeof...(Types))
@ -407,14 +440,14 @@ struct binary_dispatcher<F, V, T, Types...>
}
else
{
return binary_dispatcher_rhs<F, V, T, Types...>::apply_const(v0, v1, f);
return binary_dispatcher_rhs<F, V, R, T, Types...>::apply_const(v0, v1, f);
}
}
else if (v1.get_type_index() == sizeof...(Types))
{
return binary_dispatcher_lhs<F, V, T, Types...>::apply_const(v0, v1, f);
return binary_dispatcher_lhs<F, V, R, T, Types...>::apply_const(v0, v1, f);
}
return binary_dispatcher<F, V, Types...>::apply_const(v0, v1, f);
return binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, f);
}
VARIANT_INLINE static result_type apply(V & v0, V & v1, F f)
@ -427,21 +460,21 @@ struct binary_dispatcher<F, V, T, Types...>
}
else
{
return binary_dispatcher_rhs<F, V, T, Types...>::apply(v0, v1, f);
return binary_dispatcher_rhs<F, V, R, T, Types...>::apply(v0, v1, f);
}
}
else if (v1.get_type_index() == sizeof...(Types))
{
return binary_dispatcher_lhs<F, V, T, Types...>::apply(v0, v1, f);
return binary_dispatcher_lhs<F, V, R, T, Types...>::apply(v0, v1, f);
}
return binary_dispatcher<F, V, Types...>::apply(v0, v1, f);
return binary_dispatcher<F, V, R, Types...>::apply(v0, v1, f);
}
};
template<typename F, typename V>
struct binary_dispatcher<F, V>
template<typename F, typename V, typename R>
struct binary_dispatcher<F, V, R>
{
using result_type = typename F::result_type;
using result_type = R;
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
{
throw std::runtime_error("binary dispatch: FAIL");
@ -473,7 +506,7 @@ struct less_comp
};
template <typename Variant, typename Comp>
class comparer : public static_visitor<bool>
class comparer
{
public:
explicit comparer(Variant const& lhs) noexcept
@ -492,7 +525,7 @@ private:
// operator<< helper
template <typename Out>
class printer : public static_visitor<>
class printer
{
public:
explicit printer(Out & out)
@ -528,9 +561,11 @@ private:
data_type data;
public:
// tell spirit that this is an adapted variant
struct adapted_variant_tag;
using types = boost::mpl::vector<Types...>;
VARIANT_INLINE variant()
: type_index(sizeof...(Types) - 1)
{
@ -540,6 +575,7 @@ public:
VARIANT_INLINE variant(no_init)
: type_index(detail::invalid_value) {}
// http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
template <typename T, class = typename std::enable_if<
detail::is_valid_type<typename std::remove_reference<T>::type, Types...>::value>::type>
VARIANT_INLINE variant(T && val) noexcept
@ -649,17 +685,23 @@ public:
template <typename F, typename V>
auto VARIANT_INLINE
static visit(V const& v, F f)
-> decltype(detail::dispatcher<F, V, Types...>::apply_const(v, f))
-> decltype(detail::dispatcher<F, V,
typename detail::result_of_unary_visit<F,
typename detail::select_type<0, Types...>::type>::type, Types...>::apply_const(v, f))
{
return detail::dispatcher<F, V, Types...>::apply_const(v, f);
using R = typename detail::result_of_unary_visit<F, typename detail::select_type<0, Types...>::type>::type;
return detail::dispatcher<F, V, R, Types...>::apply_const(v, f);
}
// non-const
template <typename F, typename V>
auto VARIANT_INLINE
static visit(V & v, F f)
-> decltype(detail::dispatcher<F, V, Types...>::apply(v, f))
-> decltype(detail::dispatcher<F, V,
typename detail::result_of_unary_visit<F,
typename detail::select_type<0, Types...>::type>::type, Types...>::apply(v, f))
{
return detail::dispatcher<F, V, Types...>::apply(v, f);
using R = typename detail::result_of_unary_visit<F, typename detail::select_type<0, Types...>::type>::type;
return detail::dispatcher<F, V, R, Types...>::apply(v, f);
}
// binary
@ -667,17 +709,23 @@ public:
template <typename F, typename V>
auto VARIANT_INLINE
static binary_visit(V const& v0, V const& v1, F f)
-> decltype(detail::binary_dispatcher<F, V, Types...>::apply_const(v0, v1, f))
-> decltype(detail::binary_dispatcher<F, V,
typename detail::result_of_binary_visit<F,
typename detail::select_type<0, Types...>::type>::type, Types...>::apply_const(v0, v1, f))
{
return detail::binary_dispatcher<F, V, Types...>::apply_const(v0, v1, f);
using R = typename detail::result_of_binary_visit<F,typename detail::select_type<0, Types...>::type>::type;
return detail::binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, f);
}
// non-const
template <typename F, typename V>
auto VARIANT_INLINE
static binary_visit(V& v0, V& v1, F f)
-> decltype(detail::binary_dispatcher<F, V, Types...>::apply(v0, v1, f))
-> decltype(detail::binary_dispatcher<F, V,
typename detail::result_of_binary_visit<F,
typename detail::select_type<0, Types...>::type>::type, Types...>::apply(v0, v1, f))
{
return detail::binary_dispatcher<F, V, Types...>::apply(v0, v1, f);
using R = typename detail::result_of_binary_visit<F,typename detail::select_type<0, Types...>::type>::type;
return detail::binary_dispatcher<F, V, R, Types...>::apply(v0, v1, f);
}
~variant() noexcept
@ -749,6 +797,7 @@ ResultType const& get(T const& var)
return var.template get<ResultType>();
}
// operator<<
template <typename charT, typename traits, typename... Types>
VARIANT_INLINE std::basic_ostream<charT, traits>&