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