Skip to content

Commit 0d37485

Browse files
committed
implement insert ranges series
1 parent cbfe0c4 commit 0d37485

File tree

1 file changed

+192
-25
lines changed

1 file changed

+192
-25
lines changed

tests/beman/inplace_vector/spec.test.cpp

Lines changed: 192 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#include "beman/inplace_vector/inplace_vector.hpp"
22
#include "gtest/gtest.h"
33
#include <algorithm>
4+
#include <array>
45
#include <concepts>
56
#include <iterator>
7+
#include <numeric>
8+
#include <ranges>
69
#include <type_traits>
710

811
namespace {
@@ -1260,23 +1263,9 @@ TYPED_TEST(Modifiers, InsertEmplace) {
12601263
}
12611264

12621265
TYPED_TEST(Modifiers, InsertMulti) {
1263-
// constexpr iterator insert(const_iterator position, const T& x);
1264-
// constexpr iterator insert(const_iterator position, T&& x);
12651266
// constexpr iterator insert(const_iterator position, size_type n, const T&
12661267
// x);
1267-
// template<class InputIterator>
1268-
// constexpr iterator insert(const_iterator position, InputIterator first,
1269-
// InputIterator last);
1270-
// template<container-compatible-range<T> R>
1271-
// constexpr iterator insert_range(const_iterator position, R&& rg);
1272-
// constexpr iterator insert(const_iterator position, initializer_list<T> il);
1273-
// template<class... Args>
1274-
// constexpr iterator emplace(const_iterator position, Args&&... args);
1275-
// template<container-compatible-range<T> R>
1276-
// constexpr void append_range(R&& rg);
12771268
//
1278-
// Let n be the value of size() before this call for the append_range
1279-
// overload, and distance(begin, position) otherwise.
12801269
// Complexity: Linear in the number of elements inserted plus the distance
12811270
// to the end of the vector.
12821271
// Remarks: If an exception is thrown other than by the copy constructor,
@@ -1309,9 +1298,196 @@ TYPED_TEST(Modifiers, InsertMulti) {
13091298
EXPECT_THROW(device.insert(device.begin(), 1, {2538}), beman::bad_alloc);
13101299
}
13111300

1301+
TYPED_TEST(Modifiers, InsertInitList) {
1302+
// constexpr iterator insert(const_iterator position, initializer_list<T> il);
1303+
//
1304+
// Let n be the value of size() before this call for the append_range
1305+
// overload, and distance(begin, position) otherwise.
1306+
// Complexity: Linear in the number of elements inserted plus the distance
1307+
// to the end of the vector.
1308+
// Remarks: If an exception is thrown other than by the copy constructor,
1309+
// move constructor, assignment operator, or move assignment operator of T or
1310+
// by any InputIterator operation, there are no effects. Otherwise, if an
1311+
// exception is thrown, then size()  ≥ n and elements in the range begin() +
1312+
// [0, n) are not modified.
1313+
1314+
using IV = TestFixture::IV;
1315+
using T = TestFixture::T;
1316+
1317+
IV device;
1318+
auto res = device.insert(device.end(), {});
1319+
EXPECT_EQ(res, device.end());
1320+
EXPECT_EQ(device, IV());
1321+
1322+
if (device.capacity() > 0) {
1323+
res = device.insert(device.begin(), {T{0}});
1324+
EXPECT_EQ(res, device.begin());
1325+
EXPECT_EQ(device, IV{T{0}});
1326+
1327+
if (device.capacity() >= 3) {
1328+
res = device.insert(device.begin(), {T{1}, T{2}});
1329+
EXPECT_EQ(res, device.begin());
1330+
1331+
IV expected{T{1}, T{2}, T{0}};
1332+
EXPECT_EQ(device, expected);
1333+
}
1334+
}
1335+
1336+
auto full = this->unique();
1337+
EXPECT_NO_THROW(full.insert(full.begin(), {}));
1338+
EXPECT_THROW(full.insert(full.begin(), {T{25}}), beman::bad_alloc);
1339+
}
1340+
1341+
TYPED_TEST(Modifiers, InsertRange) {
1342+
// template<container-compatible-range<T> R>
1343+
// constexpr iterator insert_range(const_iterator position, R&& rg);
1344+
//
1345+
// Let n be the value of size() before this call for the append_range
1346+
// overload, and distance(begin, position) otherwise.
1347+
// Complexity: Linear in the number of elements inserted plus the distance
1348+
// to the end of the vector.
1349+
// Remarks: If an exception is thrown other than by the copy constructor,
1350+
// move constructor, assignment operator, or move assignment operator of T or
1351+
// by any InputIterator operation, there are no effects. Otherwise, if an
1352+
// exception is thrown, then size()  ≥ n and elements in the range begin() +
1353+
// [0, n) are not modified.
1354+
1355+
using IV = TestFixture::IV;
1356+
using T = TestFixture::T;
1357+
1358+
IV device;
1359+
auto reference = this->unique();
1360+
1361+
auto res = device.insert_range(device.end(), reference | std::views::take(0));
1362+
EXPECT_EQ(res, device.end());
1363+
1364+
res = device.insert_range(device.end(), reference);
1365+
EXPECT_EQ(res, device.begin());
1366+
EXPECT_EQ(device, reference);
1367+
device.clear();
1368+
1369+
if (device.capacity() > 0) {
1370+
res = device.insert_range(device.end(), reference | std::views::take(1));
1371+
EXPECT_EQ(res, device.begin());
1372+
EXPECT_EQ(device, IV({reference.front()}));
1373+
1374+
if (device.capacity() > 1) {
1375+
res = device.insert_range(
1376+
device.begin() + 1,
1377+
std::ranges::subrange(reference.end() - 1, reference.end()));
1378+
EXPECT_EQ(res, device.begin() + 1);
1379+
EXPECT_EQ(device, IV({reference.front(), reference.back()}));
1380+
1381+
if (device.capacity() > 2) {
1382+
res = device.insert_range(device.begin() + 1,
1383+
reference | std::views::drop(1) |
1384+
std::views::take(reference.size() - 2));
1385+
EXPECT_EQ(res, device.begin() + 1);
1386+
EXPECT_EQ(device, reference);
1387+
}
1388+
}
1389+
}
1390+
1391+
EXPECT_NO_THROW(device.insert_range(device.begin(), std::array<T, 0>{}));
1392+
EXPECT_EQ(device, reference);
1393+
1394+
EXPECT_THROW(device.insert_range(device.begin(), std::array<T, 1>{T{25}}),
1395+
beman::bad_alloc);
1396+
}
1397+
1398+
TYPED_TEST(Modifiers, InsertItrRange) {
1399+
// constexpr iterator emplace(const_iterator position, Args&&... args);
1400+
// template<container-compatible-range<T> R>
1401+
// constexpr void append_range(R&& rg);
1402+
//
1403+
// Let n be the value of size() before this call for the append_range
1404+
// overload, and distance(begin, position) otherwise.
1405+
// Complexity: Linear in the number of elements inserted plus the distance
1406+
// to the end of the vector.
1407+
// Remarks: If an exception is thrown other than by the copy constructor,
1408+
// move constructor, assignment operator, or move assignment operator of T or
1409+
// by any InputIterator operation, there are no effects. Otherwise, if an
1410+
// exception is thrown, then size()  ≥ n and elements in the range begin() +
1411+
// [0, n) are not modified.
1412+
1413+
using IV = TestFixture::IV;
1414+
using T = TestFixture::T;
1415+
1416+
IV device;
1417+
auto reference = this->unique();
1418+
1419+
auto res = device.insert(device.end(), reference.end(), reference.end());
1420+
EXPECT_EQ(res, device.end());
1421+
1422+
res = device.insert(device.end(), reference.begin(), reference.end());
1423+
EXPECT_EQ(res, device.begin());
1424+
EXPECT_EQ(device, reference);
1425+
device.clear();
1426+
1427+
if (device.capacity() > 0) {
1428+
res = device.insert(device.end(), reference.begin(), reference.begin() + 1);
1429+
EXPECT_EQ(res, device.begin());
1430+
EXPECT_EQ(device, IV({reference.front()}));
1431+
1432+
if (device.capacity() > 1) {
1433+
res = device.insert(device.begin() + 1, reference.end() - 1,
1434+
reference.end());
1435+
EXPECT_EQ(res, device.begin() + 1);
1436+
EXPECT_EQ(device, IV({reference.front(), reference.back()}));
1437+
1438+
if (device.capacity() > 2) {
1439+
res = device.insert(device.begin() + 1, reference.begin() + 1,
1440+
reference.end() - 1);
1441+
EXPECT_EQ(res, device.begin() + 1);
1442+
EXPECT_EQ(device, reference);
1443+
}
1444+
}
1445+
}
1446+
1447+
EXPECT_NO_THROW(
1448+
device.insert(device.begin(), reference.end(), reference.end()));
1449+
EXPECT_EQ(device, reference);
1450+
1451+
std::array<T, 1> single_array{T{25}};
1452+
EXPECT_THROW(
1453+
device.insert(device.begin(), single_array.begin(), single_array.end()),
1454+
beman::bad_alloc);
1455+
}
1456+
1457+
TYPED_TEST(Modifiers, InsertAppendRange) {
1458+
// template<container-compatible-range<T> R>
1459+
// constexpr void append_range(R&& rg);
1460+
//
1461+
// Let n be the value of size() before this call for the append_range
1462+
// overload, and distance(begin, position) otherwise.
1463+
// Complexity: Linear in the number of elements inserted plus the distance
1464+
// to the end of the vector.
1465+
// Remarks: If an exception is thrown other than by the copy constructor,
1466+
// move constructor, assignment operator, or move assignment operator of T or
1467+
// by any InputIterator operation, there are no effects. Otherwise, if an
1468+
// exception is thrown, then size()  ≥ n and elements in the range begin() +
1469+
// [0, n) are not modified.
1470+
1471+
using IV = TestFixture::IV;
1472+
1473+
IV device;
1474+
auto reference = this->unique();
1475+
1476+
device.append_range(reference | std::views::take(0));
1477+
EXPECT_EQ(device, IV());
1478+
1479+
device.append_range(reference);
1480+
EXPECT_EQ(device, reference);
1481+
device.clear();
1482+
1483+
auto half_size = std::midpoint(0ul, reference.size());
1484+
device.append_range(reference | std::views::take(half_size));
1485+
device.append_range(reference | std::views::drop(half_size));
1486+
EXPECT_EQ(device, reference);
1487+
}
1488+
13121489
TYPED_TEST(Modifiers, PushBackConstRef) {
13131490
// constexpr reference push_back(const T& x);
1314-
// constexpr reference push_back(T&& x);
13151491
//
13161492
// Returns: back().
13171493
// Throws: bad_alloc or any exception thrown by the initialization of the
@@ -1337,7 +1513,6 @@ TYPED_TEST(Modifiers, PushBackConstRef) {
13371513
}
13381514

13391515
TYPED_TEST(Modifiers, PushBackRV) {
1340-
// constexpr reference push_back(const T& x);
13411516
// constexpr reference push_back(T&& x);
13421517
//
13431518
// Returns: back().
@@ -1365,7 +1540,7 @@ TYPED_TEST(Modifiers, PushBackRV) {
13651540

13661541
// TODO: Check if there's extra copies
13671542

1368-
TYPED_TEST(Modifiers, EmplaceBackRV) {
1543+
TYPED_TEST(Modifiers, EmplaceBack) {
13691544
// template<class... Args>
13701545
// constexpr reference emplace_back(Args&&... args);
13711546
//
@@ -1392,8 +1567,6 @@ TYPED_TEST(Modifiers, EmplaceBackRV) {
13921567
TYPED_TEST(Modifiers, TryEmplaceBack) {
13931568
// template<class... Args>
13941569
// constexpr pointer try_emplace_back(Args&&... args);
1395-
// constexpr pointer try_push_back(const T& x);
1396-
// constexpr pointer try_push_back(T&& x);
13971570
//
13981571
// Let vals denote a pack:
13991572
// (8.1) std::forward<Args>(args)... for the first overload,
@@ -1433,10 +1606,7 @@ TYPED_TEST(Modifiers, TryEmplaceBack) {
14331606
}
14341607

14351608
TYPED_TEST(Modifiers, TryPushBackConstRef) {
1436-
// template<class... Args>
1437-
// constexpr pointer try_emplace_back(Args&&... args);
14381609
// constexpr pointer try_push_back(const T& x);
1439-
// constexpr pointer try_push_back(T&& x);
14401610
//
14411611
// Let vals denote a pack:
14421612
// (8.1) std::forward<Args>(args)... for the first overload,
@@ -1480,9 +1650,6 @@ TYPED_TEST(Modifiers, TryPushBackConstRef) {
14801650
}
14811651

14821652
TYPED_TEST(Modifiers, TryPushBackRV) {
1483-
// template<class... Args>
1484-
// constexpr pointer try_emplace_back(Args&&... args);
1485-
// constexpr pointer try_push_back(const T& x);
14861653
// constexpr pointer try_push_back(T&& x);
14871654
//
14881655
// Let vals denote a pack:

0 commit comments

Comments
 (0)