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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 11 // <utility> 12 13 // LWG-3382 NTTP for pair and array: 14 // pair<T, U> is a structural type ([temp.param]) if T and U are both structural types. 15 16 #include <utility> 17 18 #include <functional> 19 #include <string> 20 21 struct LiteralBase {}; 22 struct LiteralNSDM {}; 23 24 struct LiteralType : LiteralBase { 25 LiteralNSDM nsdm; 26 }; 27 28 struct NotALiteral { 29 NotALiteral() {} 30 }; 31 32 int i; 33 NotALiteral not_a_literal; 34 35 namespace test_full_type { 36 template <class T, class U, std::pair<T, U> P> 37 struct test {}; 38 39 using A = test<int, int, std::pair{0, 1}>; 40 using B = test<int&, int&, std::make_pair(std::ref(i), std::ref(i))>; 41 using C = test<const int&, const int&, std::make_pair(std::cref(i), std::cref(i))>; 42 using D = test<LiteralType, LiteralType, std::pair<LiteralType, LiteralType>{}>; 43 using E = test<int*, int*, std::pair<int*, int*>{&i, &i}>; 44 using F = test<NotALiteral&, NotALiteral&, std::make_pair(std::ref(not_a_literal), std::ref(not_a_literal))>; 45 46 using G = test<int&&, int&&, std::pair<int&&, int&&>{std::move(i), std::move(i)}>; 47 // expected-error@*:* {{type 'std::pair<int &&, int &&>' of non-type template parameter is not a structural type}} 48 49 using H = test<NotALiteral, NotALiteral, std::pair<NotALiteral, NotALiteral>{}>; 50 // expected-error@*:* {{non-type template parameter has non-literal type 'std::pair<NotALiteral, NotALiteral>'}} 51 52 using I = test<std::string, std::string, std::pair<std::string, std::string>{}>; 53 // expected-error-re@*:* {{type 'std::pair<{{(std::)?}}string, {{(std::)?}}string>' {{(\(aka 'pair<basic_string<char>, basic_string<char>>'\) )?}}of non-type template parameter is not a structural type}} 54 } // namespace test_full_type 55 56 namespace test_ctad { 57 template <std::pair P> 58 struct test {}; 59 60 using A = test<std::pair{2, 3}>; 61 using B = test<std::make_pair(std::ref(i), std::ref(i))>; 62 using C = test<std::make_pair(std::cref(i), std::cref(i))>; 63 using D = test<std::pair<LiteralType, LiteralType>{}>; 64 using E = test<std::pair<int*, int*>{&i, &i}>; 65 using F = test<std::make_pair(std::ref(not_a_literal), std::ref(not_a_literal))>; 66 67 using G = test<std::pair<int&&, int&&>{std::move(i), std::move(i)}>; 68 // expected-error@-1 {{type 'std::pair<int &&, int &&>' of non-type template parameter is not a structural type}} 69 70 using H = test<std::pair<NotALiteral, NotALiteral>{}>; 71 // expected-error@-1 {{non-type template parameter has non-literal type 'std::pair<NotALiteral, NotALiteral>'}} 72 73 using I = test<std::pair<std::string, std::string>{}>; 74 // expected-error@-1 {{type 'std::pair<string, string>' (aka 'std::pair<std::string, std::string>') of non-type template parameter is not a structural type}} 75 } // namespace test_ctad 76 77 namespace test_auto { 78 template <auto P> 79 struct test {}; 80 81 using A = test<std::pair{4, 5}>; 82 using B = test<std::make_pair(std::ref(i), std::ref(i))>; 83 using C = test<std::make_pair(std::cref(i), std::cref(i))>; 84 using D = test<std::pair<LiteralType, LiteralType>{}>; 85 using E = test<std::pair<int*, int*>{&i, &i}>; 86 using F = test<std::make_pair(std::ref(not_a_literal), std::ref(not_a_literal))>; 87 88 using G = test<std::pair<int&&, int&&>{std::move(i), std::move(i)}>; 89 // expected-error@-1 {{type 'std::pair<int &&, int &&>' of non-type template parameter is not a structural type}} 90 91 using H = test<std::pair<NotALiteral, NotALiteral>{}>; 92 // expected-error@-1 {{non-type template parameter has non-literal type 'std::pair<NotALiteral, NotALiteral>'}} 93 94 using I = test<std::pair<std::string, std::string>{}>; 95 // expected-error@-1 {{type 'std::pair<std::string, std::string>' (aka 'pair<basic_string<char>, basic_string<char>>') of non-type template parameter is not a structural type}} 96 } // namespace test_auto 97