152
|
1 // Copyright (C) 2020 Free Software Foundation, Inc.
|
|
2 //
|
|
3 // This file is part of the GNU ISO C++ Library. This library is free
|
|
4 // software; you can redistribute it and/or modify it under the
|
|
5 // terms of the GNU General Public License as published by the
|
|
6 // Free Software Foundation; either version 3, or (at your option)
|
|
7 // any later version.
|
|
8
|
|
9 // This library is distributed in the hope that it will be useful,
|
|
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12 // GNU General Public License for more details.
|
|
13
|
|
14 // You should have received a copy of the GNU General Public License along
|
|
15 // with this library; see the file COPYING3. If not see
|
|
16 // <http://www.gnu.org/licenses/>.
|
|
17
|
|
18 // { dg-do compile { target c++11 } }
|
|
19
|
|
20 #include <ext/new_allocator.h>
|
|
21 #include <memory>
|
|
22 #include <type_traits>
|
|
23
|
|
24 using __gnu_cxx::new_allocator;
|
|
25 using AT = std::allocator_traits<new_allocator<int>>;
|
|
26
|
|
27 template<typename...> using void_t = void;
|
|
28
|
|
29 template<typename T, typename U, typename = void>
|
|
30 struct has_construct
|
|
31 : std::false_type
|
|
32 { };
|
|
33
|
|
34 template<typename T, typename U>
|
|
35 struct has_construct<T, U,
|
|
36 void_t<decltype(std::declval<T&>().construct(std::declval<U*>()))>>
|
|
37 : std::true_type
|
|
38 { };
|
|
39
|
|
40 template<typename T, typename U, typename = void>
|
|
41 struct has_destroy
|
|
42 : std::false_type
|
|
43 { };
|
|
44
|
|
45 template<typename T, typename U>
|
|
46 struct has_destroy<T, U,
|
|
47 void_t<decltype(std::declval<T&>().destroy(std::declval<U*>()))>>
|
|
48 : std::true_type
|
|
49 { };
|
|
50
|
|
51 template<typename T, typename U, typename = void>
|
|
52 struct has_traits_construct
|
|
53 : std::false_type
|
|
54 { };
|
|
55
|
|
56 template<typename T, typename U>
|
|
57 struct has_traits_construct<T, U,
|
|
58 void_t<decltype(AT::construct(std::declval<T&>(), std::declval<U*>()))>>
|
|
59 : std::true_type
|
|
60 { };
|
|
61
|
|
62 template<typename T, typename U, typename = void>
|
|
63 struct has_traits_destroy
|
|
64 : std::false_type
|
|
65 { };
|
|
66
|
|
67 template<typename T, typename U>
|
|
68 struct has_traits_destroy<T, U,
|
|
69 void_t<decltype(AT::destroy(std::declval<T&>(), std::declval<U*>()))>>
|
|
70 : std::true_type
|
|
71 { };
|
|
72
|
|
73 struct NoDefault { NoDefault(int); };
|
|
74 struct NoDest { private: ~NoDest(); };
|
|
75
|
|
76 // Whether true or false, these should not give errors:
|
|
77 constexpr bool c = has_construct<new_allocator<NoDefault>, NoDefault>::value;
|
|
78 constexpr bool c2 = has_traits_construct<new_allocator<int>, NoDefault>::value;
|
|
79 constexpr bool d = has_destroy<new_allocator<NoDest>, NoDest>::value;
|
|
80 constexpr bool d2 = has_traits_destroy<new_allocator<int>, NoDest>::value;
|
|
81
|
|
82 new_allocator<int> a;
|
|
83
|
|
84 long* lp;
|
|
85 #if __cplusplus <= 201703L
|
|
86 static_assert( noexcept(a.construct(lp)), "" );
|
|
87 static_assert( noexcept(a.construct(lp, 1L)), "" );
|
|
88 static_assert( noexcept(a.construct(lp, 2)), "" );
|
|
89 static_assert( noexcept(a.construct(lp, 2U)), "" );
|
|
90 static_assert( noexcept(a.destroy(lp)), "" );
|
|
91 #endif
|
|
92 static_assert( noexcept(AT::construct(a, lp)), "" );
|
|
93 static_assert( noexcept(AT::construct(a, lp, 1L)), "" );
|
|
94 static_assert( noexcept(AT::construct(a, lp, 2)), "" );
|
|
95 static_assert( noexcept(AT::construct(a, lp, 2U)), "" );
|
|
96 static_assert( noexcept(AT::destroy(a, lp)), "" );
|
|
97
|
|
98 struct X
|
|
99 {
|
|
100 X() noexcept;
|
|
101 X(int) noexcept;
|
|
102 ~X() noexcept;
|
|
103 };
|
|
104
|
|
105 X* xp;
|
|
106 #if __cplusplus <= 201703L
|
|
107 static_assert( noexcept(a.construct(xp)), "" );
|
|
108 static_assert( noexcept(a.construct(xp, 1)), "" );
|
|
109 static_assert( noexcept(a.destroy(xp)), "" );
|
|
110 #endif
|
|
111 static_assert( noexcept(AT::construct(a, xp)), "" );
|
|
112 static_assert( noexcept(AT::construct(a, xp, 1)), "" );
|
|
113 static_assert( noexcept(AT::destroy(a, xp)), "" );
|
|
114
|
|
115 struct Y
|
|
116 {
|
|
117 Y() noexcept;
|
|
118 Y(int) noexcept(false);
|
|
119 ~Y() noexcept;
|
|
120 };
|
|
121
|
|
122 Y* yp;
|
|
123 #if __cplusplus <= 201703L
|
|
124 static_assert( noexcept(a.construct(yp)), "" );
|
|
125 static_assert( ! noexcept(a.construct(yp, 1)), "" );
|
|
126 static_assert( noexcept(a.destroy(yp)), "" );
|
|
127 #endif
|
|
128 static_assert( noexcept(AT::construct(a, yp)), "" );
|
|
129 static_assert( ! noexcept(AT::construct(a, yp, 1)), "" );
|
|
130 static_assert( noexcept(AT::destroy(a, yp)), "" );
|
|
131
|
|
132 struct Z
|
|
133 {
|
|
134 Z() noexcept;
|
|
135 Z(int) noexcept;
|
|
136 ~Z() noexcept(false);
|
|
137 };
|
|
138
|
|
139 Z* zp;
|
|
140 // These construct calls should be noexcept, but they are false because
|
|
141 // they use is_nothrow_constructible which depends on is_nothrow_destructible.
|
|
142 #if __cplusplus <= 201703L
|
|
143 static_assert( ! noexcept(a.construct(zp)), "wrong" );
|
|
144 static_assert( ! noexcept(a.construct(zp, 1)), "wrong" );
|
|
145 static_assert( ! noexcept(a.destroy(zp)), "" );
|
|
146 #endif
|
|
147 static_assert( ! noexcept(AT::construct(a, zp)), "" );
|
|
148 static_assert( ! noexcept(AT::construct(a, zp, 1)), "" );
|
|
149 static_assert( ! noexcept(AT::destroy(a, zp)), "" );
|