]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*! |
2 | @file | |
3 | Defines `boost::hana::detail::type_at`. | |
4 | ||
5 | @copyright Louis Dionne 2013-2016 | |
6 | Distributed under the Boost Software License, Version 1.0. | |
7 | (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | |
8 | */ | |
9 | ||
10 | #ifndef BOOST_HANA_DETAIL_TYPE_AT_HPP | |
11 | #define BOOST_HANA_DETAIL_TYPE_AT_HPP | |
12 | ||
13 | #include <boost/hana/config.hpp> | |
14 | ||
15 | #include <cstddef> | |
16 | #include <utility> | |
17 | ||
18 | ||
19 | // If possible, use an intrinsic provided by Clang | |
20 | #if defined(__has_builtin) | |
21 | # if __has_builtin(__type_pack_element) | |
22 | # define BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC | |
23 | # endif | |
24 | #endif | |
25 | ||
26 | BOOST_HANA_NAMESPACE_BEGIN namespace detail { | |
27 | namespace td { | |
28 | template <std::size_t I, typename T> | |
29 | struct elt { using type = T; }; | |
30 | ||
31 | template <typename Indices, typename ...T> | |
32 | struct indexer; | |
33 | ||
34 | template <std::size_t ...I, typename ...T> | |
35 | struct indexer<std::index_sequence<I...>, T...> | |
36 | : elt<I, T>... | |
37 | { }; | |
38 | ||
39 | template <std::size_t I, typename T> | |
40 | elt<I, T> get_elt(elt<I, T> const&); | |
41 | } | |
42 | ||
43 | //! @ingroup group-details | |
44 | //! Classic MPL-style metafunction returning the nth element of a type | |
45 | //! parameter pack. | |
46 | template <std::size_t n, typename ...T> | |
47 | struct type_at { | |
48 | #if defined(BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC) | |
49 | using type = __type_pack_element<n, T...>; | |
50 | #else | |
51 | using Indexer = td::indexer<std::make_index_sequence<sizeof...(T)>, T...>; | |
52 | using type = typename decltype(td::get_elt<n>(Indexer{}))::type; | |
53 | #endif | |
54 | }; | |
55 | } BOOST_HANA_NAMESPACE_END | |
56 | ||
57 | #endif // !BOOST_HANA_DETAIL_TYPE_AT_HPP |