add static_variant_visitor

This commit is contained in:
bolero-MURAKAMI 2012-12-20 00:09:05 +09:00
parent f01382e3e5
commit fce61f0def
6 changed files with 103 additions and 41 deletions

View file

@ -7,6 +7,8 @@
#include <sprout/variant/tuple.hpp>
#include <sprout/variant/get.hpp>
#include <sprout/variant/static_visitor.hpp>
#include <sprout/variant/static_variant_visitor.hpp>
#include <sprout/variant/visitor_result.hpp>
#include <sprout/variant/apply_visitor.hpp>
#endif // #ifndef SPROUT_VARIANT_HPP

View file

@ -4,41 +4,9 @@
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/type_traits/has_xxx.hpp>
#include <sprout/variant/visitor_result.hpp>
namespace sprout {
//
// has_visitor_result
//
SPROUT_HAS_XXX_TEMPLATE_DEF_LAZY(visitor_result);
namespace detail {
template<typename Visitor, typename Visitable, typename = void>
struct visitor_result_impl;
template<typename Visitor, typename Visitable>
struct visitor_result_impl<
Visitor, Visitable,
typename std::enable_if<sprout::has_visitor_result<Visitable>::value>::type
>
: public Visitable::template visitor_result<Visitor, Visitable>
{};
template<typename Visitor, typename Visitable>
struct visitor_result_impl<
Visitor, Visitable,
typename std::enable_if<!sprout::has_visitor_result<Visitable>::value>::type
> {
public:
typedef typename Visitor::result_type type;
};
} // namespace detail
//
// visitor_result
//
template<typename Visitor, typename Visitable>
struct visitor_result
: public sprout::detail::visitor_result_impl<Visitor, Visitable>
{};
//
// apply_visitor
//

View file

@ -0,0 +1,22 @@
#ifndef SPROUT_VARIANT_STATIC_VARIANT_VISITOR_HPP
#define SPROUT_VARIANT_STATIC_VARIANT_VISITOR_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/variant/variant.hpp>
namespace sprout {
//
// static_variant_visitor
//
class static_variant_visitor {
public:
template<typename... Types>
struct visitor_result {
public:
typedef sprout::variant<typename std::decay<Types>::type...> type;
};
};
} // namespace sprout
#endif // #ifndef SPROUT_VARIANT_STATIC_VARIANT_VISITOR_HPP

View file

@ -4,6 +4,9 @@
#include <sprout/config.hpp>
namespace sprout {
//
// static_visitor
//
template<typename R = void>
class static_visitor {
public:

View file

@ -16,6 +16,7 @@
#include <sprout/type/algorithm/find_index.hpp>
#include <sprout/functional/type_traits/has_type.hpp>
#include <sprout/functional/type_traits/weak_result_type.hpp>
#include <sprout/variant/visitor_result.hpp>
namespace sprout {
template<typename... Types>
@ -75,6 +76,15 @@ namespace sprout {
public:
typedef typename impl_type::tuple_type tuple_type;
private:
template<typename Visitor, typename Tuple, typename IndexTuple>
struct visitor_result_impl_2;
template<typename Visitor, typename Tuple, sprout::index_t... Indexes>
struct visitor_result_impl_2<Visitor, Tuple, sprout::index_tuple<Indexes...> > {
public:
typedef typename Visitor::template visitor_result<
decltype((std::declval<Visitor>())(sprout::tuples::get<Indexes>(std::declval<Tuple>())))...
>::type type;
};
template<typename Visitor, typename Tuple, typename IndexTuple>
struct visitor_result_impl_1;
template<typename Visitor, typename Tuple, sprout::index_t... Indexes>
@ -91,19 +101,35 @@ namespace sprout {
template<typename Visitor, typename Tuple>
struct visitor_result_impl<
Visitor, Tuple,
typename std::enable_if<!sprout::has_result_type<sprout::weak_result_type<Visitor> >::value>::type
>
: public visitor_result_impl_1<Visitor, Tuple, typename sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::type>
{};
template<typename Visitor, typename Tuple>
struct visitor_result_impl<
Visitor, Tuple,
typename std::enable_if<sprout::has_result_type<sprout::weak_result_type<Visitor> >::value>::type
typename std::enable_if<
sprout::has_result_type<sprout::weak_result_type<Visitor> >::value
>::type
> {
public:
typedef typename sprout::weak_result_type<Visitor>::result_type type;
};
template<typename Visitor, typename Tuple>
struct visitor_result_impl<
Visitor, Tuple,
typename std::enable_if<
sprout::has_visitor_result<Visitor>::value
&& !sprout::has_result_type<sprout::weak_result_type<Visitor> >::value
>::type
>
: public visitor_result_impl_2<Visitor, Tuple, typename sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::type>
{};
template<typename Visitor, typename Tuple>
struct visitor_result_impl<
Visitor, Tuple,
typename std::enable_if<
!sprout::has_visitor_result<Visitor>::value
&& !sprout::has_result_type<sprout::weak_result_type<Visitor> >::value
>::type
>
: public visitor_result_impl_1<Visitor, Tuple, typename sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::type>
{};
public:
// visitation support
template<typename Visitor, typename Visitable>
struct visitor_result
: public visitor_result_impl<Visitor, typename Visitable::tuple_type>

View file

@ -0,0 +1,41 @@
#ifndef SPROUT_VARIANT_VISITOR_RESULT_HPP
#define SPROUT_VARIANT_VISITOR_RESULT_HPP
#include <sprout/config.hpp>
#include <sprout/type_traits/has_xxx.hpp>
namespace sprout {
//
// has_visitor_result
//
SPROUT_HAS_XXX_TEMPLATE_DEF_LAZY(visitor_result);
namespace detail {
template<typename Visitor, typename Visitable, typename = void>
struct visitor_result_impl;
template<typename Visitor, typename Visitable>
struct visitor_result_impl<
Visitor, Visitable,
typename std::enable_if<sprout::has_visitor_result<Visitable>::value>::type
>
: public Visitable::template visitor_result<Visitor, Visitable>
{};
template<typename Visitor, typename Visitable>
struct visitor_result_impl<
Visitor, Visitable,
typename std::enable_if<!sprout::has_visitor_result<Visitable>::value>::type
> {
public:
typedef typename Visitor::result_type type;
};
} // namespace detail
//
// visitor_result
//
template<typename Visitor, typename Visitable>
struct visitor_result
: public sprout::detail::visitor_result_impl<Visitor, Visitable>
{};
} // namespace sprout
#endif // #ifndef SPROUT_VARIANT_VISITOR_RESULT_HPP