46#include <gtest/gtest.h>
62 explicit Probe(
int v) :
value(v) { ++live; }
63 Probe(
const Probe &p) :
value(p.
value) { ++live; }
64 Probe(Probe &&p) noexcept :
value(p.value) { ++live; }
65 Probe &operator=(
const Probe &) =
default;
66 Probe &operator=(Probe &&) noexcept = default;
76 static int throw_after;
79 explicit Throwing_Copy(
int v) :
value(v) { ++live; }
81 Throwing_Copy(
const Throwing_Copy &x) :
value(x.
value)
83 if (throw_after >= 0
and copies++ >= throw_after)
84 throw std::runtime_error(
"copy failed");
88 Throwing_Copy(Throwing_Copy &&x)
noexcept :
value(x.value) { ++live; }
90 Throwing_Copy &operator=(
const Throwing_Copy &) =
default;
93 ~Throwing_Copy() { --live; }
95 static void reset(
int limit = -1)
102int Throwing_Copy::live = 0;
103int Throwing_Copy::copies = 0;
104int Throwing_Copy::throw_after = -1;
110 Throwing_Move() =
default;
111 explicit Throwing_Move(
int v) :
value(v) {}
112 Throwing_Move(
const Throwing_Move &) =
delete;
113 Throwing_Move(Throwing_Move &&x)
noexcept(
false) :
value(x.
value) {}
114 Throwing_Move &operator=(
const Throwing_Move &) =
delete;
115 Throwing_Move &operator=(Throwing_Move &&) noexcept(false) = default;
120static_assert(not noexcept(
std::declval<
SmallVector<Throwing_Move, 2> &>().swap
131 for (
int i = 0; i < 4; ++i)
134 EXPECT_EQ(v.
size(), 4u);
139 ASSERT_EQ(v.
size(), 5u);
140 for (
int i = 0; i < 5; ++i)
148 const char *obj =
reinterpret_cast<const char *
>(&v);
149 const char *elem =
reinterpret_cast<const char *
>(v.
data());
150 EXPECT_GE(elem, obj);
151 EXPECT_LT(elem, obj +
sizeof(v));
153 for (
int i = 0; i < 10; ++i)
155 const char *heap_elem =
reinterpret_cast<const char *
>(v.
data());
156 EXPECT_TRUE(heap_elem < obj or heap_elem >= obj +
sizeof(v));
161 ASSERT_EQ(Probe::live, 0);
166 EXPECT_EQ(Probe::live, 2);
168 EXPECT_EQ(Probe::live, 3);
170 EXPECT_EQ(Probe::live, 2);
172 EXPECT_EQ(Probe::live, 0);
174 EXPECT_EQ(Probe::live, 1);
176 EXPECT_EQ(Probe::live, 0);
181 ASSERT_EQ(Throwing_Copy::live, 0);
184 Throwing_Copy
value(1);
185 Throwing_Copy::reset(1);
188 EXPECT_EQ(Throwing_Copy::live, 1);
190 EXPECT_EQ(Throwing_Copy::live, 0);
192 Throwing_Copy::reset(1);
194 {Throwing_Copy(1), Throwing_Copy(2), Throwing_Copy(3)}),
196 EXPECT_EQ(Throwing_Copy::live, 0);
199 std::vector<Throwing_Copy> src;
203 ASSERT_EQ(Throwing_Copy::live, 3);
204 Throwing_Copy::reset(1);
207 EXPECT_EQ(Throwing_Copy::live, 3);
209 EXPECT_EQ(Throwing_Copy::live, 0);
216 ASSERT_EQ(Throwing_Copy::live, 3);
217 Throwing_Copy::reset(1);
219 EXPECT_EQ(Throwing_Copy::live, 3);
221 EXPECT_EQ(Throwing_Copy::live, 0);
227 v.
append(std::make_unique<int>(1));
228 v.
append(std::make_unique<int>(2));
229 v.
append(std::make_unique<int>(3));
230 ASSERT_EQ(v.
size(), 3u);
236 EXPECT_EQ(v.
size(), 2u);
239 ASSERT_EQ(moved.
size(), 2u);
240 EXPECT_EQ(*moved[1], 2);
247 EXPECT_EQ(c1, inline_v);
249 EXPECT_EQ(inline_v[0],
"a");
254 EXPECT_EQ(c2, heap_v);
258 ASSERT_EQ(c2.
size(), 1u);
259 EXPECT_EQ(c2[0],
"s");
267 ASSERT_EQ(ma.
size(), 2u);
268 EXPECT_EQ(ma[0],
"x");
273 const std::string *heap_data = b.
data();
275 EXPECT_EQ(mb.
data(), heap_data);
279 EXPECT_EQ(b[0],
"reuse");
286 ASSERT_EQ(v.
size(), 4u);
287 for (
int i = 0; i < 4; ++i)
288 EXPECT_EQ(v[i], i + 1);
302 EXPECT_EQ(v.
size(), 4u);
304 EXPECT_THROW(v.
insert(v.
size() + 1, 9), std::out_of_range);
305 EXPECT_THROW(v.
erase(v.
size()), std::out_of_range);
313 EXPECT_THROW((
void) v[2], std::out_of_range);
316 EXPECT_EQ(cv[0], 10);
317 EXPECT_THROW((
void) cv[5], std::out_of_range);
320 EXPECT_THROW((
void) e.
get_first(), std::underflow_error);
321 EXPECT_THROW((
void) e.
get_last(), std::underflow_error);
322 EXPECT_THROW((
void) e.
remove_last(), std::underflow_error);
323 EXPECT_THROW(e.
pop_back(), std::underflow_error);
338 EXPECT_EQ(
static_cast<size_t>(v.
end() - v.
begin()), v.
size());
346 EXPECT_TRUE(v.
traverse([&sum] (
int &x) { sum += x; return true; }));
351 EXPECT_FALSE(cv.
traverse([&visited] (
const int &x)
356 EXPECT_EQ(visited, 2);
360 EXPECT_EQ(v.
size(), 0u);
373 const int *p = v.
data();
374 for (
int i = 0; i < 90; ++i)
376 EXPECT_EQ(v.
data(), p);
382 EXPECT_THROW(v.
reserve(
static_cast<size_t>(-1)), std::overflow_error);
389 const std::vector<int> src = {5, 6, 7, 8, 9};
391 ASSERT_EQ(v.
size(), 5u);
395 ASSERT_EQ(f.
size(), 3u);
396 EXPECT_EQ(f[2],
"ho");
414 const int *p1 = h1.
data();
415 const int *p2 = h2.
data();
417 EXPECT_EQ(h1.
data(), p2);
418 EXPECT_EQ(h2.
data(), p1);
419 EXPECT_EQ(h1.
size(), 4u);
420 EXPECT_EQ(h2.
size(), 3u);
426 EXPECT_EQ(s1.
size(), 5u);
428 EXPECT_EQ(s2.
size(), 1u);
435 const char src[] = {
'a',
'b',
'c',
'd',
'e',
'f'};
440 ASSERT_EQ(v.
size(), 3u);
441 for (
size_t i = 0; i < 3; ++i)
442 EXPECT_EQ(v[i], src[i]);
446 ASSERT_EQ(v.
size(), 4u);
450 ASSERT_EQ(v.
size(), 6u);
451 for (
size_t i = 0; i < 6; ++i)
452 EXPECT_EQ(v[i], src[i]);
459 EXPECT_EQ(v.
size(), 3u);
466 EXPECT_THROW(v.
append_range(
nullptr, 1), std::invalid_argument);
468 EXPECT_EQ(v.
size(), 3u);
482 const int src[] = {2, 3, 4, 5, 6};
484 ASSERT_EQ(v.
size(), 6u);
486 for (
size_t i = 0; i < 5; ++i)
487 EXPECT_EQ(v[i + 1], src[i]);
492 ASSERT_EQ(Probe::live, 0);
494 Probe src[3] = {Probe(1), Probe(2), Probe(3)};
495 EXPECT_EQ(Probe::live, 3);
499 EXPECT_EQ(Probe::live, 6);
500 ASSERT_EQ(v.
size(), 3u);
501 EXPECT_EQ(v[0].
value, 1);
502 EXPECT_EQ(v[1].
value, 2);
503 EXPECT_EQ(v[2].
value, 3);
505 EXPECT_EQ(Probe::live, 0);
510 ASSERT_EQ(Throwing_Copy::live, 0);
512 Throwing_Copy src[4] = {Throwing_Copy(1), Throwing_Copy(2),
513 Throwing_Copy(3), Throwing_Copy(4)};
518 Throwing_Copy::reset(2);
519 EXPECT_THROW(v.
append_range(src, 4), std::runtime_error);
521 EXPECT_EQ(v.
size(), 0u);
522 EXPECT_EQ(Throwing_Copy::live, 4);
524 Throwing_Copy::reset(-1);
525 EXPECT_EQ(Throwing_Copy::live, 4);
size_t size_t int32_t value
Contiguous dynamic array with N elements of inline storage.
size_t capacity() const noexcept
Return the current capacity (inline or heap). O(1).
size_t size() const noexcept
Return the number of stored elements. O(1).
void reserve(const size_t cap)
Reserve capacity for at least cap elements.
T & get_last()
Last element (checked).
T & emplace_back(Args &&...args)
Construct an element in place at the end.
void append_range(const T *first, const size_t count)
Append count copies from [first, first + count), in order.
T & append(const T &item)
Append a copy of item.
void empty() noexcept
Destroy all elements (Aleph convention).
iterator end() noexcept
Iterator past the last element. O(1).
T * data() noexcept
Pointer to the contiguous element storage. O(1).
bool traverse(Operation operation)
Traverse elements in order while operation returns true.
void swap(SmallVector &v) noexcept(std::is_nothrow_move_constructible_v< T >)
Swap contents with v.
bool is_small() const noexcept
Return true while the elements still live in the inline buffer. O(1).
T remove_last()
Remove and return the last element.
T & get_first()
First element (checked).
T & insert(size_t pos, T item)
Insert an element at position pos, shifting the tail right.
void pop_back()
Remove the last element (STL style).
iterator begin() noexcept
Iterator to the first element. O(1).
void erase(const size_t pos)
Remove the element at position pos, shifting the tail left.
bool is_empty() const noexcept
Return true if no elements are stored. O(1).
void clear() noexcept
Destroy all elements. Alias of empty(). Capacity is kept.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
and
Check uniqueness with explicit hash + equality functors.
Dynamic array with inline storage (Aleph::SmallVector).