Commit afbdb170 authored by Dominik Charousset's avatar Dominik Charousset

Enable CAF visit only if used with CAF variants

parent a8c7dd29
...@@ -61,6 +61,21 @@ struct variant_marker_t {}; ...@@ -61,6 +61,21 @@ struct variant_marker_t {};
constexpr variant_marker_t variant_marker = variant_marker_t{}; constexpr variant_marker_t variant_marker = variant_marker_t{};
template <class T>
struct is_variant : std::false_type {};
template <class... Ts>
struct is_variant<variant<Ts...>> : std::true_type {};
template <class... Ts>
struct is_variant<variant<Ts...>&> : std::true_type {};
template <class... Ts>
struct is_variant<const variant<Ts...>&> : std::true_type {};
template <class... Ts>
struct is_variant<const variant<Ts...>&&> : std::true_type {};
template <class T> template <class T>
struct variant_assign_helper { struct variant_assign_helper {
using result_type = void; using result_type = void;
...@@ -83,12 +98,20 @@ struct variant_move_helper { ...@@ -83,12 +98,20 @@ struct variant_move_helper {
} }
}; };
template <class F, class... Ts> template <bool Valid, class F, class... Ts>
struct variant_visit_result { struct variant_visit_result_impl {
using type = using type =
decltype((std::declval<F&>())(std::declval<typename Ts::type0&>()...)); decltype((std::declval<F&>())(std::declval<typename Ts::type0&>()...));
}; };
template <class F, class... Ts>
struct variant_visit_result_impl<false, F, Ts...> {};
template <class F, class... Ts>
struct variant_visit_result
: variant_visit_result_impl<
detail::conjunction<is_variant<Ts>::value...>::value, F, Ts...> {};
template <class F, class... Ts> template <class F, class... Ts>
using variant_visit_result_t = using variant_visit_result_t =
typename variant_visit_result<detail::decay_t<F>, typename variant_visit_result<detail::decay_t<F>,
...@@ -119,21 +142,6 @@ struct is_same_ish ...@@ -119,21 +142,6 @@ struct is_same_ish
is_equal_int_type<T, U> is_equal_int_type<T, U>
>::type { }; >::type { };
template <class T>
struct is_variant : std::false_type {};
template <class... Ts>
struct is_variant<variant<Ts...>> : std::true_type {};
template <class... Ts>
struct is_variant<variant<Ts...>&> : std::true_type {};
template <class... Ts>
struct is_variant<const variant<Ts...>&> : std::true_type {};
template <class... Ts>
struct is_variant<const variant<Ts...>&&> : std::true_type {};
/// A variant represents always a valid value of one of the types `Ts...`. /// A variant represents always a valid value of one of the types `Ts...`.
template <class... Ts> template <class... Ts>
class variant { class variant {
...@@ -395,7 +403,8 @@ const T* get_if(const variant<Us...>* value) { ...@@ -395,7 +403,8 @@ const T* get_if(const variant<Us...>* value) {
/// @relates variant /// @relates variant
template <class Visitor, class Variant, class... Variants, template <class Visitor, class Variant, class... Variants,
class Result = variant_visit_result_t<Visitor, Variant, Variants...>> class Result = variant_visit_result_t<Visitor, Variant, Variants...>>
Result visit(Visitor&& f, Variant&& x, Variants&&... xs) { detail::enable_if_t<is_variant<Variant>::value, Result>
visit(Visitor&& f, Variant&& x, Variants&&... xs) {
return x.template apply<Result>(std::forward<Visitor>(f), return x.template apply<Result>(std::forward<Visitor>(f),
std::forward<Variants>(xs)...); std::forward<Variants>(xs)...);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment