Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / hana / test / pair / cnstr.copy.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 namespace hana = boost::hana;
12
13
14 template <typename Target>
15 struct implicit_to {
16     constexpr operator Target() const { return Target{}; }
17 };
18
19 struct NoCopy {
20     NoCopy() = default;
21     NoCopy(NoCopy const&) = delete;
22 };
23
24 // Note: It is also useful to check with a non-empty class, because that
25 //       triggers different instantiations due to EBO.
26 struct NoCopy_nonempty {
27     NoCopy_nonempty() = default;
28     NoCopy_nonempty(NoCopy_nonempty const&) = delete;
29     int i;
30 };
31
32 int main() {
33     {
34         typedef std::pair<int, short> P1;
35         hana::pair<int, short> p1(3, 4);
36         hana::pair<int, short> p2 = p1;
37         BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
38         BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
39     }
40
41     static_assert(std::is_trivially_copy_constructible<hana::pair<int, int>>{}, "");
42
43     // make sure it also works constexpr
44     {
45         constexpr hana::pair<int, short> p1(3, 4);
46         constexpr hana::pair<int, short> p2 = p1;
47         static_assert(hana::first(p2) == 3, "");
48         static_assert(hana::second(p2) == 4, "");
49     }
50
51     // Make sure it works across pair types (pair<T, U> -> pair<U, V>)
52     {
53         hana::pair<int, short> p1(3, 4);
54         hana::pair<double, long> p2 = p1;
55         BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
56         BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
57     }
58     {
59         struct target1 { };
60         struct target2 { };
61         using Target = hana::pair<target1, target2>;
62
63         auto p1_ = hana::make_pair(target1{}, target2{});
64         Target p1(p1_); (void)p1;
65
66         auto p2_ = hana::make_pair(implicit_to<target1>{}, target2{});
67         Target p2(p2_);
68
69         auto p3_ = hana::make_pair(target1{}, implicit_to<target2>{});
70         Target p3(p3_);
71
72         auto p4_ = hana::make_pair(implicit_to<target1>{}, implicit_to<target2>{});
73         Target p4(p4_);
74     }
75
76     // And also constexpr across pair types
77     {
78         constexpr hana::pair<int, short> p1(3, 4);
79         constexpr hana::pair<double, long> p2 = p1;
80         static_assert(hana::first(p2) == 3, "");
81         static_assert(hana::second(p2) == 4, "");
82     }
83
84     // Make sure we don't define the copy constructor when it shouldn't be defined.
85     {
86         using Pair1 = hana::pair<NoCopy, NoCopy>;
87         Pair1 pair1;
88         static_assert(!std::is_copy_constructible<Pair1>::value, "");
89
90         using Pair2 = hana::pair<NoCopy_nonempty, NoCopy_nonempty>;
91         Pair2 pair2;
92         static_assert(!std::is_copy_constructible<Pair2>::value, "");
93     }
94 }