mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
refix tuple_element roder
This commit is contained in:
parent
c9610b5ae5
commit
37e5f52e4c
3 changed files with 164 additions and 30 deletions
|
@ -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>
|
||||
|
|
|
@ -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__)
|
||||
|
|
82
sprout/type/uniform_types.hpp
Normal file
82
sprout/type/uniform_types.hpp
Normal 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
|
Loading…
Reference in a new issue