100 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++0310 11// FIXME: Why does this start to fail with GCC 14?12// XFAIL: !(c++11 || c++14) && (gcc-14 || gcc-15)13 14// See https://llvm.org/PR31384.15 16#include <tuple>17#include <cassert>18 19#include "test_macros.h"20 21int count = 0;22 23struct Explicit {24 Explicit() = default;25 explicit Explicit(int) {}26};27 28struct Implicit {29 Implicit() = default;30 Implicit(int) {}31};32 33template<class T>34struct Derived : std::tuple<T> {35 using std::tuple<T>::tuple;36 template<class U>37 operator std::tuple<U>() && { ++count; return {}; }38};39 40 41template<class T>42struct ExplicitDerived : std::tuple<T> {43 using std::tuple<T>::tuple;44 template<class U>45 explicit operator std::tuple<U>() && { ++count; return {}; }46};47 48int main(int, char**) {49 {50 std::tuple<Explicit> foo = Derived<int>{42}; ((void)foo);51 assert(count == 1);52 Derived<int> d{42};53 std::tuple<Explicit> bar(std::move(d)); ((void)bar);54#if TEST_STD_VER < 1755 assert(count == 1);56#else57 assert(count == 2);58#endif59 }60 count = 0;61 {62 std::tuple<Implicit> foo = Derived<int>{42}; ((void)foo);63 assert(count == 1);64 Derived<int> d{42};65 std::tuple<Implicit> bar(std::move(d)); ((void)bar);66#if TEST_STD_VER < 1767 assert(count == 1);68#else69 assert(count == 2);70#endif71 }72 count = 0;73 {74 static_assert(!std::is_convertible<ExplicitDerived<int>, std::tuple<Explicit>>::value, "");75 ExplicitDerived<int> d{42};76 std::tuple<Explicit> bar(std::move(d)); ((void)bar);77#if TEST_STD_VER < 1778 assert(count == 0);79#else80 assert(count == 1);81#endif82 }83 count = 0;84 {85 std::tuple<Implicit> foo = ExplicitDerived<int>{42}; ((void)foo);86 static_assert(std::is_convertible<ExplicitDerived<int>, std::tuple<Implicit>>::value, "");87 assert(count == 0);88 ExplicitDerived<int> d{42};89 std::tuple<Implicit> bar(std::move(d)); ((void)bar);90#if TEST_STD_VER < 1791 assert(count == 0);92#else93 assert(count == 1);94#endif95 }96 count = 0;97 98 return 0;99}100