//===----------------------------------------------------------------------===// // // 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 // TODO: Revisit this test once we have more information // with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102247 // XFAIL: gcc // // template struct pair // // pair(const T1&, const T2&); // template pair(U&&, V&&); // This test checks support for brace-initialization of pairs. #include #include #include "test_macros.h" struct ExplicitT { constexpr explicit ExplicitT(int x) : value(x) {} constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} int value; }; struct ImplicitT { constexpr ImplicitT(int x) : value(x) {} constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} int value; }; template ({}, {}))> constexpr bool can_construct_with_brace_init(int) { return true; } template constexpr bool can_construct_with_brace_init(...) { return false; } #if TEST_STD_VER >= 17 // CTAD isn't supported before C++17 template constexpr bool can_construct_with_ctad_brace_init(int) { return true; } template constexpr bool can_construct_with_ctad_brace_init(...) { return false; } #endif struct BraceInit { BraceInit() = default; }; struct NoBraceInit { NoBraceInit(int); }; struct ExplicitBraceInit { explicit ExplicitBraceInit() = default; }; constexpr int explicit_vs_implicit_brace_init(std::pair) { return 1; } constexpr int explicit_vs_implicit_brace_init(std::pair) { return 2; } TEST_CONSTEXPR_CXX14 bool test() { // Explicit constructor { std::pair p1(ExplicitT{42}, {}); assert(p1.first.value == 42); std::pair p2{ExplicitT{42}, {}}; assert(p2.first.value == 42); } { std::pair p1({}, ExplicitT{42}); assert(p1.second.value == 42); std::pair p2{{}, ExplicitT{42}}; assert(p2.second.value == 42); } { std::pair p{{}, {}}; (void)p; } // Implicit constructor { std::pair p = {42, {}}; assert(p.first.value == 42); } { std::pair p = {{}, 42}; assert(p.second.value == 42); } { std::pair p = {{}, {}}; (void)p; } // SFINAE-friendliness of some invalid cases { static_assert( can_construct_with_brace_init(0), ""); static_assert(!can_construct_with_brace_init(0), ""); #if TEST_STD_VER >= 17 // CTAD with {} should never work, since we can't possibly deduce the types static_assert(!can_construct_with_ctad_brace_init(0), ""); static_assert(!can_construct_with_ctad_brace_init(0), ""); #endif } // Make sure there is no ambiguity between the explicit and the non-explicit constructors { assert(explicit_vs_implicit_brace_init({{}, {}}) == 2); } return true; } int main(int, char**) { test(); #if TEST_STD_VER > 11 static_assert(test(), ""); #endif return 0; }