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/config.hpp>
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
#include <sprout/type/tuple.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 sprout {
|
||||||
namespace types {
|
namespace types {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<
|
template<
|
||||||
typename Tuple, typename T, std::size_t I,
|
typename Tuple, typename T, std::size_t First, std::size_t Last,
|
||||||
bool Valid = (I != sprout::types::tuple_size<Tuple>::value),
|
std::size_t Pivot, std::size_t Found,
|
||||||
typename Enable = void
|
bool C0 = (Found != First), bool C1 = (Pivot == 0)
|
||||||
>
|
>
|
||||||
struct find_index_impl;
|
struct find_index_impl;
|
||||||
template<typename Tuple, typename T, std::size_t I>
|
template<
|
||||||
struct find_index_impl<
|
typename Tuple, typename T, std::size_t First, std::size_t Last,
|
||||||
Tuple, T, I, false,
|
std::size_t Pivot, std::size_t Found,
|
||||||
void
|
bool C1
|
||||||
>
|
>
|
||||||
: public sprout::integral_constant<std::size_t, I>
|
struct find_index_impl<Tuple, T, First, Last, Pivot, Found, true, C1>
|
||||||
{
|
: public sprout::types::detail::find_index_result<Tuple, Found>
|
||||||
public:
|
{};
|
||||||
typedef sprout::false_type found;
|
template<
|
||||||
};
|
typename Tuple, typename T, std::size_t First, std::size_t Last,
|
||||||
template<typename Tuple, typename T, std::size_t I>
|
std::size_t Pivot, std::size_t Found
|
||||||
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
|
|
||||||
>
|
>
|
||||||
: public sprout::integral_constant<std::size_t, I>
|
struct find_index_impl<Tuple, T, First, Last, Pivot, Found, false, true>
|
||||||
{
|
: public sprout::types::detail::find_index_result<
|
||||||
public:
|
Tuple, (std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value ? First : Last)
|
||||||
typedef sprout::true_type found;
|
>
|
||||||
typedef typename sprout::types::tuple_element<I, Tuple>::type element;
|
{};
|
||||||
};
|
template<
|
||||||
template<typename Tuple, typename T, std::size_t I>
|
typename Tuple, typename T, std::size_t First, std::size_t Last,
|
||||||
struct find_index_impl<
|
std::size_t Pivot, std::size_t Found
|
||||||
Tuple, T, I, true,
|
|
||||||
typename std::enable_if<
|
|
||||||
!std::is_same<typename sprout::types::tuple_element<I, Tuple>::type, T>::value
|
|
||||||
>::type
|
|
||||||
>
|
>
|
||||||
: 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
|
} // namespace detail
|
||||||
//
|
//
|
||||||
|
@ -61,7 +69,7 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
template<typename Tuple, typename T>
|
template<typename Tuple, typename T>
|
||||||
struct find_index
|
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
|
#if SPROUT_USE_TEMPLATE_ALIASES
|
||||||
|
|
|
@ -13,48 +13,56 @@
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
#include <sprout/type/apply.hpp>
|
#include <sprout/type/apply.hpp>
|
||||||
#include <sprout/type/tuple.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 sprout {
|
||||||
namespace types {
|
namespace types {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<
|
template<
|
||||||
typename Tuple, typename Predicate, std::size_t I,
|
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
|
||||||
bool Valid = (I != sprout::types::tuple_size<Tuple>::value),
|
std::size_t Pivot, std::size_t Found,
|
||||||
typename Enable = void
|
bool C0 = (Found != First), bool C1 = (Pivot == 0)
|
||||||
>
|
>
|
||||||
struct find_index_if_impl;
|
struct find_index_if_impl;
|
||||||
template<typename Tuple, typename Predicate, std::size_t I>
|
template<
|
||||||
struct find_index_if_impl<
|
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
|
||||||
Tuple, Predicate, I, false,
|
std::size_t Pivot, std::size_t Found,
|
||||||
void
|
bool C1
|
||||||
>
|
>
|
||||||
: public sprout::integral_constant<std::size_t, I>
|
struct find_index_if_impl<Tuple, Predicate, First, Last, Pivot, Found, true, C1>
|
||||||
{
|
: public sprout::types::detail::find_index_result<Tuple, Found>
|
||||||
public:
|
{};
|
||||||
typedef sprout::false_type found;
|
template<
|
||||||
};
|
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
|
||||||
template<typename Tuple, typename Predicate, std::size_t I>
|
std::size_t Pivot, std::size_t Found
|
||||||
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
|
|
||||||
>
|
>
|
||||||
: public sprout::integral_constant<std::size_t, I>
|
struct find_index_if_impl<Tuple, Predicate, First, Last, Pivot, Found, false, true>
|
||||||
{
|
: public sprout::types::detail::find_index_result<
|
||||||
public:
|
Tuple, (sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value ? First : Last)
|
||||||
typedef sprout::true_type found;
|
>
|
||||||
typedef typename sprout::types::tuple_element<I, Tuple>::type element;
|
{};
|
||||||
};
|
template<
|
||||||
template<typename Tuple, typename Predicate, std::size_t I>
|
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
|
||||||
struct find_index_if_impl<
|
std::size_t Pivot, std::size_t Found
|
||||||
Tuple, Predicate, I, true,
|
|
||||||
typename std::enable_if<
|
|
||||||
!sprout::types::apply<Predicate, typename sprout::types::tuple_element<I, Tuple>::type>::type::value
|
|
||||||
>::type
|
|
||||||
>
|
>
|
||||||
: 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
|
} // namespace detail
|
||||||
//
|
//
|
||||||
|
@ -62,7 +70,7 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
template<typename Tuple, typename Predicate>
|
template<typename Tuple, typename Predicate>
|
||||||
struct find_index_if
|
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
|
#if SPROUT_USE_TEMPLATE_ALIASES
|
||||||
|
|
Loading…
Add table
Reference in a new issue