//===----------------------------------------------------------------------===// // // 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++98, c++03 // // template struct pair // template pair(pair&& p); #include #include #include #include "archetypes.h" #include "test_convertible.h" #include "test_macros.h" using namespace ImplicitTypes; // Get implicitly archetypes template void test_pair_rv() { using P1 = std::pair; using P2 = std::pair; using UP1 = std::pair&&; using UP2 = std::pair&&; static_assert(std::is_constructible::value == CanCopy, ""); static_assert(test_convertible() == CanConvert, ""); static_assert(std::is_constructible::value == CanCopy, ""); static_assert(test_convertible() == CanConvert, ""); } struct Base { virtual ~Base() {} }; struct Derived : public Base { }; template struct DPair : public std::pair { using Base = std::pair; using Base::Base; }; struct ExplicitT { constexpr explicit ExplicitT(int x) : value(x) {} int value; }; struct ImplicitT { constexpr ImplicitT(int x) : value(x) {} int value; }; int main(int, char**) { { typedef std::pair, int> P1; typedef std::pair, long> P2; P1 p1(std::unique_ptr(), 4); P2 p2 = std::move(p1); assert(p2.first == nullptr); assert(p2.second == 4); } { // We allow derived types to use this constructor using P1 = DPair; using P2 = std::pair; P1 p1(42, 101); P2 p2(std::move(p1)); assert(p2.first == 42); assert(p2.second == 101); } { test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); // copy construction test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); } { // Test construction of references test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); // Unfortunately the below conversions are allowed and create dangling // references. //test_pair_rv(); //test_pair_rv(); //test_pair_rv(); // But these are not because the converting constructor is explicit. test_pair_rv(); test_pair_rv(); test_pair_rv(); } { test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); test_pair_rv(); } #if TEST_STD_VER > 11 { // explicit constexpr test constexpr std::pair p1(42, 43); constexpr std::pair p2(std::move(p1)); static_assert(p2.first.value == 42, ""); static_assert(p2.second.value == 43, ""); } { // implicit constexpr test constexpr std::pair p1(42, 43); constexpr std::pair p2 = std::move(p1); static_assert(p2.first.value == 42, ""); static_assert(p2.second.value == 43, ""); } #endif return 0; }