summaryrefslogtreecommitdiff
path: root/include/mbgl/util
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2015-02-11 11:18:54 -0800
committerKonstantin Käfer <mail@kkaefer.com>2015-03-06 14:40:33 +0100
commit86455585ee9a2be5aed210411605e712eafd98d7 (patch)
treeaf151bfe7c9abe1df1b29b9bd0ad30e1b325b878 /include/mbgl/util
parentfb44fc81bdab09d079ed27e22b86718627ded48b (diff)
downloadqtlocation-mapboxgl-86455585ee9a2be5aed210411605e712eafd98d7.tar.gz
update mapbox::variant
Diffstat (limited to 'include/mbgl/util')
-rw-r--r--include/mbgl/util/variant.hpp187
-rw-r--r--include/mbgl/util/variant_io.hpp41
2 files changed, 145 insertions, 83 deletions
diff --git a/include/mbgl/util/variant.hpp b/include/mbgl/util/variant.hpp
index 411f1918d5..a3cdea63a7 100644
--- a/include/mbgl/util/variant.hpp
+++ b/include/mbgl/util/variant.hpp
@@ -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
diff --git a/include/mbgl/util/variant_io.hpp b/include/mbgl/util/variant_io.hpp
new file mode 100644
index 0000000000..224732d97c
--- /dev/null
+++ b/include/mbgl/util/variant_io.hpp
@@ -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