to.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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/core/to.hpp>
  5. #include <boost/hana/assert.hpp>
  6. #include <boost/hana/core/tag_of.hpp>
  7. #include <string>
  8. #include <type_traits>
  9. namespace hana = boost::hana;
  10. template <typename X, typename Y>
  11. constexpr auto operator==(X x, Y y)
  12. { return x.value == y.value; }
  13. struct Datatype {
  14. int value;
  15. using hana_tag = Datatype;
  16. };
  17. struct Other {
  18. int value;
  19. using hana_tag = Datatype;
  20. };
  21. struct SpecializedFrom;
  22. struct specialized_from {
  23. int value;
  24. using hana_tag = SpecializedFrom;
  25. };
  26. struct SpecializedTo;
  27. struct specialized_to {
  28. int value;
  29. using hana_tag = SpecializedTo;
  30. };
  31. namespace boost { namespace hana {
  32. template <>
  33. struct to_impl<SpecializedTo, SpecializedFrom> {
  34. template <typename T>
  35. static constexpr auto apply(T t)
  36. { return specialized_to{t.value}; }
  37. };
  38. }}
  39. template <typename F, typename T>
  40. void check_convert(F f, T t) {
  41. using From = hana::tag_of_t<F>;
  42. using To = hana::tag_of_t<T>;
  43. // Check From -> To conversion
  44. BOOST_HANA_RUNTIME_CHECK(hana::to<To>(f) == t);
  45. static_assert(std::is_same<
  46. hana::tag_of_t<decltype(hana::to<To>(f))>, To
  47. >{}, "");
  48. static_assert(hana::is_convertible<From, To>{}, "");
  49. // Make sure From -> From and To -> To are the identity.
  50. BOOST_HANA_RUNTIME_CHECK(hana::to<From>(f) == f);
  51. static_assert(std::is_same<
  52. hana::tag_of_t<decltype(hana::to<From>(f))>, From
  53. >{}, "");
  54. BOOST_HANA_RUNTIME_CHECK(hana::to<To>(t) == t);
  55. static_assert(std::is_same<
  56. hana::tag_of_t<decltype(hana::to<To>(t))>, To
  57. >{}, "");
  58. static_assert(hana::is_convertible<From, From>{}, "");
  59. static_assert(hana::is_convertible<To, To>{}, "");
  60. static_assert(hana::is_embedded<From, From>{}, "");
  61. static_assert(hana::is_embedded<To, To>{}, "");
  62. }
  63. template <typename X>
  64. void check_variable_template_in_dependent_context(X x) {
  65. hana::to<int>(x);
  66. }
  67. int main() {
  68. // Clang used to assert in the code generation when we used variable
  69. // templates inside a lambda; this is to catch this.
  70. check_variable_template_in_dependent_context(3);
  71. check_convert("abcdef", std::string{"abcdef"});
  72. check_convert(int{1}, double{1});
  73. check_convert(double{1}, int{1});
  74. check_convert(std::true_type{}, int{1});
  75. check_convert(std::false_type{}, int{0});
  76. check_convert(Datatype{1}, Datatype{1});
  77. check_convert(Other{1}, Other{1});
  78. check_convert(specialized_from{1}, specialized_to{1});
  79. static_assert(!hana::is_convertible<void, int>{}, "");
  80. static_assert(!hana::is_embedded<void, int>{}, "");
  81. static_assert(hana::is_convertible<int, void>{}, "");
  82. static_assert(!hana::is_embedded<int, void>{}, "");
  83. }