]>
Commit | Line | Data |
---|---|---|
8868286e | 1 | // { dg-options "-std=gnu++11" } |
409e2405 | 2 | // { dg-do compile } |
3 | ||
f1717362 | 4 | // Copyright (C) 2011-2016 Free Software Foundation, Inc. |
409e2405 | 5 | // |
6 | // This file is part of the GNU ISO C++ Library. This library is free | |
7 | // software; you can redistribute it and/or modify it under the | |
8 | // terms of the GNU General Public License as published by the | |
9 | // Free Software Foundation; either version 3, or (at your option) | |
10 | // any later version. | |
11 | // | |
12 | // This library is distributed in the hope that it will be useful, | |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | // GNU General Public License for more details. | |
16 | // | |
17 | // You should have received a copy of the GNU General Public License along | |
18 | // with this library; see the file COPYING3. If not see | |
19 | // <http://www.gnu.org/licenses/>. | |
20 | ||
21 | #include <functional> | |
22 | #include <type_traits> | |
23 | ||
24 | struct S { }; | |
25 | ||
26 | struct S0 | |
27 | { | |
28 | typedef int argument_type; | |
29 | }; | |
30 | ||
31 | struct S1 | |
32 | { | |
33 | typedef float first_argument_type; | |
34 | }; | |
35 | ||
36 | struct S2 | |
37 | { | |
38 | typedef char second_argument_type; | |
39 | }; | |
40 | ||
41 | struct S01 : S0, S1 { }; | |
42 | struct S02 : S0, S2 { }; | |
43 | struct S12 : S1, S2 { }; | |
44 | ||
45 | struct S012 : S0, S1, S2 { }; | |
46 | ||
c6e805a7 | 47 | using std::true_type; |
48 | using std::false_type; | |
bf564680 | 49 | using std::__void_t; |
409e2405 | 50 | |
51 | _GLIBCXX_HAS_NESTED_TYPE(argument_type) | |
52 | _GLIBCXX_HAS_NESTED_TYPE(first_argument_type) | |
53 | _GLIBCXX_HAS_NESTED_TYPE(second_argument_type) | |
54 | ||
55 | template<typename T> | |
56 | struct has_arg_type : __has_argument_type<T> | |
57 | { }; | |
58 | ||
59 | template<typename T> | |
60 | struct has_1st_arg_type : __has_first_argument_type<T> | |
61 | { }; | |
62 | ||
63 | template<typename T> | |
64 | struct has_2nd_arg_type : __has_second_argument_type<T> | |
65 | { }; | |
66 | ||
67 | template<typename T, bool = has_arg_type<T>::value> | |
68 | struct test_arg_type | |
69 | { | |
70 | static_assert( !has_arg_type<std::reference_wrapper<T>>::value, | |
71 | "reference_wrapper has no nested argument_type"); | |
72 | }; | |
73 | ||
74 | template<typename T> | |
75 | struct test_arg_type<T, true> | |
76 | { | |
77 | typedef std::reference_wrapper<T> ref; | |
78 | ||
79 | static_assert( has_arg_type<ref>::value, | |
80 | "reference_wrapper has nested argument_type"); | |
81 | ||
82 | static_assert( | |
83 | std::is_same< typename T::argument_type, | |
84 | typename ref::argument_type >::value, | |
85 | "reference_wrapper has the correct argument_type"); | |
86 | }; | |
87 | ||
88 | template<typename T, | |
89 | bool = has_1st_arg_type<T>::value && has_2nd_arg_type<T>::value> | |
90 | struct test_1st_2nd_arg_types | |
91 | { | |
92 | typedef std::reference_wrapper<T> ref; | |
93 | ||
94 | static_assert( !has_1st_arg_type<ref>::value, | |
95 | "reference_wrapper has no nested first_argument_type"); | |
96 | ||
97 | static_assert( !has_2nd_arg_type<ref>::value, | |
98 | "reference_wrapper has no nested second_argument_type"); | |
99 | }; | |
100 | ||
101 | template<typename T> | |
102 | struct test_1st_2nd_arg_types<T, true> | |
103 | { | |
104 | typedef std::reference_wrapper<T> ref; | |
105 | ||
106 | static_assert( has_1st_arg_type<ref>::value, | |
107 | "reference_wrapper has nested first_argument_type"); | |
108 | ||
109 | static_assert( has_2nd_arg_type<ref>::value, | |
110 | "reference_wrapper has nested second_argument_type"); | |
111 | ||
112 | static_assert( | |
113 | std::is_same< typename T::first_argument_type, | |
114 | typename ref::first_argument_type>::value, | |
115 | "reference_wrapper has correct first_argument_type"); | |
116 | ||
117 | static_assert( | |
118 | std::is_same< typename T::second_argument_type, | |
119 | typename ref::second_argument_type>::value, | |
120 | "reference_wrapper has correct second_argument_type"); | |
121 | }; | |
122 | ||
123 | ||
124 | template<typename T> | |
125 | void test() | |
126 | { | |
ec54e51f | 127 | test_arg_type<T> t __attribute__((unused)); |
128 | test_arg_type<const T> tc __attribute__((unused)); | |
129 | test_arg_type<volatile T> tv __attribute__((unused)); | |
130 | test_arg_type<const volatile T> tcv __attribute__((unused)); | |
131 | test_1st_2nd_arg_types<T> t12 __attribute__((unused)); | |
132 | test_1st_2nd_arg_types<const T> t12c __attribute__((unused)); | |
133 | test_1st_2nd_arg_types<volatile T> t12v __attribute__((unused)); | |
134 | test_1st_2nd_arg_types<const volatile T> t12cv __attribute__((unused)); | |
409e2405 | 135 | } |
136 | ||
137 | int main() | |
138 | { | |
139 | test<S>(); | |
140 | test<S0>(); | |
141 | test<S1>(); | |
142 | test<S2>(); | |
143 | test<S01>(); | |
144 | test<S02>(); | |
145 | test<S12>(); | |
146 | test<S012>(); | |
147 | } | |
148 |