From 8103682fdbb9aa830509e71676e9762eccc3e463 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sat, 12 Nov 2011 20:24:42 +0900 Subject: [PATCH] =?UTF-8?q?sprout/variant/apply=5Fvisitor.hpp=20=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sprout/tuple/tuple.hpp | 4 ++-- sprout/variant.hpp | 2 ++ sprout/variant/apply_visitor.hpp | 18 ++++++++++++++++++ sprout/variant/static_visitor.hpp | 14 ++++++++++++++ sprout/variant/variant.hpp | 30 +++++++++++++++++++++++++++++- 5 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 sprout/variant/apply_visitor.hpp create mode 100644 sprout/variant/static_visitor.hpp diff --git a/sprout/tuple/tuple.hpp b/sprout/tuple/tuple.hpp index 1661c759..aa5c1242 100644 --- a/sprout/tuple/tuple.hpp +++ b/sprout/tuple/tuple.hpp @@ -61,7 +61,7 @@ namespace sprout { }; template - class tuple_impl; + class tuple_impl; template class tuple_impl { public: @@ -200,7 +200,7 @@ namespace sprout { // // tuple // - template + template class tuple : public sprout::tuples::detail::tuple_impl<0, Types...> { diff --git a/sprout/variant.hpp b/sprout/variant.hpp index c9c77ab2..754eccf5 100644 --- a/sprout/variant.hpp +++ b/sprout/variant.hpp @@ -4,5 +4,7 @@ #include #include #include +#include +#include #endif // #ifndef SPROUT_VARIANT_HPP diff --git a/sprout/variant/apply_visitor.hpp b/sprout/variant/apply_visitor.hpp new file mode 100644 index 00000000..05e84b32 --- /dev/null +++ b/sprout/variant/apply_visitor.hpp @@ -0,0 +1,18 @@ +#ifndef SPROUT_VARIANT_APPLY_VISITOR_HPP +#define SPROUT_VARIANT_APPLY_VISITOR_HPP + +#include +#include + +namespace sprout { + template + SPROUT_CONSTEXPR inline typename Visitor::result_type apply_visitor( + Visitor&& visitor, + Visitable&& visitable + ) + { + return sprout::forward(visitable).apply_visitor(sprout::forward(visitor)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_VARIANT_APPLY_VISITOR_HPP diff --git a/sprout/variant/static_visitor.hpp b/sprout/variant/static_visitor.hpp new file mode 100644 index 00000000..265c13cf --- /dev/null +++ b/sprout/variant/static_visitor.hpp @@ -0,0 +1,14 @@ +#ifndef SPROUT_VARIANT_STATIC_VISITOR_HPP +#define SPROUT_VARIANT_STATIC_VISITOR_HPP + +#include + +namespace sprout { + template + class static_visitor { + public: + typedef R result_type; + }; +} // namespace sprout + +#endif // #ifndef SPROUT_VARIANT_STATIC_VISITOR_HPP diff --git a/sprout/variant/variant.hpp b/sprout/variant/variant.hpp index 3439b47c..c4272b3c 100644 --- a/sprout/variant/variant.hpp +++ b/sprout/variant/variant.hpp @@ -114,6 +114,23 @@ namespace sprout { : output(os, t, which) ; } + template + 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 + 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(v)(sprout::tuples::get(sprout::forward(t))) + : visit(sprout::forward(t), sprout::forward(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& operator<<(std::basic_ostream& lhs, variant const& rhs) { return output<0>(lhs, rhs.tuple_, rhs.which_); } + // get support template SPROUT_CONSTEXPR typename std::enable_if< sprout::types::find_index::value != sizeof...(Types), @@ -197,6 +215,15 @@ namespace sprout { : (throw std::domain_error("variant<>: bad get"), sprout::tuples::get::value>(tuple_)) ; } + // visitation support + template + SPROUT_CONSTEXPR typename Visitor::result_type apply_visitor(Visitor&& visitor) const { + return visit(tuple_, sprout::forward(visitor), which_); + } + template + typename Visitor::result_type apply_visitor(Visitor&& visitor) { + return visit(tuple_, sprout::forward(visitor), which_); + } }; // @@ -217,6 +244,7 @@ namespace std { // tuple_size // template + struct tuple_size > : public std::tuple_size::tuple_tyep> {};