min.hpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*!
  2. @file
  3. Defines `boost::hana::min`.
  4. Copyright Louis Dionne 2013-2022
  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_MIN_HPP
  9. #define BOOST_HANA_MIN_HPP
  10. #include <boost/hana/fwd/min.hpp>
  11. #include <boost/hana/concept/orderable.hpp>
  12. #include <boost/hana/config.hpp>
  13. #include <boost/hana/core/dispatch.hpp>
  14. #include <boost/hana/if.hpp>
  15. #include <boost/hana/less.hpp>
  16. namespace boost { namespace hana {
  17. //! @cond
  18. template <typename X, typename Y>
  19. constexpr decltype(auto) min_t::operator()(X&& x, Y&& y) const {
  20. using T = typename hana::tag_of<X>::type;
  21. using U = typename hana::tag_of<Y>::type;
  22. using Min = BOOST_HANA_DISPATCH_IF(decltype(min_impl<T, U>{}),
  23. hana::Orderable<T>::value &&
  24. hana::Orderable<U>::value
  25. );
  26. #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
  27. static_assert(hana::Orderable<T>::value,
  28. "hana::min(x, y) requires 'x' to be Orderable");
  29. static_assert(hana::Orderable<U>::value,
  30. "hana::min(x, y) requires 'y' to be Orderable");
  31. #endif
  32. return Min::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
  33. }
  34. //! @endcond
  35. template <typename T, typename U, bool condition>
  36. struct min_impl<T, U, when<condition>> : default_ {
  37. template <typename X, typename Y>
  38. static constexpr decltype(auto) apply(X&& x, Y&& y) {
  39. decltype(auto) cond = hana::less(x, y);
  40. return hana::if_(static_cast<decltype(cond)&&>(cond),
  41. static_cast<X&&>(x),
  42. static_cast<Y&&>(y)
  43. );
  44. }
  45. };
  46. }} // end namespace boost::hana
  47. #endif // !BOOST_HANA_MIN_HPP