diff --git a/sprout/variant/get.hpp b/sprout/variant/get.hpp index 99e34800..bfc6024f 100644 --- a/sprout/variant/get.hpp +++ b/sprout/variant/get.hpp @@ -1,7 +1,9 @@ #ifndef SPROUT_VARIANT_GET_HPP #define SPROUT_VARIANT_GET_HPP +#include #include +#include #include namespace sprout { @@ -16,6 +18,20 @@ namespace sprout { U& get(sprout::variant& operand) { return operand.template get(); } + template + SPROUT_CONSTEXPR typename sprout::tuples::tuple_element< + I, + sprout::variant + >::type const& get(sprout::variant const& operand) { + return operand.template get_at(); + } + template + typename sprout::tuples::tuple_element< + I, + sprout::variant + >::type& get(sprout::variant& operand) { + return operand.template get_at(); + } } // namespace sprout #endif // #ifndef SPROUT_VARIANT_GET_HPP diff --git a/sprout/variant/variant.hpp b/sprout/variant/variant.hpp index 9d5274e4..e1f6151a 100644 --- a/sprout/variant/variant.hpp +++ b/sprout/variant/variant.hpp @@ -4,11 +4,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include namespace sprout { @@ -17,6 +19,7 @@ namespace sprout { class variant_impl { protected: typedef sprout::tuples::tuple tuple_type;; + typedef sprout::types::type_tuple::type...> uncvref_tuple_type;; private: template static SPROUT_CONSTEXPR tuple_type init(T&& operand, sprout::index_tuple) { @@ -60,6 +63,7 @@ namespace sprout { { private: typedef sprout::detail::variant_impl impl_type;; + typedef typename impl_type::uncvref_tuple_type uncvref_tuple_type;; public: typedef typename impl_type::tuple_type tuple_type;; private: @@ -143,7 +147,10 @@ namespace sprout { variant(variant&&) = default; template SPROUT_CONSTEXPR variant(T&& operand) - : impl_type(sprout::forward(operand), sprout::types::find_index()) + : impl_type( + sprout::forward(operand), + sprout::types::find_index::type>() + ) {} // modifiers void swap(variant& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(impl_type::swap(other))) { @@ -196,25 +203,39 @@ namespace sprout { return output<0>(lhs, rhs.tuple_, rhs.which_); } // get support + template + SPROUT_CONSTEXPR typename std::enable_if< + I != sizeof...(Types), + typename sprout::tuples::tuple_element::type const& + >::type get_at() const { + return I == static_cast(which_) + ? sprout::tuples::get(tuple_) + : (throw std::domain_error("variant<>: bad get"), sprout::tuples::get(tuple_)) + ; + } + template + typename std::enable_if< + I != sizeof...(Types), + typename sprout::tuples::tuple_element::type& + >::type get_at() { + return I == which_ + ? sprout::tuples::get(tuple_) + : (throw std::domain_error("variant<>: bad get"), sprout::tuples::get(tuple_)) + ; + } template SPROUT_CONSTEXPR typename std::enable_if< sprout::types::find_index::value != sizeof...(Types), U const& >::type get() const { - return sprout::types::find_index::value == static_cast(which_) - ? sprout::tuples::get::value>(tuple_) - : (throw std::domain_error("variant<>: bad get"), sprout::tuples::get::value>(tuple_)) - ; + return get_at::value>(); } template typename std::enable_if< sprout::types::find_index::value != sizeof...(Types), U& >::type get() { - return sprout::types::find_index::value == which_ - ? sprout::tuples::get::value>(tuple_) - : (throw std::domain_error("variant<>: bad get"), sprout::tuples::get::value>(tuple_)) - ; + return get_at::value>(); } // visitation support template @@ -245,9 +266,8 @@ namespace std { // tuple_size // template - struct tuple_size > - : public std::tuple_size::tuple_tyep> + : public std::tuple_size::tuple_type> {}; // @@ -255,7 +275,7 @@ namespace std { // template struct tuple_element > - : public std::tuple_element::tuple_tyep> + : public std::tuple_element::tuple_type> {}; } // namespace std diff --git a/sprout/weed/attr_cnv/bitwise_or.hpp b/sprout/weed/attr_cnv/bitwise_or.hpp index 18b13563..9c69374e 100644 --- a/sprout/weed/attr_cnv/bitwise_or.hpp +++ b/sprout/weed/attr_cnv/bitwise_or.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,14 @@ namespace sprout { >::type bitwise_or(X const& x) { return x; } + // V | W -> variant + template + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::weed::detail::is_different_elem::value, + typename sprout::weed::attr_cnv::result_of::bitwise_or::type + >::type bitwise_or(X const& x) { + return typename sprout::weed::attr_cnv::result_of::bitwise_or::type(x); + } // V | unused -> container template SPROUT_CONSTEXPR inline typename std::enable_if< diff --git a/sprout/weed/attr_cnv/result_of/bitwise_or.hpp b/sprout/weed/attr_cnv/result_of/bitwise_or.hpp index 2bed1931..4009c8d0 100644 --- a/sprout/weed/attr_cnv/result_of/bitwise_or.hpp +++ b/sprout/weed/attr_cnv/result_of/bitwise_or.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +104,18 @@ namespace sprout { public: typedef T type; }; + // V | W -> variant + template + struct bitwise_or< + T, + U, + typename std::enable_if< + sprout::weed::detail::is_different_elem::value + >::type + > { + public: + typedef sprout::variant type; + }; // V | unused -> container template struct bitwise_or<