cnstr.default.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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/tuple.hpp>
  6. #include <string>
  7. #include <type_traits>
  8. namespace hana = boost::hana;
  9. struct DefaultOnly {
  10. int data_;
  11. DefaultOnly(DefaultOnly const&) = delete;
  12. DefaultOnly& operator=(DefaultOnly const&) = delete;
  13. static int count;
  14. DefaultOnly() : data_(-1) { ++count; }
  15. ~DefaultOnly() { data_ = 0; --count; }
  16. friend bool operator==(DefaultOnly const& x, DefaultOnly const& y)
  17. { return x.data_ == y.data_; }
  18. friend bool operator< (DefaultOnly const& x, DefaultOnly const& y)
  19. { return x.data_ < y.data_; }
  20. };
  21. int DefaultOnly::count = 0;
  22. struct NoDefault {
  23. NoDefault() = delete;
  24. explicit NoDefault(int) { }
  25. };
  26. struct IllFormedDefault {
  27. IllFormedDefault(int x) : value(x) {}
  28. template <bool Pred = false>
  29. constexpr IllFormedDefault() {
  30. static_assert(Pred,
  31. "The default constructor should not be instantiated");
  32. }
  33. int value;
  34. };
  35. int main() {
  36. {
  37. hana::tuple<> t; (void)t;
  38. }
  39. {
  40. hana::tuple<int> t;
  41. BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
  42. }
  43. {
  44. hana::tuple<int, char*> t;
  45. BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
  46. BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
  47. }
  48. {
  49. hana::tuple<int, char*, std::string> t;
  50. BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
  51. BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
  52. BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
  53. }
  54. {
  55. hana::tuple<int, char*, std::string, DefaultOnly> t;
  56. BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
  57. BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
  58. BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
  59. BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == DefaultOnly());
  60. }
  61. {
  62. // See LLVM bug #21157.
  63. static_assert(!std::is_default_constructible<
  64. hana::tuple<NoDefault>
  65. >(), "");
  66. static_assert(!std::is_default_constructible<
  67. hana::tuple<DefaultOnly, NoDefault>
  68. >(), "");
  69. static_assert(!std::is_default_constructible<
  70. hana::tuple<NoDefault, DefaultOnly, NoDefault>
  71. >(), "");
  72. }
  73. {
  74. struct T { };
  75. struct U { };
  76. struct V { };
  77. constexpr hana::tuple<> z0; (void)z0;
  78. constexpr hana::tuple<T> z1; (void)z1;
  79. constexpr hana::tuple<T, U> z2; (void)z2;
  80. constexpr hana::tuple<T, U, V> z3; (void)z3;
  81. }
  82. {
  83. constexpr hana::tuple<int> t;
  84. BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
  85. }
  86. {
  87. constexpr hana::tuple<int, char*> t;
  88. BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
  89. BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
  90. }
  91. // Make sure we can hold non default-constructible elements, and that
  92. // it does not trigger an error in the default constructor.
  93. {
  94. {
  95. IllFormedDefault v(0);
  96. hana::tuple<IllFormedDefault> t1(v);
  97. hana::tuple<IllFormedDefault> t2{v};
  98. hana::tuple<IllFormedDefault> t3 = {v};
  99. (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
  100. }
  101. {
  102. hana::tuple<NoDefault> t1(0);
  103. hana::tuple<NoDefault> t2{0};
  104. hana::tuple<NoDefault> t3 = {0};
  105. (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
  106. }
  107. {
  108. NoDefault v(0);
  109. hana::tuple<NoDefault> t1(v);
  110. hana::tuple<NoDefault> t2{v};
  111. hana::tuple<NoDefault> t3 = {v};
  112. (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
  113. }
  114. }
  115. // Make sure a tuple_t can be default-constructed
  116. {
  117. struct T;
  118. struct U;
  119. using Types = decltype(hana::tuple_t<T, U>);
  120. Types t{}; (void)t;
  121. }
  122. }