sprout/variant/variant.hpp 修正

sprout/weed/attr_cnv/bitwise_or.hpp (variant に対応)
This commit is contained in:
bolero-MURAKAMI 2012-01-11 01:34:37 +09:00
parent e731c3caf4
commit e11da4400b
4 changed files with 71 additions and 12 deletions

View file

@ -1,7 +1,9 @@
#ifndef SPROUT_VARIANT_GET_HPP
#define SPROUT_VARIANT_GET_HPP
#include <cstddef>
#include <sprout/config.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/variant/variant.hpp>
namespace sprout {
@ -16,6 +18,20 @@ namespace sprout {
U& get(sprout::variant<Types...>& operand) {
return operand.template get<U>();
}
template<std::size_t I, typename... Types>
SPROUT_CONSTEXPR typename sprout::tuples::tuple_element<
I,
sprout::variant<Types...>
>::type const& get(sprout::variant<Types...> const& operand) {
return operand.template get_at<I>();
}
template<std::size_t I, typename... Types>
typename sprout::tuples::tuple_element<
I,
sprout::variant<Types...>
>::type& get(sprout::variant<Types...>& operand) {
return operand.template get_at<I>();
}
} // namespace sprout
#endif // #ifndef SPROUT_VARIANT_GET_HPP

View file

@ -4,11 +4,13 @@
#include <cstddef>
#include <utility>
#include <stdexcept>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/utility/operation.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/tuple/functions.hpp>
#include <sprout/type/type_tuple.hpp>
#include <sprout/type/algorithm/find_index.hpp>
namespace sprout {
@ -17,6 +19,7 @@ namespace sprout {
class variant_impl {
protected:
typedef sprout::tuples::tuple<Types...> tuple_type;;
typedef sprout::types::type_tuple<typename std::decay<Types>::type...> uncvref_tuple_type;;
private:
template<typename T, std::ptrdiff_t... Indexes>
static SPROUT_CONSTEXPR tuple_type init(T&& operand, sprout::index_tuple<Indexes...>) {
@ -60,6 +63,7 @@ namespace sprout {
{
private:
typedef sprout::detail::variant_impl<Types...> 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<typename T>
SPROUT_CONSTEXPR variant(T&& operand)
: impl_type(sprout::forward<T>(operand), sprout::types::find_index<tuple_type, T>())
: impl_type(
sprout::forward<T>(operand),
sprout::types::find_index<uncvref_tuple_type, typename std::decay<T>::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<std::size_t I>
SPROUT_CONSTEXPR typename std::enable_if<
I != sizeof...(Types),
typename sprout::tuples::tuple_element<I, tuple_type>::type const&
>::type get_at() const {
return I == static_cast<std::size_t>(which_)
? sprout::tuples::get<I>(tuple_)
: (throw std::domain_error("variant<>: bad get"), sprout::tuples::get<I>(tuple_))
;
}
template<std::size_t I>
typename std::enable_if<
I != sizeof...(Types),
typename sprout::tuples::tuple_element<I, tuple_type>::type&
>::type get_at() {
return I == which_
? sprout::tuples::get<I>(tuple_)
: (throw std::domain_error("variant<>: bad get"), sprout::tuples::get<I>(tuple_))
;
}
template<typename U>
SPROUT_CONSTEXPR typename std::enable_if<
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
U const&
>::type get() const {
return sprout::types::find_index<tuple_type, U>::value == static_cast<std::size_t>(which_)
? sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_)
: (throw std::domain_error("variant<>: bad get"), sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_))
;
return get_at<sprout::types::find_index<tuple_type, U>::value>();
}
template<typename U>
typename std::enable_if<
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
U&
>::type get() {
return sprout::types::find_index<tuple_type, U>::value == which_
? sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_)
: (throw std::domain_error("variant<>: bad get"), sprout::tuples::get<sprout::types::find_index<tuple_type, U>::value>(tuple_))
;
return get_at<sprout::types::find_index<tuple_type, U>::value>();
}
// visitation support
template<typename Visitor>
@ -245,9 +266,8 @@ namespace std {
// tuple_size
//
template<typename... Types>
struct tuple_size<sprout::variant<Types...> >
: public std::tuple_size<typename sprout::variant<Types...>::tuple_tyep>
: public std::tuple_size<typename sprout::variant<Types...>::tuple_type>
{};
//
@ -255,7 +275,7 @@ namespace std {
//
template<std::size_t I, typename... Types>
struct tuple_element<I, sprout::variant<Types...> >
: public std::tuple_element<I, typename sprout::variant<Types...>::tuple_tyep>
: public std::tuple_element<I, typename sprout::variant<Types...>::tuple_type>
{};
} // namespace std

View file

@ -13,6 +13,7 @@
#include <sprout/weed/detail/is_elem_and_container.hpp>
#include <sprout/weed/detail/is_both_tuple.hpp>
#include <sprout/weed/detail/is_same_elem.hpp>
#include <sprout/weed/detail/is_different_elem.hpp>
#include <sprout/weed/detail/is_elem_and_unused.hpp>
#include <sprout/weed/detail/is_unused_and_elem.hpp>
#include <sprout/weed/detail/is_both_unused.hpp>
@ -88,6 +89,14 @@ namespace sprout {
>::type bitwise_or(X const& x) {
return x;
}
// V | W -> variant<V, W>
template<typename T, typename U, typename X>
SPROUT_CONSTEXPR inline typename std::enable_if<
sprout::weed::detail::is_different_elem<T, U>::value,
typename sprout::weed::attr_cnv::result_of::bitwise_or<T, U>::type
>::type bitwise_or(X const& x) {
return typename sprout::weed::attr_cnv::result_of::bitwise_or<T, U>::type(x);
}
// V | unused -> container<V, 1>
template<typename T, typename U, typename X>
SPROUT_CONSTEXPR inline typename std::enable_if<

View file

@ -6,6 +6,7 @@
#include <sprout/string.hpp>
#include <sprout/array.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/variant/variant.hpp>
#include <sprout/weed/unused.hpp>
#include <sprout/weed/traits/type/is_char_type.hpp>
#include <sprout/weed/detail/is_same_container.hpp>
@ -13,6 +14,7 @@
#include <sprout/weed/detail/is_elem_and_container.hpp>
#include <sprout/weed/detail/is_both_tuple.hpp>
#include <sprout/weed/detail/is_same_elem.hpp>
#include <sprout/weed/detail/is_different_elem.hpp>
#include <sprout/weed/detail/is_elem_and_unused.hpp>
#include <sprout/weed/detail/is_unused_and_elem.hpp>
#include <sprout/weed/detail/is_both_unused.hpp>
@ -102,6 +104,18 @@ namespace sprout {
public:
typedef T type;
};
// V | W -> variant<V, W>
template<typename T, typename U>
struct bitwise_or<
T,
U,
typename std::enable_if<
sprout::weed::detail::is_different_elem<T, U>::value
>::type
> {
public:
typedef sprout::variant<T, U> type;
};
// V | unused -> container<V, 1>
template<typename T, typename U>
struct bitwise_or<