1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2024-11-12 21:09:01 +00:00

sprout/variant/apply_visitor.hpp 追加

This commit is contained in:
bolero-MURAKAMI 2011-11-12 20:24:42 +09:00
parent 04809933e0
commit 8103682fdb
5 changed files with 65 additions and 3 deletions

View file

@ -61,7 +61,7 @@ namespace sprout {
};
template<std::size_t Index, typename... Types>
class tuple_impl;
class tuple_impl;
template<std::size_t Index>
class tuple_impl<Index> {
public:
@ -200,7 +200,7 @@ namespace sprout {
//
// tuple
//
template<typename... Types>
template<typename... Types>
class tuple
: public sprout::tuples::detail::tuple_impl<0, Types...>
{

View file

@ -4,5 +4,7 @@
#include <sprout/config.hpp>
#include <sprout/variant/variant.hpp>
#include <sprout/variant/get.hpp>
#include <sprout/variant/static_visitor.hpp>
#include <sprout/variant/apply_visitor.hpp>
#endif // #ifndef SPROUT_VARIANT_HPP

View file

@ -0,0 +1,18 @@
#ifndef SPROUT_VARIANT_APPLY_VISITOR_HPP
#define SPROUT_VARIANT_APPLY_VISITOR_HPP
#include <sprout/config.hpp>
#include <sprout/utility/forward.hpp>
namespace sprout {
template<typename Visitor, typename Visitable>
SPROUT_CONSTEXPR inline typename Visitor::result_type apply_visitor(
Visitor&& visitor,
Visitable&& visitable
)
{
return sprout::forward<Visitable>(visitable).apply_visitor(sprout::forward<Visitor>(visitor));
}
} // namespace sprout
#endif // #ifndef SPROUT_VARIANT_APPLY_VISITOR_HPP

View file

@ -0,0 +1,14 @@
#ifndef SPROUT_VARIANT_STATIC_VISITOR_HPP
#define SPROUT_VARIANT_STATIC_VISITOR_HPP
#include <sprout/config.hpp>
namespace sprout {
template<typename R = void>
class static_visitor {
public:
typedef R result_type;
};
} // namespace sprout
#endif // #ifndef SPROUT_VARIANT_STATIC_VISITOR_HPP

View file

@ -114,6 +114,23 @@ namespace sprout {
: output<I + 1>(os, t, which)
;
}
template<int I, typename Tuple, typename Visitor>
static SPROUT_CONSTEXPR typename std::enable_if<
I == sizeof...(Types),
typename Visitor::result_type
>::type visit(Tuple&& t, Visitor&& v, int which) {
return typename Visitor::result_type();
}
template<int I, typename Tuple, typename Visitor>
static SPROUT_CONSTEXPR typename std::enable_if<
I != sizeof...(Types),
typename Visitor::result_type
>::type visit(Tuple&& t, Visitor&& v, int which) {
return I == which
? sprout::forward<Visitor>(v)(sprout::tuples::get<I>(sprout::forward<Tuple>(t)))
: visit<I + 1>(sprout::forward<Tuple>(t), sprout::forward<Visitor>(v), which)
;
}
private:
using impl_type::tuple_;
using impl_type::which_;
@ -149,7 +166,7 @@ namespace sprout {
return which_;
}
SPROUT_CONSTEXPR bool empty() const {
return sizeof...(Types) == 0;
return false;
}
// relational
friend SPROUT_CONSTEXPR bool operator==(variant const& lhs, variant const& rhs) {
@ -177,6 +194,7 @@ namespace sprout {
friend std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& lhs, variant const& rhs) {
return output<0>(lhs, rhs.tuple_, rhs.which_);
}
// get support
template<typename U>
SPROUT_CONSTEXPR typename std::enable_if<
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
@ -197,6 +215,15 @@ namespace sprout {
: (throw std::domain_error("variant<>: bad get"), sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_))
;
}
// visitation support
template<typename Visitor>
SPROUT_CONSTEXPR typename Visitor::result_type apply_visitor(Visitor&& visitor) const {
return visit(tuple_, sprout::forward<Visitor>(visitor), which_);
}
template<typename Visitor>
typename Visitor::result_type apply_visitor(Visitor&& visitor) {
return visit(tuple_, sprout::forward<Visitor>(visitor), which_);
}
};
//
@ -217,6 +244,7 @@ namespace std {
// tuple_size
//
template<typename... Types>
struct tuple_size<sprout::variant<Types...> >
: public std::tuple_size<typename sprout::variant<Types...>::tuple_tyep>
{};