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 #include <utility>
10 namespace hana = boost::hana;
11 
12 
13 struct MoveOnly {
14     int data_;
15     MoveOnly(MoveOnly const&) = delete;
16     MoveOnly& operator=(MoveOnly const&) = delete;
MoveOnlyMoveOnly17     MoveOnly(int data = 1) : data_(data) { }
MoveOnlyMoveOnly18     MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
19 
operator =MoveOnly20     MoveOnly& operator=(MoveOnly&& x)
21     { data_ = x.data_; x.data_ = 0; return *this; }
22 
getMoveOnly23     int get() const {return data_;}
operator ==MoveOnly24     bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
operator <MoveOnly25     bool operator< (const MoveOnly& x) const { return data_ <  x.data_; }
26 };
27 
main()28 int main() {
29     {
30         using T = hana::tuple<>;
31         T t0;
32         T t = std::move(t0); (void)t;
33     }
34     {
35         using T = hana::tuple<MoveOnly>;
36         T t0(MoveOnly(0));
37         T t = std::move(t0); (void)t;
38         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
39     }
40     {
41         using T = hana::tuple<MoveOnly, MoveOnly>;
42         T t0(MoveOnly(0), MoveOnly(1));
43         T t = std::move(t0); (void)t;
44         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
45         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
46     }
47     {
48         using T = hana::tuple<MoveOnly, MoveOnly, MoveOnly>;
49         T t0(MoveOnly(0), MoveOnly(1), MoveOnly(2));
50         T t = std::move(t0); (void)t;
51         BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
52         BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
53         BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
54     }
55     {
56         // Check for SFINAE-friendliness
57         static_assert(!std::is_constructible<
58             hana::tuple<MoveOnly>, MoveOnly const&
59         >{}, "");
60 
61         static_assert(!std::is_constructible<
62             hana::tuple<MoveOnly>, MoveOnly&
63         >{}, "");
64 
65         static_assert(std::is_constructible<
66             hana::tuple<MoveOnly>, MoveOnly
67         >{}, "");
68 
69         static_assert(std::is_constructible<
70             hana::tuple<MoveOnly>, MoveOnly&&
71         >{}, "");
72     }
73 }
74