mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add types::upper_bound_index meta-function
This commit is contained in:
parent
9d7d243886
commit
a7def70996
3 changed files with 96 additions and 14 deletions
|
@ -5,5 +5,6 @@
|
|||
#include <sprout/type/algorithm/find_index.hpp>
|
||||
#include <sprout/type/algorithm/find_index_if.hpp>
|
||||
#include <sprout/type/algorithm/lower_bound_index.hpp>
|
||||
#include <sprout/type/algorithm/upper_bound_index.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_TYPE_ALGORITHM_HPP
|
||||
|
|
|
@ -10,30 +10,50 @@
|
|||
namespace sprout {
|
||||
namespace types {
|
||||
namespace detail {
|
||||
template<std::size_t I, typename Tuple, typename T, typename Compare, typename = void>
|
||||
struct lower_bound_index_impl
|
||||
: public std::integral_constant<std::size_t, I>
|
||||
{};
|
||||
template<std::size_t I, typename Tuple, typename T, typename Compare>
|
||||
struct lower_bound_index_impl<
|
||||
I, Tuple, T, Compare,
|
||||
typename std::enable_if<(I < sprout::tuples::tuple_size<Tuple>::value)>::type
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last,
|
||||
std::size_t Distance = (Last - First)
|
||||
>
|
||||
struct lower_bound_index_impl;
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last
|
||||
>
|
||||
struct lower_bound_index_impl<
|
||||
Tuple, T, Compare, First, Last,
|
||||
0
|
||||
>
|
||||
: public std::integral_constant<std::size_t, Last>
|
||||
{};
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last
|
||||
>
|
||||
struct lower_bound_index_impl<
|
||||
Tuple, T, Compare, First, Last,
|
||||
1
|
||||
>
|
||||
: public std::integral_constant<
|
||||
std::size_t,
|
||||
Compare::template apply<typename sprout::types::tuple_element<First, Tuple>::type, T>::type::value ? Last : First
|
||||
>
|
||||
{};
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last,
|
||||
std::size_t Distance
|
||||
>
|
||||
struct lower_bound_index_impl
|
||||
: public std::conditional<
|
||||
Compare::template apply<typename sprout::tuples::tuple_element<I, Tuple>::type, T>::type::value,
|
||||
sprout::types::detail::lower_bound_index_impl<I + 1, Tuple, T, Compare>,
|
||||
std::integral_constant<std::size_t, I>
|
||||
Compare::template apply<typename sprout::types::tuple_element<First + Distance / 2, Tuple>::type, T>::type::value,
|
||||
sprout::types::detail::lower_bound_index_impl<Tuple, T, Compare, First + Distance / 2, Last>,
|
||||
sprout::types::detail::lower_bound_index_impl<Tuple, T, Compare, First, First + Distance / 2>
|
||||
>::type
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// lower_bound_index
|
||||
//
|
||||
// TODO: O(log N) implementation
|
||||
//
|
||||
template<typename Tuple, typename T, typename Compare = sprout::types::less_>
|
||||
struct lower_bound_index
|
||||
: public sprout::types::detail::lower_bound_index_impl<0, Tuple, T, Compare>
|
||||
: public sprout::types::detail::lower_bound_index_impl<Tuple, T, Compare, 0, sprout::types::tuple_size<Tuple>::value>
|
||||
{};
|
||||
} // namespace types
|
||||
} // namespace sprout
|
||||
|
|
61
sprout/type/algorithm/upper_bound_index.hpp
Normal file
61
sprout/type/algorithm/upper_bound_index.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#ifndef SPROUT_TYPE_ALGORITHM_UPPER_BOUND_INDEX_HPP
|
||||
#define SPROUT_TYPE_ALGORITHM_UPPER_BOUND_INDEX_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type/functional/less.hpp>
|
||||
#include <sprout/type/tuple.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace types {
|
||||
namespace detail {
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last,
|
||||
std::size_t Distance = (Last - First)
|
||||
>
|
||||
struct upper_bound_index_impl;
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last
|
||||
>
|
||||
struct upper_bound_index_impl<
|
||||
Tuple, T, Compare, First, Last,
|
||||
0
|
||||
>
|
||||
: public std::integral_constant<std::size_t, Last>
|
||||
{};
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last
|
||||
>
|
||||
struct upper_bound_index_impl<
|
||||
Tuple, T, Compare, First, Last,
|
||||
1
|
||||
>
|
||||
: public std::integral_constant<
|
||||
std::size_t,
|
||||
!Compare::template apply<T, typename sprout::types::tuple_element<First, Tuple>::type>::type::value ? Last : First
|
||||
>
|
||||
{};
|
||||
template<
|
||||
typename Tuple, typename T, typename Compare, std::size_t First, std::size_t Last,
|
||||
std::size_t Distance
|
||||
>
|
||||
struct upper_bound_index_impl
|
||||
: public std::conditional<
|
||||
!Compare::template apply<T, typename sprout::types::tuple_element<First + Distance / 2, Tuple>::type>::type::value,
|
||||
sprout::types::detail::upper_bound_index_impl<Tuple, T, Compare, First + Distance / 2, Last>,
|
||||
sprout::types::detail::upper_bound_index_impl<Tuple, T, Compare, First, First + Distance / 2>
|
||||
>::type
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// upper_bound_index
|
||||
//
|
||||
template<typename Tuple, typename T, typename Compare = sprout::types::less_>
|
||||
struct upper_bound_index
|
||||
: public sprout::types::detail::upper_bound_index_impl<Tuple, T, Compare, 0, sprout::types::tuple_size<Tuple>::value>
|
||||
{};
|
||||
} // namespace types
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_TYPE_ALGORITHM_UPPER_BOUND_INDEX_HPP
|
Loading…
Reference in a new issue