refix tuple_element roder

This commit is contained in:
bolero-MURAKAMI 2013-11-30 10:22:24 +09:00
parent c9610b5ae5
commit 37e5f52e4c
3 changed files with 164 additions and 30 deletions

View file

@ -13,6 +13,7 @@
#include <sprout/type/type_tuple.hpp>
#include <sprout/type/integral_array.hpp>
#include <sprout/type/string.hpp>
#include <sprout/type/uniform_types.hpp>
#include <sprout/type/rebind_types.hpp>
#include <sprout/type/functional.hpp>
#include <sprout/type/algorithm.hpp>

View file

@ -12,6 +12,7 @@
#include <tuple>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple/index_n.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type/iterator.hpp>
#include <sprout/type/iterator/index_iterator.hpp>
@ -51,41 +52,91 @@ namespace sprout {
namespace detail {
template<typename T>
struct tuple_head;
struct head_element;
template<typename Head, typename... Tail>
struct tuple_head<sprout::types::type_tuple<Head, Tail...> >
struct head_element<sprout::types::type_tuple<Head, Tail...> >
: public sprout::identity<Head>
{};
template<std::size_t I, std::size_t N, typename T, typename Enable = void>
struct tuple_skip;
template<std::size_t I, std::size_t N, typename Head, typename... Tail>
struct tuple_skip<
I, N, sprout::types::type_tuple<Head, Tail...>,
typename std::enable_if<(I == 0)>::type
>
: public sprout::identity<sprout::types::type_tuple<Head, Tail...> >
template<typename T>
struct tuple_head;
template<typename Head, typename... Tail>
struct tuple_head<sprout::types::type_tuple<Head, Tail...> >
: public sprout::identity<sprout::types::type_tuple<Head> >
{};
template<std::size_t I, std::size_t N, typename Head, typename... Tail>
struct tuple_skip<
I, N, sprout::types::type_tuple<Head, Tail...>,
typename std::enable_if<(I != 0 && I < N / 2)>::type
>
: public sprout::types::detail::tuple_skip<
I - 1, N / 2 - 1,
sprout::types::type_tuple<Tail...>
>
template<typename T>
struct tuple_tail;
template<typename Head, typename... Tail>
struct tuple_tail<sprout::types::type_tuple<Head, Tail...> >
: public sprout::identity<sprout::types::type_tuple<Tail...> >
{};
template<std::size_t I, std::size_t N, typename Head, typename... Tail>
struct tuple_skip<
I, N, sprout::types::type_tuple<Head, Tail...>,
typename std::enable_if<(I != 0 && I >= N / 2)>::type
>
: public sprout::types::detail::tuple_skip<
I - N / 2, N - N / 2,
typename sprout::types::detail::tuple_skip<N / 2 - 1, N / 2, sprout::types::type_tuple<Tail...> >::type
>
template<sprout::index_t, typename T = void>
struct dummy_index
: sprout::identity<T>
{};
template<typename IndexTuple>
struct tuple_drop_helper;
template<sprout::index_t... Indexes>
struct tuple_drop_helper<sprout::index_tuple<Indexes...> > {
template<typename... Types>
static sprout::types::type_tuple<typename Types::type...>
eval(typename sprout::types::detail::dummy_index<Indexes>::type*..., Types*...);
};
template<std::size_t I, typename T>
struct tuple_drop_impl;
template<std::size_t I, typename... Types>
struct tuple_drop_impl<I, sprout::types::type_tuple<Types...> >
: public sprout::identity<decltype(
sprout::types::detail::tuple_drop_helper<typename sprout::index_n<0, I>::type>::eval(
static_cast<sprout::identity<Types>*>(0)...
)
)>::type
{};
template<std::size_t I, typename T>
struct tuple_drop;
template<std::size_t I, typename... Types>
struct tuple_drop<I, sprout::types::type_tuple<Types...> >
: public sprout::types::detail::tuple_drop_impl<I, sprout::types::type_tuple<Types...> >
{};
// template<std::size_t I, std::size_t N, typename T, typename Enable = void>
// struct tuple_drop_impl;
// template<std::size_t I, std::size_t N, typename Head, typename... Tail>
// struct tuple_drop_impl<
// I, N, sprout::types::type_tuple<Head, Tail...>,
// typename std::enable_if<(I == 0)>::type
// >
// : public sprout::identity<sprout::types::type_tuple<Head, Tail...> >
// {};
// template<std::size_t I, std::size_t N, typename Head, typename... Tail>
// struct tuple_drop_impl<
// I, N, sprout::types::type_tuple<Head, Tail...>,
// typename std::enable_if<(I != 0 && I < N / 2)>::type
// >
// : public sprout::types::detail::tuple_drop_impl<
// I - 1, N / 2 - 1,
// sprout::types::type_tuple<Tail...>
// >
// {};
// template<std::size_t I, std::size_t N, typename Head, typename... Tail>
// struct tuple_drop_impl<
// I, N, sprout::types::type_tuple<Head, Tail...>,
// typename std::enable_if<(I != 0 && I >= N / 2)>::type
// >
// : public sprout::types::detail::tuple_drop_impl<
// I - N / 2, N - N / 2,
// typename sprout::types::detail::tuple_drop_impl<N / 2 - 1, N / 2, sprout::types::type_tuple<Tail...> >::type
// >
// {};
// template<std::size_t I, typename T>
// struct tuple_drop;
// template<std::size_t I, typename... Types>
// struct tuple_drop<I, sprout::types::type_tuple<Types...> >
// : public sprout::types::detail::tuple_drop_impl<I, sizeof...(Types), sprout::types::type_tuple<Types...> >
// {};
} // namespace detail
} // namespace types
@ -111,8 +162,8 @@ namespace std {
//
template<std::size_t I, typename... Types>
struct tuple_element<I, sprout::types::type_tuple<Types...> >
: public sprout::types::detail::tuple_head<
typename sprout::types::detail::tuple_skip<I, sizeof...(Types), sprout::types::type_tuple<Types...> >::type
: public sprout::types::detail::head_element<
typename sprout::types::detail::tuple_drop<I, sprout::types::type_tuple<Types...> >::type
>
{};
#if defined(__clang__)

View file

@ -0,0 +1,82 @@
/*=============================================================================
Copyright (c) 2011-2013 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_TYPE_UNIFORM_TYPES_HPP
#define SPROUT_TYPE_UNIFORM_TYPES_HPP
#include <cstddef>
#include <tuple>
#include <sprout/config.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type/iterator.hpp>
#include <sprout/type/iterator/index_iterator.hpp>
#include <sprout/type/rebind_types.hpp>
#include <sprout/type_traits/integral_constant.hpp>
namespace sprout {
namespace types {
//
// uniform_types
//
template<typename T, std::size_t N>
struct uniform_types {
public:
typedef uniform_types type;
typedef sprout::types::index_iterator<uniform_types, 0> begin;
typedef sprout::types::index_iterator<uniform_types, N> end;
public:
SPROUT_STATIC_CONSTEXPR std::size_t static_size = N;
};
template<typename T, std::size_t N>
SPROUT_CONSTEXPR_OR_CONST std::size_t sprout::types::uniform_types<T, N>::static_size;
//
// rebind_types
//
template<typename T, std::size_t N>
struct rebind_types<sprout::types::uniform_types<T, N> > {
public:
template<typename Head, typename... Tail>
struct apply {
public:
typedef sprout::types::uniform_types<Head, 1 + sizeof...(Tail)> type;
};
};
} // namespace types
using sprout::types::uniform_types;
using sprout::types::rebind_types;
} // namespace sprout
namespace std {
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wmismatched-tags"
#endif
//
// tuple_size
//
template<typename T, std::size_t N>
struct tuple_size<sprout::types::uniform_types<T, N> >
: public sprout::integral_constant<std::size_t, N>
{};
//
// tuple_element
//
template<std::size_t I, typename T, std::size_t N>
struct tuple_element<I, sprout::types::uniform_types<T, N> > {
static_assert(I < N, "tuple_element<>: index out of range");
public:
typedef T type;
};
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
} // namespace std
#endif // #ifndef SPROUT_TYPE_UNIFORM_TYPES_HPP