mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-02-11 10:03:59 +00:00
reimplementation template recursion depth order: types::find_index, find_index__if
This commit is contained in:
parent
9bcc98cb29
commit
530bc92d0c
3 changed files with 112 additions and 66 deletions
30
sprout/type/algorithm/detail/find_index_result.hpp
Normal file
30
sprout/type/algorithm/detail/find_index_result.hpp
Normal 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
|
|
@ -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)
|
||||
>
|
||||
: public sprout::types::detail::find_index_impl<Tuple, T, I + 1>
|
||||
{};
|
||||
template<
|
||||
typename Tuple, typename T, std::size_t First, std::size_t Last,
|
||||
std::size_t Pivot, std::size_t Found
|
||||
>
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
>
|
||||
: public sprout::types::detail::find_index_if_impl<Tuple, Predicate, I + 1>
|
||||
{};
|
||||
template<
|
||||
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
|
||||
std::size_t Pivot, std::size_t Found
|
||||
>
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue