update variant to the latest version
This commit is contained in:
parent
b0b89e76d1
commit
b28aadcf41
1 changed files with 109 additions and 60 deletions
|
@ -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>&
|
||||
|
|
Loading…
Reference in a new issue