From a7def70996e7172cb6e5d01134d38fa2e479ecd7 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 11 Jul 2013 03:05:49 +0900 Subject: [PATCH] add types::upper_bound_index meta-function --- sprout/type/algorithm.hpp | 1 + sprout/type/algorithm/lower_bound_index.hpp | 48 +++++++++++----- sprout/type/algorithm/upper_bound_index.hpp | 61 +++++++++++++++++++++ 3 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 sprout/type/algorithm/upper_bound_index.hpp diff --git a/sprout/type/algorithm.hpp b/sprout/type/algorithm.hpp index 32f0390d..55298a9f 100644 --- a/sprout/type/algorithm.hpp +++ b/sprout/type/algorithm.hpp @@ -5,5 +5,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_TYPE_ALGORITHM_HPP diff --git a/sprout/type/algorithm/lower_bound_index.hpp b/sprout/type/algorithm/lower_bound_index.hpp index 0f21056d..2f915a03 100644 --- a/sprout/type/algorithm/lower_bound_index.hpp +++ b/sprout/type/algorithm/lower_bound_index.hpp @@ -10,30 +10,50 @@ namespace sprout { namespace types { namespace detail { - template - struct lower_bound_index_impl - : public std::integral_constant - {}; - template - struct lower_bound_index_impl< - I, Tuple, T, Compare, - typename std::enable_if<(I < sprout::tuples::tuple_size::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 + {}; + 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::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::type, T>::type::value, - sprout::types::detail::lower_bound_index_impl, - std::integral_constant + Compare::template apply::type, T>::type::value, + sprout::types::detail::lower_bound_index_impl, + sprout::types::detail::lower_bound_index_impl >::type {}; } // namespace detail // // lower_bound_index // - // TODO: O(log N) implementation - // template struct lower_bound_index - : public sprout::types::detail::lower_bound_index_impl<0, Tuple, T, Compare> + : public sprout::types::detail::lower_bound_index_impl::value> {}; } // namespace types } // namespace sprout diff --git a/sprout/type/algorithm/upper_bound_index.hpp b/sprout/type/algorithm/upper_bound_index.hpp new file mode 100644 index 00000000..f77e0053 --- /dev/null +++ b/sprout/type/algorithm/upper_bound_index.hpp @@ -0,0 +1,61 @@ +#ifndef SPROUT_TYPE_ALGORITHM_UPPER_BOUND_INDEX_HPP +#define SPROUT_TYPE_ALGORITHM_UPPER_BOUND_INDEX_HPP + +#include +#include +#include +#include +#include + +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 + {}; + 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::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::type>::type::value, + sprout::types::detail::upper_bound_index_impl, + sprout::types::detail::upper_bound_index_impl + >::type + {}; + } // namespace detail + // + // upper_bound_index + // + template + struct upper_bound_index + : public sprout::types::detail::upper_bound_index_impl::value> + {}; + } // namespace types +} // namespace sprout + +#endif // #ifndef SPROUT_TYPE_ALGORITHM_UPPER_BOUND_INDEX_HPP