index_if.hpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /*!
  2. @file
  3. Defines `boost::hana::detail::index_if`.
  4. @copyright Louis Dionne 2013-2017
  5. @copyright Jason Rice 2017
  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. #ifndef BOOST_HANA_DETAIL_INDEX_IF_HPP
  10. #define BOOST_HANA_DETAIL_INDEX_IF_HPP
  11. #include <boost/hana/config.hpp>
  12. #include <boost/hana/detail/decay.hpp>
  13. #include <boost/hana/integral_constant.hpp>
  14. #include <boost/hana/optional.hpp>
  15. #include <cstddef>
  16. #include <utility>
  17. BOOST_HANA_NAMESPACE_BEGIN namespace detail {
  18. template <std::size_t i, std::size_t N, bool Done>
  19. struct index_if_helper;
  20. template <std::size_t i, std::size_t N>
  21. struct index_if_helper<i, N, false> {
  22. template <typename Pred, typename X1, typename ...Xs>
  23. using f = typename index_if_helper<i + 1, N,
  24. static_cast<bool>(detail::decay<decltype(
  25. std::declval<Pred>()(std::declval<X1>()))>::type::value)
  26. >::template f<Pred, Xs...>;
  27. };
  28. template <std::size_t N>
  29. struct index_if_helper<N, N, false> {
  30. template <typename ...>
  31. using f = hana::optional<>;
  32. };
  33. template <std::size_t i, std::size_t N>
  34. struct index_if_helper<i, N, true> {
  35. template <typename ...>
  36. using f = hana::optional<hana::size_t<i - 1>>;
  37. };
  38. template <typename Pred, typename ...Xs>
  39. struct index_if {
  40. using type = typename index_if_helper<0, sizeof...(Xs), false>
  41. ::template f<Pred, Xs...>;
  42. };
  43. } BOOST_HANA_NAMESPACE_END
  44. #endif // !BOOST_HANA_DETAIL_INDEX_IF_HPP