]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/test/pair/cnstr.move.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / hana / test / pair / cnstr.move.cpp
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/first.hpp>
7 #include <boost/hana/pair.hpp>
8 #include <boost/hana/second.hpp>
9
10 #include <type_traits>
11 #include <utility>
12 namespace hana = boost::hana;
13
14
15 struct MoveOnly {
16 int data_;
17 MoveOnly(MoveOnly const&) = delete;
18 MoveOnly& operator=(MoveOnly const&) = delete;
19 MoveOnly(int data) : data_(data) { }
20 MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
21
22 MoveOnly& operator=(MoveOnly&& x)
23 { data_ = x.data_; x.data_ = 0; return *this; }
24
25 bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
26 };
27
28 struct MoveOnlyDerived : MoveOnly {
29 MoveOnlyDerived(MoveOnlyDerived&&) = default;
30 MoveOnlyDerived(int data = 1) : MoveOnly(data) { }
31 };
32
33 template <typename Target>
34 struct implicit_to {
35 constexpr operator Target() const { return Target{}; }
36 };
37
38 struct NoMove {
39 NoMove() = default;
40 NoMove(NoMove const&) = delete;
41 NoMove(NoMove&&) = delete;
42 };
43
44 // Note: It is also useful to check with a non-empty class, because that
45 // triggers different instantiations due to EBO.
46 struct NoMove_nonempty {
47 NoMove_nonempty() = default;
48 NoMove_nonempty(NoMove_nonempty const&) = delete;
49 NoMove_nonempty(NoMove_nonempty&&) = delete;
50 int i;
51 };
52
53 int main() {
54 {
55 hana::pair<MoveOnly, short> p1(MoveOnly{3}, 4);
56 hana::pair<MoveOnly, short> p2(std::move(p1));
57 BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
58 BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
59 }
60
61 // Make sure it works across pair types
62 {
63 hana::pair<MoveOnlyDerived, short> p1(MoveOnlyDerived{3}, 4);
64 hana::pair<MoveOnly, long> p2 = std::move(p1);
65 BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
66 BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
67 }
68 {
69 struct target1 {
70 target1() = default;
71 target1(target1 const&) = delete;
72 target1(target1&&) = default;
73 };
74
75 struct target2 {
76 target2() = default;
77 target2(target2 const&) = delete;
78 target2(target2&&) = default;
79 };
80 using Target = hana::pair<target1, target2>;
81 Target p1(hana::make_pair(target1{}, target2{})); (void)p1;
82 Target p2(hana::make_pair(implicit_to<target1>{}, target2{})); (void)p2;
83 Target p3(hana::make_pair(target1{}, implicit_to<target2>{})); (void)p3;
84 Target p4(hana::make_pair(implicit_to<target1>{}, implicit_to<target2>{})); (void)p4;
85 }
86
87 // Make sure we don't define the move constructor when it shouldn't be defined.
88 {
89 using Pair1 = hana::pair<NoMove, NoMove>;
90 Pair1 pair1; (void)pair1;
91 static_assert(!std::is_move_constructible<Pair1>::value, "");
92
93 using Pair2 = hana::pair<NoMove_nonempty, NoMove_nonempty>;
94 Pair2 pair2; (void)pair2;
95 static_assert(!std::is_move_constructible<Pair2>::value, "");
96 }
97 }