//===----------------------------------------------------------------------===// // // 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 // // template struct pair // template pair(U&&, V&&); #include #include #include #include "archetypes.h" #include "test_convertible.h" #include "test_macros.h" using namespace ImplicitTypes; // Get implicitly archetypes template void test_sfinae() { using P1 = std::pair; using P2 = std::pair; using T2 = int const&; 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 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, short*> P; P p(std::unique_ptr(new int(3)), nullptr); assert(*p.first == 3); assert(p.second == nullptr); } { // Test non-const lvalue and rvalue types test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); } { // Test converting types test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); test_sfinae(); } #if TEST_STD_VER > 11 { // explicit constexpr test constexpr std::pair p(42, 43); static_assert(p.first.value == 42, ""); static_assert(p.second.value == 43, ""); } { // implicit constexpr test constexpr std::pair p = {42, 43}; static_assert(p.first.value == 42, ""); static_assert(p.second.value == 43, ""); } #endif // Test support for http://wg21.link/P1951, default arguments for pair's constructor. // Basically, this turns copies for brace initialization into moves. #if TEST_STD_VER > 20 { struct TrackInit { TrackInit() = default; constexpr TrackInit(TrackInit const& other) : wasMoveInit(other.wasMoveInit), wasCopyInit(true) { } constexpr TrackInit(TrackInit&& other) : wasMoveInit(true), wasCopyInit(other.wasCopyInit) { } bool wasMoveInit = false; bool wasCopyInit = false; }; // Explicit constructor { { std::pair p({}, 3); assert( p.first.wasMoveInit); assert(!p.first.wasCopyInit); } { std::pair p(3, {}); assert( p.second.wasMoveInit); assert(!p.second.wasCopyInit); } } // Implicit constructor { { std::pair p = {{}, 3}; assert( p.first.wasMoveInit); assert(!p.first.wasCopyInit); } { std::pair p = {3, {}}; assert( p.second.wasMoveInit); assert(!p.second.wasCopyInit); } } } #endif // TEST_STD_VER > 20 return 0; }