1aedcbf89SEric Fiselier //===----------------------------------------------------------------------===//
2aedcbf89SEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6aedcbf89SEric Fiselier //
7aedcbf89SEric Fiselier //===----------------------------------------------------------------------===//
8aedcbf89SEric Fiselier
931cbe0f2SLouis Dionne // UNSUPPORTED: c++03
10aedcbf89SEric Fiselier
11aedcbf89SEric Fiselier // <utility>
12aedcbf89SEric Fiselier
13aedcbf89SEric Fiselier // template <class T1, class T2> struct pair
14aedcbf89SEric Fiselier
15aedcbf89SEric Fiselier // pair& operator=(pair const& p);
16aedcbf89SEric Fiselier
17aedcbf89SEric Fiselier #include <utility>
18aedcbf89SEric Fiselier #include <memory>
19aedcbf89SEric Fiselier #include <cassert>
20aedcbf89SEric Fiselier
217fc6a556SMarshall Clow #include "test_macros.h"
22737a4501SMichael Schellenberger Costa #include "archetypes.h"
23aedcbf89SEric Fiselier
24aedcbf89SEric Fiselier struct CountAssign {
25737a4501SMichael Schellenberger Costa int copied = 0;
26737a4501SMichael Schellenberger Costa int moved = 0;
27737a4501SMichael Schellenberger Costa TEST_CONSTEXPR_CXX20 CountAssign() = default;
operator =CountAssign28737a4501SMichael Schellenberger Costa TEST_CONSTEXPR_CXX20 CountAssign& operator=(CountAssign const&) {
29737a4501SMichael Schellenberger Costa ++copied;
30737a4501SMichael Schellenberger Costa return *this;
31737a4501SMichael Schellenberger Costa }
operator =CountAssign32737a4501SMichael Schellenberger Costa TEST_CONSTEXPR_CXX20 CountAssign& operator=(CountAssign&&) {
33737a4501SMichael Schellenberger Costa ++moved;
34737a4501SMichael Schellenberger Costa return *this;
35737a4501SMichael Schellenberger Costa }
36aedcbf89SEric Fiselier };
37aedcbf89SEric Fiselier
38aedcbf89SEric Fiselier struct Incomplete;
39aedcbf89SEric Fiselier extern Incomplete inc_obj;
40aedcbf89SEric Fiselier
test()41737a4501SMichael Schellenberger Costa TEST_CONSTEXPR_CXX20 bool test() {
42aedcbf89SEric Fiselier {
43737a4501SMichael Schellenberger Costa typedef std::pair<ConstexprTestTypes::CopyOnly, int> P;
44737a4501SMichael Schellenberger Costa const P p1(ConstexprTestTypes::CopyOnly(), short{4});
45aedcbf89SEric Fiselier P p2;
46aedcbf89SEric Fiselier p2 = p1;
47aedcbf89SEric Fiselier assert(p2.second == 4);
48aedcbf89SEric Fiselier }
49aedcbf89SEric Fiselier {
50aedcbf89SEric Fiselier using P = std::pair<int&, int&&>;
51aedcbf89SEric Fiselier int x = 42;
52aedcbf89SEric Fiselier int y = 101;
53aedcbf89SEric Fiselier int x2 = -1;
54aedcbf89SEric Fiselier int y2 = 300;
55aedcbf89SEric Fiselier P p1(x, std::move(y));
56aedcbf89SEric Fiselier P p2(x2, std::move(y2));
57aedcbf89SEric Fiselier p1 = p2;
58aedcbf89SEric Fiselier assert(p1.first == x2);
59aedcbf89SEric Fiselier assert(p1.second == y2);
60aedcbf89SEric Fiselier }
61aedcbf89SEric Fiselier {
62737a4501SMichael Schellenberger Costa using P = std::pair<int, ConstexprTestTypes::NonCopyable>;
63aedcbf89SEric Fiselier static_assert(!std::is_copy_assignable<P>::value, "");
64aedcbf89SEric Fiselier }
65aedcbf89SEric Fiselier {
66737a4501SMichael Schellenberger Costa using P = std::pair<CountAssign, ConstexprTestTypes::Copyable>;
67aedcbf89SEric Fiselier static_assert(std::is_copy_assignable<P>::value, "");
68aedcbf89SEric Fiselier P p;
69aedcbf89SEric Fiselier P p2;
70aedcbf89SEric Fiselier p = p2;
71737a4501SMichael Schellenberger Costa assert(p.first.copied == 1);
72737a4501SMichael Schellenberger Costa assert(p.first.moved == 0);
73737a4501SMichael Schellenberger Costa assert(p2.first.copied == 0);
74737a4501SMichael Schellenberger Costa assert(p2.first.moved == 0);
75aedcbf89SEric Fiselier }
76aedcbf89SEric Fiselier {
77737a4501SMichael Schellenberger Costa using P = std::pair<int, ConstexprTestTypes::MoveAssignOnly>;
78aedcbf89SEric Fiselier static_assert(!std::is_copy_assignable<P>::value, "");
79aedcbf89SEric Fiselier }
80aedcbf89SEric Fiselier {
81*82c4701dSzoecarver using P = std::pair<int, std::unique_ptr<int> >;
82*82c4701dSzoecarver static_assert(!std::is_copy_assignable<P>::value, "");
83*82c4701dSzoecarver }
84*82c4701dSzoecarver {
85aedcbf89SEric Fiselier using P = std::pair<int, Incomplete&>;
86aedcbf89SEric Fiselier static_assert(!std::is_copy_assignable<P>::value, "");
87aedcbf89SEric Fiselier P p(42, inc_obj);
88aedcbf89SEric Fiselier assert(&p.second == &inc_obj);
89aedcbf89SEric Fiselier }
902df59c50SJF Bastien
91737a4501SMichael Schellenberger Costa return true;
92737a4501SMichael Schellenberger Costa }
93737a4501SMichael Schellenberger Costa
main(int,char **)94737a4501SMichael Schellenberger Costa int main(int, char**) {
95737a4501SMichael Schellenberger Costa test();
96737a4501SMichael Schellenberger Costa #if TEST_STD_VER >= 20
97737a4501SMichael Schellenberger Costa static_assert(test());
98737a4501SMichael Schellenberger Costa #endif
99737a4501SMichael Schellenberger Costa
1002df59c50SJF Bastien return 0;
101aedcbf89SEric Fiselier }
102aedcbf89SEric Fiselier
103aedcbf89SEric Fiselier struct Incomplete {};
104aedcbf89SEric Fiselier Incomplete inc_obj;
105