2
0
mirror of https://github.com/boostorg/hana.git synced 2026-02-19 14:32:11 +00:00

Add a more efficient at_index algorithm.

This commit is contained in:
Louis Dionne
2014-05-26 14:21:29 -04:00
parent d85eb7ccb2
commit eda7ea303a
5 changed files with 100 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
/*!
* @file
* Defines `boost::hana::detail::at_index::best`.
*
*
* @copyright Louis Dionne 2014
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.md or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_HANA_DETAIL_AT_INDEX_BEST_HPP
#define BOOST_HANA_DETAIL_AT_INDEX_BEST_HPP
#include <boost/hana/detail/at_index/overload_resolution.hpp>
namespace boost { namespace hana { namespace detail { namespace at_index {
BOOST_HANA_CONSTEXPR_LAMBDA auto best = overload_resolution;
}}}}
#endif // !BOOST_HANA_DETAIL_AT_INDEX_BEST_HPP

View File

@@ -0,0 +1,36 @@
/*!
* @file
* Defines `boost::hana::detail::at_index::overload_resolution`.
*
*
* @copyright Louis Dionne 2014
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.md or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_HANA_DETAIL_AT_INDEX_OVERLOAD_RESOLUTION_HPP
#define BOOST_HANA_DETAIL_AT_INDEX_OVERLOAD_RESOLUTION_HPP
#include <boost/hana/detail/constexpr.hpp>
#include <boost/hana/detail/integer_sequence.hpp>
#include <cstddef>
namespace boost { namespace hana { namespace detail { namespace at_index {
struct eat_pod { eat_pod(...) { } };
template <std::size_t ...ignore>
constexpr auto overload_impl(index_sequence<ignore...>) {
return [](decltype(ignore, eat_pod{})..., auto nth, ...) {
return nth;
};
}
BOOST_HANA_CONSTEXPR_LAMBDA auto overload_resolution = [](auto n, auto ...xs) {
return overload_impl(make_index_sequence<n>{})(xs...);
};
}}}} // end namespace boost::hana::detail::at_index
#endif // !BOOST_HANA_DETAIL_AT_INDEX_OVERLOAD_RESOLUTION_HPP

View File

@@ -13,6 +13,7 @@
#define BOOST_HANA_LIST_HPP
#include <boost/hana/comparable.hpp>
#include <boost/hana/detail/at_index/best.hpp>
#include <boost/hana/detail/comparable_from_iterable.hpp>
#include <boost/hana/detail/constexpr.hpp>
#include <boost/hana/detail/foldable_from_iterable.hpp>
@@ -68,6 +69,13 @@ namespace boost { namespace hana {
return size_t<sizeof...(xs)>;
});
}
template <typename Index>
static constexpr auto at_impl(Index n, List<Storage> xs) {
return xs.into([=](auto ...xs) {
return detail::at_index::best(n, xs...);
});
}
};
template <typename Storage>

View File

@@ -19,6 +19,7 @@ boost_hana_add_test(adapted.std_integer_sequence.iterable)
boost_hana_add_test(adapted.std_tuple.functor)
boost_hana_add_test(adapted.std_tuple.iterable)
boost_hana_add_test(detail.at_index)
boost_hana_add_test(detail.comparable_from_iterable)
boost_hana_add_test(detail.foldable_from_iterable)
boost_hana_add_test(detail.integer_sequence)

33
test/detail/at_index.cpp Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright Louis Dionne 2014
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.md or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/hana/detail/at_index/overload_resolution.hpp>
#include <boost/hana/detail/static_assert.hpp>
#include <boost/hana/integral.hpp>
using namespace boost::hana;
template <typename At>
constexpr void test_at(At at) {
BOOST_HANA_STATIC_ASSERT(at(size_t<0>, int_<0>) == int_<0>);
BOOST_HANA_STATIC_ASSERT(at(size_t<0>, int_<0>, int_<1>) == int_<0>);
BOOST_HANA_STATIC_ASSERT(at(size_t<0>, int_<0>, int_<1>, int_<2>) == int_<0>);
BOOST_HANA_STATIC_ASSERT(at(size_t<1>, int_<0>, int_<1>) == int_<1>);
BOOST_HANA_STATIC_ASSERT(at(size_t<1>, int_<0>, int_<1>, int_<2>) == int_<1>);
BOOST_HANA_STATIC_ASSERT(at(size_t<2>, int_<0>, int_<1>, int_<2>) == int_<2>);
BOOST_HANA_STATIC_ASSERT(at(size_t<0>, 0) == 0);
BOOST_HANA_STATIC_ASSERT(at(size_t<1>, 0, '1') == '1');
BOOST_HANA_STATIC_ASSERT(at(size_t<2>, 0, '1', "2") == "2");
}
int main() {
test_at(detail::at_index::overload_resolution);
}