Skip to content

Commit 356598c

Browse files
committed
Add freestanding tests
1 parent ac8aae2 commit 356598c

File tree

2 files changed

+325
-0
lines changed

2 files changed

+325
-0
lines changed

tests/beman/inplace_vector/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ add_gtest(constructors)
4242
add_gtest(size_n_data)
4343
add_gtest(erasure)
4444
add_gtest(modifiers)
45+
add_gtest(freestanding)
4546

4647
# only add noexception tests if NO_EXCEPTIONS option is set and compiler supports -fno-exceptions
4748
if(
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
#include <array>
2+
#include <beman/inplace_vector/inplace_vector.hpp>
3+
#include <gtest/gtest.h>
4+
5+
// constexpr void assign(InputIterator first, InputIterator last);
6+
template <typename, typename = std::void_t<>>
7+
struct has_assign_iterator : std::false_type {};
8+
template <typename T>
9+
struct has_assign_iterator<T, std::void_t<decltype(std::declval<T>().assign(
10+
std::declval<typename T::iterator>(),
11+
std::declval<typename T::iterator>()))>>
12+
: std::true_type {};
13+
14+
// constexpr void assign_range(R&& rg);
15+
template <typename T, typename R, typename = void>
16+
struct has_assign_range : std::false_type {};
17+
template <typename T, typename R>
18+
struct has_assign_range<T, R,
19+
std::void_t<decltype(std::declval<T &>().assign_range(
20+
std::declval<R &&>()))>> : std::true_type {};
21+
22+
// constexpr void assign(size_type n, const T& u);
23+
template <typename T, typename = void>
24+
struct has_assign_size : std::false_type {};
25+
template <typename T>
26+
struct has_assign_size<T, std::void_t<decltype(std::declval<T>().assign(
27+
std::declval<typename T::size_type>(),
28+
std::declval<typename T::const_reference>()))>>
29+
: std::true_type {};
30+
31+
// constexpr void assign(initializer_list il);
32+
template <typename T, typename = void>
33+
struct has_assign_initializer : std::false_type {};
34+
template <typename T>
35+
struct has_assign_initializer<
36+
T, std::void_t<decltype(std::declval<T>().assign(
37+
std::declval<std::initializer_list<typename T::value_type>>()))>>
38+
: std::true_type {};
39+
40+
// constexpr void resize(size_type sz);
41+
template <typename T, typename = void> struct has_resize : std::false_type {};
42+
template <typename T>
43+
struct has_resize<T, std::void_t<decltype(std::declval<T>().resize(
44+
std::declval<typename T::size_type>()))>>
45+
: std::true_type {};
46+
47+
// constexpr void resize(size_type sz, const T& c);
48+
template <typename T, typename = void>
49+
struct has_resize_ref : std::false_type {};
50+
template <typename T>
51+
struct has_resize_ref<T, std::void_t<decltype(std::declval<T>().resize(
52+
std::declval<typename T::size_type>(),
53+
std::declval<typename T::const_reference>()))>>
54+
: std::true_type {};
55+
56+
// void reserve(size_type n);
57+
template <typename T, typename = void> struct has_reserve : std::false_type {};
58+
template <typename T>
59+
struct has_reserve<T, std::void_t<decltype(std::declval<T>().reserve(
60+
std::declval<typename T::size_type>()))>>
61+
: std::true_type {};
62+
63+
// constexpr reference at(size_type n);
64+
template <typename T, typename = void> struct has_at : std::false_type {};
65+
template <typename T>
66+
struct has_at<T, std::void_t<decltype(std::declval<T>().at(
67+
std::declval<typename T::size_type>()))>>
68+
: std::true_type {};
69+
70+
// constexpr const_reference at(size_type n) const;
71+
template <typename T, typename = void> struct has_const_at : std::false_type {};
72+
template <typename T>
73+
struct has_const_at<T, std::void_t<decltype(std::declval<const T>().at(
74+
std::declval<typename T::size_type>()))>>
75+
: std::true_type {};
76+
77+
// emplace_back(Args&&... args);
78+
template <typename T, typename = void>
79+
struct has_emplace_back : std::false_type {};
80+
template <typename T>
81+
struct has_emplace_back<T, std::void_t<decltype(std::declval<T>().emplace_back(
82+
std::declval<typename T::value_type>()))>>
83+
: std::true_type {};
84+
85+
// constexpr reference push_back(const T& x);
86+
template <typename T, typename = void>
87+
struct has_push_back_const : std::false_type {};
88+
template <typename T>
89+
struct has_push_back_const<T,
90+
std::void_t<decltype(std::declval<T>().push_back(
91+
std::declval<typename T::const_reference>()))>>
92+
: std::true_type {};
93+
94+
// constexpr reference push_back(T&& x);
95+
template <typename T, typename = void>
96+
struct has_push_back_rv : std::false_type {};
97+
template <typename T>
98+
struct has_push_back_rv<T, std::void_t<decltype(std::declval<T>().push_back(
99+
std::declval<typename T::value_type>()))>>
100+
: std::true_type {};
101+
102+
// constexpr void append_range(R&& rg);
103+
template <typename T, typename R, typename = void>
104+
struct has_append_range : std::false_type {};
105+
template <typename T, typename R>
106+
struct has_append_range<
107+
T, R,
108+
std::void_t<decltype(std::declval<T>().append_range(std::declval<R &&>()))>>
109+
: std::true_type {};
110+
111+
// constexpr iterator emplace(const_iterator position, Args&&... args);
112+
template <typename T, typename = void> struct has_emplace : std::false_type {};
113+
template <typename T>
114+
struct has_emplace<T, std::void_t<decltype(std::declval<T>().emplace(
115+
std::declval<typename T::const_iterator>(),
116+
std::declval<typename T::value_type>()))>>
117+
: std::true_type {};
118+
119+
// constexpr iterator insert(const_iterator position, const T& x);
120+
template <typename T, typename = void>
121+
struct has_insert_const : std::false_type {};
122+
template <typename T>
123+
struct has_insert_const<T, std::void_t<decltype(std::declval<T>().insert(
124+
std::declval<typename T::const_iterator>(),
125+
std::declval<typename T::const_reference>()))>>
126+
: std::true_type {};
127+
128+
// constexpr iterator insert(const_iterator position, T&& x);
129+
template <typename T, typename = void>
130+
struct has_insert_rv : std::false_type {};
131+
template <typename T>
132+
struct has_insert_rv<T, std::void_t<decltype(std::declval<T>().insert(
133+
std::declval<typename T::const_iterator>(),
134+
std::declval<typename T::value_type>()))>>
135+
: std::true_type {};
136+
137+
// constexpr iterator insert(const_iterator position, size_type n, const T& x);
138+
template <typename T, typename = void>
139+
struct has_insert_size : std::false_type {};
140+
template <typename T>
141+
struct has_insert_size<T, std::void_t<decltype(std::declval<T>().insert(
142+
std::declval<typename T::const_iterator>(),
143+
std::declval<typename T::size_type>(),
144+
std::declval<typename T::const_reference>()))>>
145+
: std::true_type {};
146+
147+
// constexpr iterator insert(const_iterator position, InputIterator first,
148+
// InputIterator last);
149+
template <typename T, typename = void>
150+
struct has_insert_iterator : std::false_type {};
151+
template <typename T>
152+
struct has_insert_iterator<T, std::void_t<decltype(std::declval<T>().insert(
153+
std::declval<typename T::const_iterator>(),
154+
std::declval<typename T::iterator>(),
155+
std::declval<typename T::iterator>()))>>
156+
: std::true_type {};
157+
158+
// InputIterator last); constexpr iterator insert_range(const_iterator position,
159+
// R&& rg);
160+
template <typename T, typename R, typename = void>
161+
struct has_insert_range : std::false_type {};
162+
template <typename T, typename R>
163+
struct has_insert_range<
164+
T, R,
165+
std::void_t<decltype(std::declval<T>().insert_range(
166+
std::declval<typename T::const_iterator>(), std::declval<R &&>()))>>
167+
: std::true_type {};
168+
169+
// constexpr iterator insert(const_iterator position, initializer_list il);
170+
template <typename T, typename = void>
171+
struct has_insert_initializer : std::false_type {};
172+
template <typename T>
173+
struct has_insert_initializer<
174+
T, std::void_t<decltype(std::declval<T>().insert(
175+
std::declval<typename T::const_iterator>(),
176+
std::declval<std::initializer_list<typename T::value_type>>()))>>
177+
: std::true_type {};
178+
179+
TEST(Freestanding, deleted) {
180+
181+
using IV = beman::inplace_vector<int, 10>;
182+
using FIV = beman::freestanding::inplace_vector<int, 10>;
183+
184+
using range = std::array<int, 10>;
185+
using input_iterator = std::istream_iterator<int>;
186+
using initializer_list = std::initializer_list<int>;
187+
188+
IV::value_type v;
189+
190+
// constexpr explicit inplace_vector(size_type n);
191+
static_assert(std::is_constructible_v<IV, std::size_t>);
192+
static_assert(!std::is_constructible_v<FIV, std::size_t>);
193+
194+
// constexpr inplace_vector(size_type n, const T& value);
195+
static_assert(std::is_constructible_v<IV, std::size_t, IV::const_reference>);
196+
static_assert(
197+
!std::is_constructible_v<FIV, std::size_t, IV::const_reference>);
198+
199+
// constexpr inplace_vector(InputIterator first, InputIterator last);
200+
static_assert(std::is_constructible_v<IV, input_iterator, input_iterator>);
201+
static_assert(!std::is_constructible_v<FIV, input_iterator, input_iterator>);
202+
203+
// constexpr inplace_vector(from_range_t, R&& rg);
204+
static_assert(std::is_constructible_v<IV, beman::from_range_t, range>);
205+
static_assert(!std::is_constructible_v<FIV, beman::from_range_t, range>);
206+
207+
// constexpr inplace_vector(initializer_list<T> il);
208+
static_assert(std::is_constructible_v<IV, initializer_list>);
209+
static_assert(!std::is_constructible_v<FIV, initializer_list>);
210+
211+
// constexpr inplace_vector& operator=(initializer_list<T>);
212+
static_assert(std::is_assignable_v<IV &, initializer_list>);
213+
static_assert(!std::is_assignable_v<FIV &, initializer_list>);
214+
215+
// constexpr void assign(InputIterator first, InputIterator last)
216+
static_assert(has_assign_iterator<IV>::value);
217+
static_assert(!has_assign_iterator<FIV>::value);
218+
219+
// constexpr void assign_range(R&& rg);
220+
static_assert(has_assign_range<IV, range>::value);
221+
static_assert(!has_assign_range<FIV, range>::value);
222+
223+
// constexpr void assign(size_type n, const T& u);
224+
static_assert(has_assign_size<IV>::value);
225+
static_assert(!has_assign_size<FIV>::value);
226+
227+
// constexpr void assign(initializer_list il);
228+
static_assert(has_assign_initializer<IV>::value);
229+
static_assert(!has_assign_initializer<FIV>::value);
230+
231+
// constexpr void resize(size_type sz);
232+
static_assert(has_resize<IV>::value);
233+
static_assert(!has_resize<FIV>::value);
234+
235+
// constexpr void resize(size_type sz, const T& c);
236+
static_assert(has_resize_ref<IV>::value);
237+
static_assert(!has_resize_ref<FIV>::value);
238+
239+
// void reserve(size_type n);
240+
static_assert(has_reserve<IV>::value);
241+
static_assert(!has_reserve<FIV>::value);
242+
243+
// constexpr reference at(size_type n);
244+
static_assert(has_at<IV>::value);
245+
static_assert(!has_at<FIV>::value);
246+
247+
// constexpr const_reference at(size_type n) const;
248+
static_assert(has_const_at<IV>::value);
249+
static_assert(!has_const_at<FIV>::value);
250+
251+
// emplace_back(Args&&... args);
252+
static_assert(has_emplace_back<IV>::value);
253+
static_assert(!has_emplace_back<FIV>::value);
254+
255+
// constexpr reference push_back(const T& x);
256+
static_assert(has_push_back_const<IV>::value);
257+
static_assert(!has_push_back_const<FIV>::value);
258+
259+
// constexpr reference push_back(T&& x);
260+
static_assert(has_push_back_rv<IV>::value);
261+
static_assert(!has_push_back_rv<FIV>::value);
262+
263+
// constexpr void append_range(R&& rg);
264+
static_assert(has_append_range<IV, range>::value);
265+
static_assert(!has_append_range<FIV, range>::value);
266+
267+
// constexpr iterator emplace(const_iterator position, Args&&... args);
268+
static_assert(has_emplace<IV>::value);
269+
static_assert(!has_emplace<FIV>::value);
270+
271+
// constexpr iterator insert(const_iterator position, const T& x);
272+
static_assert(has_insert_const<IV>::value);
273+
static_assert(!has_insert_const<FIV>::value);
274+
275+
// constexpr iterator insert(const_iterator position, T&& x);
276+
static_assert(has_insert_rv<IV>::value);
277+
static_assert(!has_insert_rv<FIV>::value);
278+
279+
// constexpr iterator insert(const_iterator position, size_type n, T& x);
280+
static_assert(has_insert_size<IV>::value);
281+
static_assert(!has_insert_size<FIV>::value);
282+
283+
// constexpr iterator insert(const_iterator position, InputIterator first,
284+
static_assert(has_insert_iterator<IV>::value);
285+
static_assert(!has_insert_iterator<FIV>::value);
286+
287+
// InputIterator last); constexpr iterator insert_range(const_iterator
288+
// position, R&& rg);
289+
static_assert(has_insert_range<IV, range>::value);
290+
static_assert(!has_insert_range<FIV, range>::value);
291+
292+
// constexpr iterator insert(const_iterator position, initializer_list il);
293+
static_assert(has_insert_initializer<IV>::value);
294+
static_assert(!has_insert_initializer<FIV>::value);
295+
296+
EXPECT_TRUE(true);
297+
}
298+
299+
TEST(Freestanding, usage) {
300+
using IV = beman::freestanding::inplace_vector<int, 10>;
301+
using T = IV::value_type;
302+
303+
IV device;
304+
305+
EXPECT_EQ(device.size(), 0);
306+
307+
for (auto i = 0; i < device.capacity(); ++i) {
308+
const auto value = T{i};
309+
auto res = device.try_emplace_back(value);
310+
EXPECT_NE(res, nullptr);
311+
EXPECT_EQ(*res, value);
312+
EXPECT_EQ(device.back(), value);
313+
}
314+
315+
EXPECT_EQ(device.size(), device.capacity());
316+
317+
for (auto i = int(device.capacity()); i > 0; --i) {
318+
const auto value = T{i - 1};
319+
EXPECT_EQ(device.back(), value);
320+
device.pop_back();
321+
}
322+
323+
EXPECT_EQ(device.size(), 0);
324+
}

0 commit comments

Comments
 (0)