cnstr.trap.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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/tuple.hpp>
  5. #include <utility>
  6. namespace hana = boost::hana;
  7. // Make sure that the tuple(Yn&&...) is not preferred over copy constructors
  8. // in single-element cases and other similar cases.
  9. struct Trap1 {
  10. Trap1() = default;
  11. Trap1(Trap1 const&) = default;
  12. #ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
  13. Trap1(Trap1&) = default;
  14. #endif
  15. Trap1(Trap1&&) = default;
  16. template <typename X>
  17. Trap1(X&&) {
  18. static_assert(sizeof(X) && false,
  19. "this constructor must not be instantiated");
  20. }
  21. };
  22. struct Trap2 {
  23. Trap2() = default;
  24. Trap2(Trap2 const&) = default;
  25. #ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
  26. Trap2(Trap2&) = default;
  27. #endif
  28. Trap2(Trap2&&) = default;
  29. template <typename X>
  30. Trap2(X) { // not by reference
  31. static_assert(sizeof(X) && false,
  32. "this constructor must not be instantiated");
  33. }
  34. };
  35. struct Trap3 {
  36. Trap3() = default;
  37. Trap3(Trap3 const&) = default;
  38. #ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
  39. Trap3(Trap3&) = default;
  40. #endif
  41. Trap3(Trap3&&) = default;
  42. template <typename X>
  43. constexpr explicit Trap3(X&&) { // explicit, and constexpr
  44. static_assert(sizeof(X) && false,
  45. "this constructor must not be instantiated");
  46. }
  47. };
  48. struct Trap4 {
  49. Trap4() = default;
  50. template <typename Args>
  51. constexpr explicit Trap4(Args&&) {
  52. static_assert(sizeof(Args) && false, "must never be instantiated");
  53. }
  54. Trap4(Trap4 const&) = default;
  55. Trap4(Trap4&&) = default;
  56. };
  57. int main() {
  58. {
  59. hana::tuple<Trap1> tuple{};
  60. hana::tuple<Trap1> implicit_copy = tuple;
  61. hana::tuple<Trap1> explicit_copy(tuple);
  62. hana::tuple<Trap1> implicit_move = std::move(tuple);
  63. hana::tuple<Trap1> explicit_move(std::move(tuple));
  64. (void)implicit_copy;
  65. (void)explicit_copy;
  66. (void)implicit_move;
  67. (void)explicit_move;
  68. }
  69. {
  70. hana::tuple<Trap2> tuple{};
  71. hana::tuple<Trap2> implicit_copy = tuple;
  72. hana::tuple<Trap2> explicit_copy(tuple);
  73. hana::tuple<Trap2> implicit_move = std::move(tuple);
  74. hana::tuple<Trap2> explicit_move(std::move(tuple));
  75. (void)implicit_copy;
  76. (void)explicit_copy;
  77. (void)implicit_move;
  78. (void)explicit_move;
  79. }
  80. {
  81. hana::tuple<Trap3> tuple{};
  82. hana::tuple<Trap3> implicit_copy = tuple;
  83. hana::tuple<Trap3> explicit_copy(tuple);
  84. hana::tuple<Trap3> implicit_move = std::move(tuple);
  85. hana::tuple<Trap3> explicit_move(std::move(tuple));
  86. (void)implicit_copy;
  87. (void)explicit_copy;
  88. (void)implicit_move;
  89. (void)explicit_move;
  90. }
  91. // Just defining the structure used to cause a failure, because of the
  92. // explicitly defaulted copy-constructor.
  93. {
  94. struct Foo {
  95. Foo() = default;
  96. Foo(Foo const&) = default;
  97. Foo(Foo&&) = default;
  98. hana::tuple<Trap4> t;
  99. };
  100. }
  101. }