//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template class tuple; // UNSUPPORTED: c++98, c++03 #include #include #include template struct ConstructibleFromT { ConstructibleFromT() = default; ConstructibleFromT(ConstructFrom v) : value(v) {} ConstructFrom value; }; template struct CtorAssertsT { bool defaulted; CtorAssertsT() : defaulted(true) {} template constexpr CtorAssertsT(T) : defaulted(false) { static_assert(!std::is_same::value, ""); } }; template struct AllowAssertT { AllowAssertT() = default; AllowAssertT(AllowT) {} template constexpr AllowAssertT(U) { static_assert(!std::is_same::value, ""); } }; // Construct a tuple from pair where T1 and T2 // are not constructible from ints but T1 is constructible from std::pair. // This considers the following constructors: // (1) tuple(TupleLike) -> checks is_constructible // (2) tuple(UTypes...) -> checks is_constructible> // and is_default_constructible // The point of this test is to ensure that the consideration of (1) // short circuits before evaluating is_constructible, which // will cause a static assertion. void test_tuple_like_lazy_sfinae() { #if defined(_LIBCPP_VERSION) // This test requires libc++'s reduced arity initialization. using T1 = ConstructibleFromT>; using T2 = CtorAssertsT; std::pair p(42, 100); std::tuple t(p); assert(std::get<0>(t).value == p); assert(std::get<1>(t).defaulted); #endif } struct NonConstCopyable { NonConstCopyable() = default; explicit NonConstCopyable(int v) : value(v) {} NonConstCopyable(NonConstCopyable&) = default; NonConstCopyable(NonConstCopyable const&) = delete; int value; }; template struct BlowsUpOnConstCopy { BlowsUpOnConstCopy() = default; constexpr BlowsUpOnConstCopy(BlowsUpOnConstCopy const&) { static_assert(!std::is_same::value, ""); } BlowsUpOnConstCopy(BlowsUpOnConstCopy&) = default; }; // Test the following constructors: // (1) tuple(Types const&...) // (2) tuple(UTypes&&...) // Test that (1) short circuits before evaluating the copy constructor of the // second argument. Constructor (2) should be selected. void test_const_Types_lazy_sfinae() { NonConstCopyable v(42); BlowsUpOnConstCopy b; std::tuple> t(v, b); assert(std::get<0>(t).value == 42); } int main() { test_tuple_like_lazy_sfinae(); test_const_Types_lazy_sfinae(); }