function.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
  2. #define BOOST_MP11_FUNCTION_HPP_INCLUDED
  3. // Copyright 2015-2017 Peter Dimov.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. //
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt
  9. #include <boost/mp11/integral.hpp>
  10. #include <boost/mp11/utility.hpp>
  11. #include <boost/mp11/detail/mp_list.hpp>
  12. #include <boost/mp11/detail/mp_count.hpp>
  13. #include <boost/mp11/detail/mp_plus.hpp>
  14. #include <boost/mp11/detail/mp_min_element.hpp>
  15. #include <boost/mp11/detail/mp_void.hpp>
  16. #include <type_traits>
  17. namespace boost
  18. {
  19. namespace mp11
  20. {
  21. // mp_void<T...>
  22. // in detail/mp_void.hpp
  23. // mp_and<T...>
  24. #if BOOST_WORKAROUND( BOOST_MSVC, < 1910 )
  25. namespace detail
  26. {
  27. template<class... T> struct mp_and_impl;
  28. } // namespace detail
  29. template<class... T> using mp_and = mp_to_bool< typename detail::mp_and_impl<T...>::type >;
  30. namespace detail
  31. {
  32. template<> struct mp_and_impl<>
  33. {
  34. using type = mp_true;
  35. };
  36. template<class T> struct mp_and_impl<T>
  37. {
  38. using type = T;
  39. };
  40. template<class T1, class... T> struct mp_and_impl<T1, T...>
  41. {
  42. using type = mp_eval_if< mp_not<T1>, T1, mp_and, T... >;
  43. };
  44. } // namespace detail
  45. #else
  46. namespace detail
  47. {
  48. template<class L, class E = void> struct mp_and_impl
  49. {
  50. using type = mp_false;
  51. };
  52. template<class... T> struct mp_and_impl< mp_list<T...>, mp_void<mp_if<T, void>...> >
  53. {
  54. using type = mp_true;
  55. };
  56. } // namespace detail
  57. template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>::type;
  58. #endif
  59. // mp_all<T...>
  60. #if BOOST_WORKAROUND( BOOST_MSVC, < 1920 ) || BOOST_WORKAROUND( BOOST_GCC, < 80200 )
  61. template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_not >::value == 0 >;
  62. #elif defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
  63. template<class... T> using mp_all = mp_bool<(static_cast<bool>(T::value) && ...)>;
  64. #else
  65. template<class... T> using mp_all = mp_and<mp_to_bool<T>...>;
  66. #endif
  67. // mp_or<T...>
  68. namespace detail
  69. {
  70. template<class... T> struct mp_or_impl;
  71. } // namespace detail
  72. template<class... T> using mp_or = mp_to_bool< typename detail::mp_or_impl<T...>::type >;
  73. namespace detail
  74. {
  75. template<> struct mp_or_impl<>
  76. {
  77. using type = mp_false;
  78. };
  79. template<class T> struct mp_or_impl<T>
  80. {
  81. using type = T;
  82. };
  83. template<class T1, class... T> struct mp_or_impl<T1, T...>
  84. {
  85. using type = mp_eval_if< T1, T1, mp_or, T... >;
  86. };
  87. } // namespace detail
  88. // mp_any<T...>
  89. #if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_WORKAROUND( BOOST_GCC, < 80200 )
  90. template<class... T> using mp_any = mp_bool<(static_cast<bool>(T::value) || ...)>;
  91. #else
  92. template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
  93. #endif
  94. // mp_same<T...>
  95. namespace detail
  96. {
  97. template<class... T> struct mp_same_impl;
  98. template<> struct mp_same_impl<>
  99. {
  100. using type = mp_true;
  101. };
  102. template<class T1, class... T> struct mp_same_impl<T1, T...>
  103. {
  104. using type = mp_all<std::is_same<T1, T>...>;
  105. };
  106. } // namespace detail
  107. template<class... T> using mp_same = typename detail::mp_same_impl<T...>::type;
  108. // mp_less<T1, T2>
  109. template<class T1, class T2> using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>;
  110. // mp_min<T...>
  111. template<class T1, class... T> using mp_min = mp_min_element<mp_list<T1, T...>, mp_less>;
  112. // mp_max<T...>
  113. template<class T1, class... T> using mp_max = mp_max_element<mp_list<T1, T...>, mp_less>;
  114. } // namespace mp11
  115. } // namespace boost
  116. #endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED