type_at.hpp 1.6 KB

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