reimplementation template recursion depth order: types::find_index, find_index__if

This commit is contained in:
bolero-MURAKAMI 2015-04-10 17:48:51 +09:00
parent 9bcc98cb29
commit 530bc92d0c
3 changed files with 112 additions and 66 deletions

View file

@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2011-2015 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_ALGORITHM_DETAIL_FIND_INDEX_RESULT_HPP
#define SPROUT_TYPE_ALGORITHM_DETAIL_FIND_INDEX_RESULT_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type_traits/integral_constant.hpp>
namespace sprout {
namespace types {
namespace detail {
template<typename Tuple, std::size_t Found>
struct find_index_result
: public sprout::integral_constant<std::size_t, Found>
{
public:
typedef sprout::bool_constant<Found != sprout::types::tuple_size<Tuple>::value> found;
};
} // namespace detail
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_DETAIL_FIND_INDEX_RESULT_HPP

View file

@ -12,48 +12,56 @@
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/algorithm/detail/find_index_result.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename T, std::size_t I,
bool Valid = (I != sprout::types::tuple_size<Tuple>::value),
typename Enable = void
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found,
bool C0 = (Found != First), bool C1 = (Pivot == 0)
>
struct find_index_impl;
template<typename Tuple, typename T, std::size_t I>
struct find_index_impl<
Tuple, T, I, false,
void
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found,
bool C1
>
: public sprout::integral_constant<std::size_t, I>
{
public:
typedef sprout::false_type found;
};
template<typename Tuple, typename T, std::size_t I>
struct find_index_impl<
Tuple, T, I, true,
typename std::enable_if<
std::is_same<typename sprout::types::tuple_element<I, Tuple>::type, T>::value
>::type
struct find_index_impl<Tuple, T, First, Last, Pivot, Found, true, C1>
: public sprout::types::detail::find_index_result<Tuple, Found>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found
>
: public sprout::integral_constant<std::size_t, I>
{
public:
typedef sprout::true_type found;
typedef typename sprout::types::tuple_element<I, Tuple>::type element;
};
template<typename Tuple, typename T, std::size_t I>
struct find_index_impl<
Tuple, T, I, true,
typename std::enable_if<
!std::is_same<typename sprout::types::tuple_element<I, Tuple>::type, T>::value
>::type
struct find_index_impl<Tuple, T, First, Last, Pivot, Found, false, true>
: public sprout::types::detail::find_index_result<
Tuple, (std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value ? First : Last)
>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found
>
: public sprout::types::detail::find_index_impl<Tuple, T, I + 1>
struct find_index_impl<Tuple, T, First, Last, Pivot, Found, false, false>
: public sprout::types::detail::find_index_impl<
Tuple, T, First + Pivot, Last,
(Last - First - Pivot) / 2,
sprout::types::detail::find_index_impl<
Tuple, T, First, First + Pivot,
Pivot / 2,
First
>::value
>
{};
template<typename Tuple, typename T, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct find_index
: public sprout::types::detail::find_index_impl<Tuple, T, 0, Size, Size / 2, 0>
{};
template<typename Tuple, typename T>
struct find_index<Tuple, T, 0>
: public sprout::types::detail::find_index_result<Tuple, 0>
{};
} // namespace detail
//
@ -61,7 +69,7 @@ namespace sprout {
//
template<typename Tuple, typename T>
struct find_index
: public sprout::types::detail::find_index_impl<Tuple, T, 0>
: public sprout::types::detail::find_index<Tuple, T>
{};
#if SPROUT_USE_TEMPLATE_ALIASES

View file

@ -13,48 +13,56 @@
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type/apply.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/algorithm/detail/find_index_result.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename Predicate, std::size_t I,
bool Valid = (I != sprout::types::tuple_size<Tuple>::value),
typename Enable = void
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found,
bool C0 = (Found != First), bool C1 = (Pivot == 0)
>
struct find_index_if_impl;
template<typename Tuple, typename Predicate, std::size_t I>
struct find_index_if_impl<
Tuple, Predicate, I, false,
void
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found,
bool C1
>
: public sprout::integral_constant<std::size_t, I>
{
public:
typedef sprout::false_type found;
};
template<typename Tuple, typename Predicate, std::size_t I>
struct find_index_if_impl<
Tuple, Predicate, I, true,
typename std::enable_if<
sprout::types::apply<Predicate, typename sprout::types::tuple_element<I, Tuple>::type>::type::value
>::type
struct find_index_if_impl<Tuple, Predicate, First, Last, Pivot, Found, true, C1>
: public sprout::types::detail::find_index_result<Tuple, Found>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found
>
: public sprout::integral_constant<std::size_t, I>
{
public:
typedef sprout::true_type found;
typedef typename sprout::types::tuple_element<I, Tuple>::type element;
};
template<typename Tuple, typename Predicate, std::size_t I>
struct find_index_if_impl<
Tuple, Predicate, I, true,
typename std::enable_if<
!sprout::types::apply<Predicate, typename sprout::types::tuple_element<I, Tuple>::type>::type::value
>::type
struct find_index_if_impl<Tuple, Predicate, First, Last, Pivot, Found, false, true>
: public sprout::types::detail::find_index_result<
Tuple, (sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value ? First : Last)
>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot, std::size_t Found
>
: public sprout::types::detail::find_index_if_impl<Tuple, Predicate, I + 1>
struct find_index_if_impl<Tuple, Predicate, First, Last, Pivot, Found, false, false>
: public sprout::types::detail::find_index_if_impl<
Tuple, Predicate, First + Pivot, Last,
(Last - First - Pivot) / 2,
sprout::types::detail::find_index_if_impl<
Tuple, Predicate, First, First + Pivot,
Pivot / 2,
First
>::value
>
{};
template<typename Tuple, typename Predicate, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct find_index_if
: public sprout::types::detail::find_index_if_impl<Tuple, Predicate, 0, Size, Size / 2, 0>
{};
template<typename Tuple, typename Predicate>
struct find_index_if<Tuple, Predicate, 0>
: public sprout::types::detail::find_index_result<Tuple, 0>
{};
} // namespace detail
//
@ -62,7 +70,7 @@ namespace sprout {
//
template<typename Tuple, typename Predicate>
struct find_index_if
: public sprout::types::detail::find_index_if_impl<Tuple, Predicate, 0>
: public sprout::types::detail::find_index_if<Tuple, Predicate>
{};
#if SPROUT_USE_TEMPLATE_ALIASES