first_unsatisfied_index.hpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /*!
  2. @file
  3. Defines `boost::hana::detail::first_unsatisfied_index`.
  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_FIRST_UNSATISFIED_INDEX_HPP
  9. #define BOOST_HANA_DETAIL_FIRST_UNSATISFIED_INDEX_HPP
  10. #include <boost/hana/config.hpp>
  11. #include <boost/hana/integral_constant.hpp>
  12. #include <boost/hana/value.hpp>
  13. #include <utility>
  14. BOOST_HANA_NAMESPACE_BEGIN namespace detail {
  15. template <bool, typename Pred, typename ...Xs>
  16. struct find_tail_size;
  17. template <typename Pred, typename X, typename ...Xs>
  18. struct find_tail_size<true, Pred, X, Xs...> {
  19. static constexpr int value = find_tail_size<
  20. static_cast<bool>(hana::value<decltype(std::declval<Pred>()(std::declval<X>()))>()),
  21. Pred, Xs...
  22. >::value;
  23. };
  24. template <typename Pred>
  25. struct find_tail_size<true, Pred> {
  26. static constexpr int value = -1;
  27. };
  28. template <typename Pred, typename ...Xs>
  29. struct find_tail_size<false, Pred, Xs...> {
  30. static constexpr int value = sizeof...(Xs);
  31. };
  32. //! @ingroup group-details
  33. //! Returns the index of the first element which does not satisfy `Pred`,
  34. //! or `sizeof...(Xs)` if no such element exists.
  35. template <typename Pred>
  36. struct first_unsatisfied_index {
  37. template <typename ...Xs>
  38. constexpr auto operator()(Xs&& ...) const {
  39. return hana::size_c<
  40. sizeof...(Xs) - 1 - find_tail_size<true, Pred, Xs&&...>::value
  41. >;
  42. }
  43. };
  44. } BOOST_HANA_NAMESPACE_END
  45. #endif // !BOOST_HANA_DETAIL_FIRST_UNSATISFIED_INDEX_HPP