mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
sprout/variant/variant.hpp 修正
sprout/weed/attr_cnv/bitwise_or.hpp (variant に対応)
This commit is contained in:
parent
e731c3caf4
commit
e11da4400b
4 changed files with 71 additions and 12 deletions
|
@ -1,7 +1,9 @@
|
||||||
#ifndef SPROUT_VARIANT_GET_HPP
|
#ifndef SPROUT_VARIANT_GET_HPP
|
||||||
#define SPROUT_VARIANT_GET_HPP
|
#define SPROUT_VARIANT_GET_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/tuple/tuple.hpp>
|
||||||
#include <sprout/variant/variant.hpp>
|
#include <sprout/variant/variant.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
@ -16,6 +18,20 @@ namespace sprout {
|
||||||
U& get(sprout::variant<Types...>& operand) {
|
U& get(sprout::variant<Types...>& operand) {
|
||||||
return operand.template get<U>();
|
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
|
} // namespace sprout
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_VARIANT_GET_HPP
|
#endif // #ifndef SPROUT_VARIANT_GET_HPP
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <type_traits>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/index_tuple.hpp>
|
#include <sprout/index_tuple.hpp>
|
||||||
#include <sprout/utility/operation.hpp>
|
#include <sprout/utility/operation.hpp>
|
||||||
#include <sprout/tuple/tuple.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
#include <sprout/tuple/functions.hpp>
|
#include <sprout/tuple/functions.hpp>
|
||||||
|
#include <sprout/type/type_tuple.hpp>
|
||||||
#include <sprout/type/algorithm/find_index.hpp>
|
#include <sprout/type/algorithm/find_index.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
@ -17,6 +19,7 @@ namespace sprout {
|
||||||
class variant_impl {
|
class variant_impl {
|
||||||
protected:
|
protected:
|
||||||
typedef sprout::tuples::tuple<Types...> tuple_type;;
|
typedef sprout::tuples::tuple<Types...> tuple_type;;
|
||||||
|
typedef sprout::types::type_tuple<typename std::decay<Types>::type...> uncvref_tuple_type;;
|
||||||
private:
|
private:
|
||||||
template<typename T, std::ptrdiff_t... Indexes>
|
template<typename T, std::ptrdiff_t... Indexes>
|
||||||
static SPROUT_CONSTEXPR tuple_type init(T&& operand, sprout::index_tuple<Indexes...>) {
|
static SPROUT_CONSTEXPR tuple_type init(T&& operand, sprout::index_tuple<Indexes...>) {
|
||||||
|
@ -60,6 +63,7 @@ namespace sprout {
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef sprout::detail::variant_impl<Types...> impl_type;;
|
typedef sprout::detail::variant_impl<Types...> impl_type;;
|
||||||
|
typedef typename impl_type::uncvref_tuple_type uncvref_tuple_type;;
|
||||||
public:
|
public:
|
||||||
typedef typename impl_type::tuple_type tuple_type;;
|
typedef typename impl_type::tuple_type tuple_type;;
|
||||||
private:
|
private:
|
||||||
|
@ -143,7 +147,10 @@ namespace sprout {
|
||||||
variant(variant&&) = default;
|
variant(variant&&) = default;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
SPROUT_CONSTEXPR variant(T&& operand)
|
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
|
// modifiers
|
||||||
void swap(variant& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(impl_type::swap(other))) {
|
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_);
|
return output<0>(lhs, rhs.tuple_, rhs.which_);
|
||||||
}
|
}
|
||||||
// get support
|
// 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>
|
template<typename U>
|
||||||
SPROUT_CONSTEXPR typename std::enable_if<
|
SPROUT_CONSTEXPR typename std::enable_if<
|
||||||
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
|
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
|
||||||
U const&
|
U const&
|
||||||
>::type get() const {
|
>::type get() const {
|
||||||
return sprout::types::find_index<tuple_type, U>::value == static_cast<std::size_t>(which_)
|
return get_at<sprout::types::find_index<tuple_type, U>::value>();
|
||||||
? 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_))
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
|
sprout::types::find_index<tuple_type, U>::value != sizeof...(Types),
|
||||||
U&
|
U&
|
||||||
>::type get() {
|
>::type get() {
|
||||||
return sprout::types::find_index<tuple_type, U>::value == which_
|
return get_at<sprout::types::find_index<tuple_type, U>::value>();
|
||||||
? 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_))
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
// visitation support
|
// visitation support
|
||||||
template<typename Visitor>
|
template<typename Visitor>
|
||||||
|
@ -245,9 +266,8 @@ namespace std {
|
||||||
// tuple_size
|
// tuple_size
|
||||||
//
|
//
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
|
|
||||||
struct tuple_size<sprout::variant<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>
|
template<std::size_t I, typename... Types>
|
||||||
struct tuple_element<I, sprout::variant<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
|
} // namespace std
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <sprout/weed/detail/is_elem_and_container.hpp>
|
#include <sprout/weed/detail/is_elem_and_container.hpp>
|
||||||
#include <sprout/weed/detail/is_both_tuple.hpp>
|
#include <sprout/weed/detail/is_both_tuple.hpp>
|
||||||
#include <sprout/weed/detail/is_same_elem.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_elem_and_unused.hpp>
|
||||||
#include <sprout/weed/detail/is_unused_and_elem.hpp>
|
#include <sprout/weed/detail/is_unused_and_elem.hpp>
|
||||||
#include <sprout/weed/detail/is_both_unused.hpp>
|
#include <sprout/weed/detail/is_both_unused.hpp>
|
||||||
|
@ -88,6 +89,14 @@ namespace sprout {
|
||||||
>::type bitwise_or(X const& x) {
|
>::type bitwise_or(X const& x) {
|
||||||
return 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>
|
// V | unused -> container<V, 1>
|
||||||
template<typename T, typename U, typename X>
|
template<typename T, typename U, typename X>
|
||||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <sprout/string.hpp>
|
#include <sprout/string.hpp>
|
||||||
#include <sprout/array.hpp>
|
#include <sprout/array.hpp>
|
||||||
#include <sprout/tuple/tuple.hpp>
|
#include <sprout/tuple/tuple.hpp>
|
||||||
|
#include <sprout/variant/variant.hpp>
|
||||||
#include <sprout/weed/unused.hpp>
|
#include <sprout/weed/unused.hpp>
|
||||||
#include <sprout/weed/traits/type/is_char_type.hpp>
|
#include <sprout/weed/traits/type/is_char_type.hpp>
|
||||||
#include <sprout/weed/detail/is_same_container.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_elem_and_container.hpp>
|
||||||
#include <sprout/weed/detail/is_both_tuple.hpp>
|
#include <sprout/weed/detail/is_both_tuple.hpp>
|
||||||
#include <sprout/weed/detail/is_same_elem.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_elem_and_unused.hpp>
|
||||||
#include <sprout/weed/detail/is_unused_and_elem.hpp>
|
#include <sprout/weed/detail/is_unused_and_elem.hpp>
|
||||||
#include <sprout/weed/detail/is_both_unused.hpp>
|
#include <sprout/weed/detail/is_both_unused.hpp>
|
||||||
|
@ -102,6 +104,18 @@ namespace sprout {
|
||||||
public:
|
public:
|
||||||
typedef T type;
|
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>
|
// V | unused -> container<V, 1>
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
struct bitwise_or<
|
struct bitwise_or<
|
||||||
|
|
Loading…
Reference in a new issue