monadic_fold_left.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #include <boost/hana/assert.hpp>
  5. #include <boost/hana/equal.hpp>
  6. #include <boost/hana/monadic_fold_left.hpp>
  7. #include <boost/hana/optional.hpp>
  8. #include <boost/hana/traits.hpp>
  9. #include <boost/hana/tuple.hpp>
  10. #include <boost/hana/type.hpp>
  11. #include <type_traits>
  12. namespace hana = boost::hana;
  13. auto builtin_common_t = hana::sfinae([](auto&& t, auto&& u) -> hana::type<
  14. std::decay_t<decltype(true ? hana::traits::declval(t) : hana::traits::declval(u))>
  15. > { return {}; });
  16. template <typename ...T>
  17. struct common_type { };
  18. template <typename T, typename U>
  19. struct common_type<T, U>
  20. : std::conditional_t<std::is_same<std::decay_t<T>, T>{} &&
  21. std::is_same<std::decay_t<U>, U>{},
  22. decltype(builtin_common_t(hana::type_c<T>, hana::type_c<U>)),
  23. common_type<std::decay_t<T>, std::decay_t<U>>
  24. >
  25. { };
  26. template <typename T1, typename ...Tn>
  27. struct common_type<T1, Tn...>
  28. : decltype(hana::monadic_fold_left<hana::optional_tag>(
  29. hana::tuple_t<Tn...>,
  30. hana::type_c<std::decay_t<T1>>,
  31. hana::sfinae(hana::metafunction<common_type>)
  32. ))
  33. { };
  34. template <typename ...Ts>
  35. using common_type_t = typename common_type<Ts...>::type;
  36. BOOST_HANA_CONSTANT_CHECK(
  37. builtin_common_t(hana::type_c<int>, hana::type_c<float>)
  38. ==
  39. hana::just(hana::type_c<float>)
  40. );
  41. static_assert(std::is_same<
  42. common_type_t<char, short, char, short>,
  43. int
  44. >{}, "");
  45. static_assert(std::is_same<
  46. common_type_t<char, double, short, char, short, double>,
  47. double
  48. >{}, "");
  49. static_assert(std::is_same<
  50. common_type_t<char, short, float, short>,
  51. float
  52. >{}, "");
  53. static_assert(
  54. hana::sfinae(hana::metafunction<common_type>)(
  55. hana::type_c<int>, hana::type_c<int>, hana::type_c<int*>
  56. ) == hana::nothing
  57. , "");
  58. int main() { }