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
|
||||
#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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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<
|
||||
|
|
Loading…
Reference in a new issue