From 86455585ee9a2be5aed210411605e712eafd98d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 11 Feb 2015 11:18:54 -0800 Subject: update mapbox::variant --- include/mbgl/util/variant.hpp | 187 +++++++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 83 deletions(-) (limited to 'include/mbgl/util/variant.hpp') 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> }; -template +template struct dispatcher; -template -struct dispatcher +template +struct dispatcher { - using result_type = typename detail::result_of_unary_visit::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 } else { - return dispatcher::apply_const(v, f); + return dispatcher::apply_const(v, f); } } @@ -278,15 +278,15 @@ struct dispatcher } else { - return dispatcher::apply(v, f); + return dispatcher::apply(v, f); } } }; -template -struct dispatcher +template +struct dispatcher { - using result_type = typename detail::result_of_unary_visit::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 }; -template +template struct binary_dispatcher_rhs; -template -struct binary_dispatcher_rhs +template +struct binary_dispatcher_rhs { - using result_type = typename detail::result_of_binary_visit::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 } else { - return binary_dispatcher_rhs::apply_const(lhs, rhs, f); + return binary_dispatcher_rhs::apply_const(lhs, rhs, f); } } @@ -328,16 +328,16 @@ struct binary_dispatcher_rhs } else { - return binary_dispatcher_rhs::apply(lhs, rhs, f); + return binary_dispatcher_rhs::apply(lhs, rhs, f); } } }; -template -struct binary_dispatcher_rhs +template +struct binary_dispatcher_rhs { - using result_type = typename detail::result_of_binary_visit::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 }; -template +template struct binary_dispatcher_lhs; -template -struct binary_dispatcher_lhs +template +struct binary_dispatcher_lhs { - using result_type = typename detail::result_of_binary_visit::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 } else { - return binary_dispatcher_lhs::apply_const(lhs, rhs, f); + return binary_dispatcher_lhs::apply_const(lhs, rhs, f); } } @@ -376,16 +376,16 @@ struct binary_dispatcher_lhs } else { - return binary_dispatcher_lhs::apply(lhs, rhs, f); + return binary_dispatcher_lhs::apply(lhs, rhs, f); } } }; -template -struct binary_dispatcher_lhs +template +struct binary_dispatcher_lhs { - using result_type = typename detail::result_of_binary_visit::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 } }; -template +template struct binary_dispatcher; -template -struct binary_dispatcher +template +struct binary_dispatcher { - using result_type = typename detail::result_of_binary_visit::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 } else { - return binary_dispatcher_rhs::apply_const(v0, v1, f); + return binary_dispatcher_rhs::apply_const(v0, v1, f); } } else if (v1.get_type_index() == sizeof...(Types)) { - return binary_dispatcher_lhs::apply_const(v0, v1, f); + return binary_dispatcher_lhs::apply_const(v0, v1, f); } - return binary_dispatcher::apply_const(v0, v1, f); + return binary_dispatcher::apply_const(v0, v1, f); } VARIANT_INLINE static result_type apply(V & v0, V & v1, F f) @@ -434,21 +434,21 @@ struct binary_dispatcher } else { - return binary_dispatcher_rhs::apply(v0, v1, f); + return binary_dispatcher_rhs::apply(v0, v1, f); } } else if (v1.get_type_index() == sizeof...(Types)) { - return binary_dispatcher_lhs::apply(v0, v1, f); + return binary_dispatcher_lhs::apply(v0, v1, f); } - return binary_dispatcher::apply(v0, v1, f); + return binary_dispatcher::apply(v0, v1, f); } }; -template -struct binary_dispatcher +template +struct binary_dispatcher { - using result_type = typename detail::result_of_binary_visit::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 -class printer -{ -public: - explicit printer(Out & out) - : out_(out) {} - printer& operator=(printer const&) = delete; - -// visitor - template - 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::index; } - template + // get() + template::index != detail::invalid_value)>::type* = nullptr> VARIANT_INLINE T& get() { if (type_index == detail::direct_type::index) @@ -629,11 +611,13 @@ public: } else { - throw std::runtime_error("in get()"); + throw std::runtime_error("in get()"); } } - template + template ::index != detail::invalid_value) + >::type* = nullptr> VARIANT_INLINE T const& get() const { if (type_index == detail::direct_type::index) @@ -642,31 +626,72 @@ public: } else { - throw std::runtime_error("in get()"); + throw std::runtime_error("in get()"); + } + } + + // get() - T stored as recursive_wrapper + template , Types...>::index != detail::invalid_value) + >::type* = nullptr> + VARIANT_INLINE T& get() + { + if (type_index == detail::direct_type, Types...>::index) + { + return (*reinterpret_cast*>(&data)).get(); + } + else + { + throw std::runtime_error("in get()"); } } + template , Types...>::index != detail::invalid_value) + >::type* = nullptr> + VARIANT_INLINE T const& get() const + { + if (type_index == detail::direct_type, Types...>::index) + { + return (*reinterpret_cast const*>(&data)).get(); + } + else + { + throw std::runtime_error("in get()"); + } + } VARIANT_INLINE std::size_t get_type_index() const { return type_index; } + VARIANT_INLINE int which() const noexcept + { + return static_cast(sizeof...(Types) - type_index - 1); + } + // visitor // unary template auto VARIANT_INLINE static visit(V const& v, F f) - -> decltype(detail::dispatcher::apply_const(v, f)) + -> decltype(detail::dispatcher::type>::type, Types...>::apply_const(v, f)) { - return detail::dispatcher::apply_const(v, f); + using R = typename detail::result_of_unary_visit::type>::type; + return detail::dispatcher::apply_const(v, f); } // non-const template auto VARIANT_INLINE static visit(V & v, F f) - -> decltype(detail::dispatcher::apply(v, f)) + -> decltype(detail::dispatcher::type>::type, Types...>::apply(v, f)) { - return detail::dispatcher::apply(v, f); + using R = typename detail::result_of_unary_visit::type>::type; + return detail::dispatcher::apply(v, f); } // binary @@ -674,17 +699,23 @@ public: template auto VARIANT_INLINE static binary_visit(V const& v0, V const& v1, F f) - -> decltype(detail::binary_dispatcher::apply_const(v0, v1, f)) + -> decltype(detail::binary_dispatcher::type>::type, Types...>::apply_const(v0, v1, f)) { - return detail::binary_dispatcher::apply_const(v0, v1, f); + using R = typename detail::result_of_binary_visit::type>::type; + return detail::binary_dispatcher::apply_const(v0, v1, f); } // non-const template auto VARIANT_INLINE static binary_visit(V& v0, V& v1, F f) - -> decltype(detail::binary_dispatcher::apply(v0, v1, f)) + -> decltype(detail::binary_dispatcher::type>::type, Types...>::apply(v0, v1, f)) { - return detail::binary_dispatcher::apply(v0, v1, f); + using R = typename detail::result_of_binary_visit::type>::type; + return detail::binary_dispatcher::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 -ResultType & get(T & var) +ResultType & get(T & var) { return var.template get(); } template -ResultType const& get(T const& var) +ResultType const& get(T const& var) { return var.template get(); } -// operator<< -template -VARIANT_INLINE std::basic_ostream& -operator<< (std::basic_ostream& out, variant const& rhs) -{ - detail::printer> visitor(out); - apply_visitor(visitor, rhs); - return out; -} - }} #endif // MAPBOX_UTIL_VARIANT_HPP -- cgit v1.2.1