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