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/assert.hpp>
6 #include <boost/hana/tuple.hpp>
7 
8 #include <type_traits>
9 namespace hana = boost::hana;
10 
11 
12 struct MoveOnly {
13     int data_;
14     MoveOnly(MoveOnly const&) = delete;
15     MoveOnly& operator=(MoveOnly const&) = delete;
MoveOnlyMoveOnly16     MoveOnly(int data = 1) : data_(data) { }
MoveOnlyMoveOnly17     MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
18 
operator =MoveOnly19     MoveOnly& operator=(MoveOnly&& x)
20     { data_ = x.data_; x.data_ = 0; return *this; }
21 
getMoveOnly22     int get() const {return data_;}
operator ==MoveOnly23     bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
operator <MoveOnly24     bool operator< (const MoveOnly& x) const { return data_ <  x.data_; }
25 };
26 
27 struct Empty { };
28 struct A {
29     int id_;
AA30     explicit constexpr A(int i) : id_(i) {}
31 };
32 
33 struct NoDefault { NoDefault() = delete; };
34 
main()35 int main() {
36     {
37         hana::tuple<MoveOnly> t(MoveOnly(0));
38         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
39     }
40     {
41         hana::tuple<MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1));
42         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
43         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
44     }
45     {
46         hana::tuple<MoveOnly, MoveOnly, MoveOnly> t(
47             MoveOnly(0), MoveOnly(1), MoveOnly(2)
48         );
49         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
50         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
51         BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
52     }
53     {
54         constexpr hana::tuple<Empty> t0{Empty()}; (void)t0;
55     }
56     {
57         constexpr hana::tuple<A, A> t(3, 2);
58         static_assert(hana::at_c<0>(t).id_ == 3, "");
59     }
60     {
61         typedef hana::tuple<MoveOnly, NoDefault> Tuple;
62 
63         static_assert(!std::is_constructible<
64             Tuple,
65             MoveOnly
66         >::value, "");
67 
68         static_assert(std::is_constructible<
69             Tuple,
70             MoveOnly, NoDefault
71         >::value, "");
72     }
73     {
74         typedef hana::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
75 
76         static_assert(!std::is_constructible<
77             Tuple,
78             MoveOnly, MoveOnly
79         >::value, "");
80 
81         static_assert(std::is_constructible<
82             Tuple,
83             MoveOnly, MoveOnly, NoDefault
84         >::value, "");
85     }
86     {
87         typedef hana::tuple<MoveOnly, NoDefault> Tuple;
88         typedef hana::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
89 
90         static_assert(!std::is_constructible<
91             NestedTuple,
92             MoveOnly, MoveOnly, MoveOnly, MoveOnly
93         >::value, "");
94 
95         static_assert(std::is_constructible<
96             NestedTuple,
97             MoveOnly, Tuple, MoveOnly, MoveOnly
98         >::value, "");
99     }
100     {
101         typedef hana::tuple<MoveOnly, int> Tuple;
102         typedef hana::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
103 
104         static_assert(!std::is_constructible<
105             NestedTuple,
106             MoveOnly, MoveOnly, MoveOnly, MoveOnly
107         >::value, "");
108 
109         static_assert(std::is_constructible<
110             NestedTuple,
111             MoveOnly, Tuple, MoveOnly, MoveOnly
112         >::value, "");
113     }
114 }
115