1 // { dg-do "run" }
2 #include <cassert>
3 
4 struct A
5 {
6   double a;
7   double b;
8 };
9 
10 struct B
11 {
12   A a;
13 };
14 
15 struct C
16 : public A { };
17 
18 struct D
19 {
DD20   D() throw() { }
21 };
22 
23 struct E
24 {
EE25   E() throw(int) { }
26 };
27 
28 struct E1
29 {
E1E130   E1() throw(int) { throw int(); }
31 };
32 
33 struct F
34 {
FF35   F(const F&) throw() { }
36 };
37 
38 struct G
39 {
GG40   G(const G&) throw(int) { throw int(); }
41 };
42 
43 template<typename T>
44   bool
f()45   f()
46   { return __has_nothrow_constructor(T); }
47 
48 template<typename T>
49   class My
50   {
51   public:
52     bool
f()53     f()
54     { return !!__has_nothrow_constructor(T); }
55   };
56 
57 template<typename T>
58   class My2
59   {
60   public:
61     static const bool trait = __has_nothrow_constructor(T);
62   };
63 
64 template<typename T>
65   const bool My2<T>::trait;
66 
67 
68 template<typename T, bool b = __has_nothrow_constructor(T)>
69   struct My3_help
70   { static const bool trait = b; };
71 
72 template<typename T, bool b>
73   const bool My3_help<T, b>::trait;
74 
75 template<typename T>
76   class My3
77   {
78   public:
79     bool
f()80     f()
81     { return My3_help<T>::trait; }
82   };
83 
84 #define PTEST(T) (__has_nothrow_constructor(T) && f<T>() \
85                   && My<T>().f() && My2<T>::trait && My3<T>().f())
86 
87 #define NTEST(T) (!__has_nothrow_constructor(T) && !f<T>() \
88                   && !My<T>().f() && !My2<T>::trait && !My3<T>().f())
89 
main()90 int main()
91 {
92   assert (PTEST (int));
93   assert (NTEST (int (int)));
94   assert (NTEST (void));
95   assert (PTEST (A));
96   assert (PTEST (B));
97   assert (PTEST (C));
98   assert (PTEST (C[]));
99   assert (PTEST (D));
100   assert (NTEST (E));
101   assert (NTEST (E1));
102   assert (NTEST (F));
103   assert (NTEST (G));
104 
105   return 0;
106 }
107