1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03
// <utility>
// template <class T, class U> struct pair;
// pair(pair const&) = default;
// pair(pair &&) = default;
// pair& operator=(pair const&);
// pair& operator=(pair&&);
// Test that the copy/move constructors and assignment operators are
// correctly defined or deleted based on the properties of `T` and `U`.
#include <cassert>
#include <string>
#include <tuple>
#include "archetypes.h"
#include "test_macros.h"
using namespace ImplicitTypes; // Get implicitly archetypes
namespace ConstructorTest {
template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
using P1 = std::pair<T1, int>;
using P2 = std::pair<int, T1>;
static_assert(std::is_copy_constructible<P1>::value == CanCopy, "");
static_assert(std::is_move_constructible<P1>::value == CanMove, "");
static_assert(std::is_copy_constructible<P2>::value == CanCopy, "");
static_assert(std::is_move_constructible<P2>::value == CanMove, "");
};
} // namespace ConstructorTest
void test_constructors_exist() {
using namespace ConstructorTest;
{
test<int>();
test<int &>();
test<int &&, false, true>();
test<const int>();
test<const int &>();
test<const int &&, false, true>();
}
{
test<Copyable>();
test<Copyable &>();
test<Copyable &&, false, true>();
}
{
test<NonCopyable, false>();
test<NonCopyable &, true>();
test<NonCopyable &&, false, true>();
}
{
// Even though CopyOnly has an explicitly deleted move constructor
// pair's move constructor is only implicitly deleted and therefore
// it doesn't participate in overload resolution.
test<CopyOnly, true, true>();
test<CopyOnly &, true>();
test<CopyOnly &&, false, true>();
}
{
test<MoveOnly, false, true>();
test<MoveOnly &, true>();
test<MoveOnly &&, false, true>();
}
}
namespace AssignmentOperatorTest {
template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
using P1 = std::pair<T1, int>;
using P2 = std::pair<int, T1>;
static_assert(std::is_copy_assignable<P1>::value == CanCopy, "");
static_assert(std::is_move_assignable<P1>::value == CanMove, "");
static_assert(std::is_copy_assignable<P2>::value == CanCopy, "");
static_assert(std::is_move_assignable<P2>::value == CanMove, "");
};
} // namespace AssignmentOperatorTest
void test_assignment_operator_exists() {
using namespace AssignmentOperatorTest;
{
test<int>();
test<int &>();
test<int &&>();
test<const int, false>();
test<const int &, false>();
test<const int &&, false>();
}
{
test<Copyable>();
test<Copyable &>();
test<Copyable &&>();
}
{
test<NonCopyable, false>();
test<NonCopyable &, false>();
test<NonCopyable &&, false>();
}
{
test<CopyOnly, true>();
test<CopyOnly &, true>();
test<CopyOnly &&, true>();
}
{
test<MoveOnly, false, true>();
test<MoveOnly &, false, false>();
test<MoveOnly &&, false, true>();
}
}
int main(int, char**) {
test_constructors_exist();
test_assignment_operator_exists();
return 0;
}
|