update mapbox::variant
This commit is contained in:
@@ -251,13 +251,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 detail::result_of_unary_visit<F, V>::type;
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& v, F f)
|
||||
{
|
||||
if (v.get_type_index() == sizeof...(Types))
|
||||
@@ -266,7 +266,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,15 +278,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 detail::result_of_unary_visit<F, V>::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());
|
||||
@@ -299,13 +299,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 detail::result_of_binary_visit<F, V>::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
|
||||
@@ -315,7 +315,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,16 +328,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 detail::result_of_binary_visit<F, V>::type;
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
@@ -349,13 +349,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 detail::result_of_binary_visit<F, V>::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
|
||||
@@ -364,7 +364,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,16 +376,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 detail::result_of_binary_visit<F, V>::type;
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
@@ -397,13 +397,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 detail::result_of_binary_visit<F, V>::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))
|
||||
@@ -414,14 +414,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)
|
||||
@@ -434,21 +434,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 detail::result_of_binary_visit<F, V>::type;
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
@@ -497,24 +497,6 @@ private:
|
||||
Variant const& lhs_;
|
||||
};
|
||||
|
||||
// operator<< helper
|
||||
template <typename Out>
|
||||
class printer
|
||||
{
|
||||
public:
|
||||
explicit printer(Out & out)
|
||||
: out_(out) {}
|
||||
printer& operator=(printer const&) = delete;
|
||||
|
||||
// visitor
|
||||
template <typename T>
|
||||
void operator()(T const& operand) const
|
||||
{
|
||||
out_ << operand;
|
||||
}
|
||||
private:
|
||||
Out & out_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -536,7 +518,6 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
|
||||
VARIANT_INLINE variant()
|
||||
: type_index(sizeof...(Types) - 1)
|
||||
{
|
||||
@@ -620,7 +601,8 @@ public:
|
||||
type_index = detail::direct_type<T, Types...>::index;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
// get<T>()
|
||||
template<typename T, typename std::enable_if<(detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
|
||||
VARIANT_INLINE T& get()
|
||||
{
|
||||
if (type_index == detail::direct_type<T, Types...>::index)
|
||||
@@ -629,11 +611,13 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get()");
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<T, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<T, Types...>::index)
|
||||
@@ -642,31 +626,72 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get()");
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
// get<T>() - T stored as recursive_wrapper<T>
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T& get()
|
||||
{
|
||||
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,typename std::enable_if<
|
||||
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
VARIANT_INLINE std::size_t get_type_index() const
|
||||
{
|
||||
return type_index;
|
||||
}
|
||||
|
||||
VARIANT_INLINE int which() const noexcept
|
||||
{
|
||||
return static_cast<int>(sizeof...(Types) - type_index - 1);
|
||||
}
|
||||
|
||||
// visitor
|
||||
// unary
|
||||
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
|
||||
@@ -674,17 +699,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
|
||||
@@ -745,28 +776,18 @@ auto VARIANT_INLINE static apply_visitor(F f, V & v0, V & v1) -> decltype(V::bin
|
||||
|
||||
// getter interface
|
||||
template<typename ResultType, typename T>
|
||||
ResultType & get(T & var)
|
||||
ResultType & get(T & var)
|
||||
{
|
||||
return var.template get<ResultType>();
|
||||
}
|
||||
|
||||
template<typename ResultType, typename T>
|
||||
ResultType const& get(T const& var)
|
||||
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>&
|
||||
operator<< (std::basic_ostream<charT, traits>& out, variant<Types...> const& rhs)
|
||||
{
|
||||
detail::printer<std::basic_ostream<charT, traits>> visitor(out);
|
||||
apply_visitor(visitor, rhs);
|
||||
return out;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPBOX_UTIL_VARIANT_HPP
|
||||
|
||||
41
include/mbgl/util/variant_io.hpp
Normal file
41
include/mbgl/util/variant_io.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef MAPBOX_UTIL_VARIANT_IO_HPP
|
||||
#define MAPBOX_UTIL_VARIANT_IO_HPP
|
||||
|
||||
#include "variant.hpp"
|
||||
|
||||
namespace mapbox { namespace util {
|
||||
|
||||
namespace detail {
|
||||
// operator<< helper
|
||||
template <typename Out>
|
||||
class printer
|
||||
{
|
||||
public:
|
||||
explicit printer(Out & out)
|
||||
: out_(out) {}
|
||||
printer& operator=(printer const&) = delete;
|
||||
|
||||
// visitor
|
||||
template <typename T>
|
||||
void operator()(T const& operand) const
|
||||
{
|
||||
out_ << operand;
|
||||
}
|
||||
private:
|
||||
Out & out_;
|
||||
};
|
||||
}
|
||||
|
||||
// operator<<
|
||||
template <typename charT, typename traits, typename... Types>
|
||||
VARIANT_INLINE std::basic_ostream<charT, traits>&
|
||||
operator<< (std::basic_ostream<charT, traits>& out, variant<Types...> const& rhs)
|
||||
{
|
||||
detail::printer<std::basic_ostream<charT, traits>> visitor(out);
|
||||
apply_visitor(visitor, rhs);
|
||||
return out;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif //MAPBOX_UTIL_VARIANT_IO_HPP
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/map/vector_tile.hpp>
|
||||
#include <mbgl/style/filter_expression_private.hpp>
|
||||
#include <mbgl/util/variant_io.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
Reference in New Issue
Block a user