//===----------------------------------------------------------------------===//
//
// 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 <utility>
#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;
}