Skip to content

Commit

Permalink
+ add static_visitor requirement to ease return_type deduction
Browse files Browse the repository at this point in the history
```c++
struct MyVisitor : util::static_visitor<int> {...};
```
  • Loading branch information
artemp committed May 15, 2014
1 parent 4927450 commit 80d999a
Showing 1 changed file with 33 additions and 27 deletions.
60 changes: 33 additions & 27 deletions variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ struct is_valid_type<T> : std::false_type {};

}

// static visitor
template <typename R = void>
struct static_visitor
{
typedef R result_type;
protected:
static_visitor() {}
~static_visitor() {}
};


template <std::size_t arg1, std::size_t ... others>
struct static_max;

Expand Down Expand Up @@ -129,8 +140,7 @@ struct dispatcher;
template <typename F, typename V, typename T, typename...Types>
struct dispatcher<F,V,T,Types...>
{
typedef typename std::result_of<F(V const&)>::type result_type;

typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const& v, F f)
{
if (v.get_type_id() == sizeof...(Types))
Expand All @@ -147,8 +157,7 @@ struct dispatcher<F,V,T,Types...>
template<typename F,typename V>
struct dispatcher<F,V>
{
typedef typename std::result_of<F(V const&)>::type result_type;

typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const&, F)
{
throw std::runtime_error("unary dispatch: FAIL");
Expand All @@ -163,7 +172,7 @@ struct binary_dispatcher_rhs;
template <typename F, typename V, typename T0, typename T1, typename...Types>
struct binary_dispatcher_rhs<F,V,T0,T1,Types...>
{
typedef typename std::result_of<F(V const&, V const&)>::type result_type;
typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const& lhs, V const& rhs, F f)
{
if (rhs.get_type_id() == sizeof...(Types)) // call binary functor
Expand All @@ -180,8 +189,7 @@ struct binary_dispatcher_rhs<F,V,T0,T1,Types...>
template<typename F,typename V, typename T>
struct binary_dispatcher_rhs<F,V,T>
{
typedef typename std::result_of<F(V const&, V const&)>::type result_type;

typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const&, V const&, F)
{
throw std::runtime_error("binary dispatch: FAIL");
Expand All @@ -195,8 +203,8 @@ struct binary_dispatcher_lhs;
template <typename F, typename V, typename T0, typename T1, typename...Types>
struct binary_dispatcher_lhs<F,V,T0,T1,Types...>
{
typedef typename std::result_of<F(V const&, V const&)>::type binary_result_type;
VARIANT_INLINE static binary_result_type apply(V const& lhs, V const& rhs, F f)
typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const& lhs, V const& rhs, F f)
{
if (lhs.get_type_id() == sizeof...(Types)) // call binary functor
{
Expand All @@ -212,8 +220,7 @@ struct binary_dispatcher_lhs<F,V,T0,T1,Types...>
template<typename F,typename V, typename T>
struct binary_dispatcher_lhs<F,V,T>
{
typedef typename std::result_of<F(V const&, V const&)>::type result_type;

typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const&, V const&, F)
{
throw std::runtime_error("binary dispatch: FAIL");
Expand All @@ -226,9 +233,8 @@ struct binary_dispatcher;
template <typename F, typename V, typename T, typename...Types>
struct binary_dispatcher<F,V,T,Types...>
{
typedef typename std::result_of<F(V const&, V const&)>::type binary_result_type;

VARIANT_INLINE static binary_result_type apply(V const& v0, V const& v1, F f)
typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const& v0, V const& v1, F f)
{
if (v0.get_type_id() == sizeof...(Types))
{
Expand All @@ -252,9 +258,8 @@ struct binary_dispatcher<F,V,T,Types...>
template<typename F,typename V>
struct binary_dispatcher<F,V>
{
typedef typename std::result_of<F(V const&, V const&)>::type binary_result_type;

VARIANT_INLINE static binary_result_type apply(V const&, V const&, F)
typedef typename F::result_type result_type;
VARIANT_INLINE static result_type apply(V const&, V const&, F)
{
throw std::runtime_error("binary dispatch: FAIL");
}
Expand All @@ -280,7 +285,7 @@ struct less_comp
};

template <typename Variant, typename Comp>
class comparer
class comparer : public static_visitor<bool>
{
public:
explicit comparer(Variant const& lhs) noexcept
Expand All @@ -299,7 +304,7 @@ class comparer

// operator<< helper
template <typename Out>
class printer
class printer : public static_visitor<>
{
public:
explicit printer(Out & out)
Expand Down Expand Up @@ -432,15 +437,18 @@ class variant
// visitor
// unary
template <typename F, typename V>
typename std::result_of<F(V const&)>::type
VARIANT_INLINE static visit(V const& v, F f)
auto VARIANT_INLINE
static visit(V const& v, F f)
-> decltype(detail::dispatcher<F, V, Types...>::apply(v, f))
{
return detail::dispatcher<F, V, Types...>::apply(v, f);
}

// binary
template <typename F, typename V>
typename std::result_of<F(V const&, V const& )>::type
VARIANT_INLINE static binary_visit(V const& v0, V const& v1, F f)
auto VARIANT_INLINE
static binary_visit(V const& v0, V const& v1, F f)
-> decltype(detail::binary_dispatcher<F, V, Types...>::apply(v0, v1, f))
{
return detail::binary_dispatcher<F, V, Types...>::apply(v0, v1, f);
}
Expand Down Expand Up @@ -474,16 +482,14 @@ class variant

// unary visitor interface
template <typename V, typename F>
typename std::result_of<F(V const&)>::type
VARIANT_INLINE static apply_visitor(V const& v, F f)
auto VARIANT_INLINE static apply_visitor(V const& v, F f) -> decltype(V::visit(v,f))
{
return V::visit(v,f);
}

// binary visitor interface
template <typename V, typename F>
typename std::result_of<F(V const&, V const&)>::type
VARIANT_INLINE static apply_visitor(V const& v0, V const& v1, F f)
auto VARIANT_INLINE static apply_visitor(V const& v0, V const& v1, F f) -> decltype(V::binary_visit(v0, v1, f))
{
return V::binary_visit(v0, v1, f);
}
Expand Down

0 comments on commit 80d999a

Please sign in to comment.