Skip to content

Commit

Permalink
Write tests for complex copy and move situations
Browse files Browse the repository at this point in the history
This exercises edge cases in the copy and move constructors and
assignment operators for value types that are nontrivial.
  • Loading branch information
Bobobalink authored and alexkaratarakis committed Jul 10, 2024
1 parent f83906e commit 41f5073
Show file tree
Hide file tree
Showing 2 changed files with 256 additions and 0 deletions.
124 changes: 124 additions & 0 deletions test/fixed_map_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,130 @@ TEST(FixedMap, NonAssignable)
}
}

TEST(FixedMap, ComplexNontrivialCopies)
{
FixedMap<int, MockNonTrivialCopyAssignable, 30> map_1{};
for (int i = 0; i < 20; i++)
{
map_1.try_emplace(i + 100);
}

auto map_2{map_1};
for(const auto& pair : map_1)
{
EXPECT_TRUE(map_2.contains(pair.first));
}
EXPECT_EQ(map_2.size(), map_1.size());
map_2.clear();
for (int i = 0; i < 11; i++)
{
map_2.try_emplace(i + 100);
}
auto map_3{map_1};
for(const auto& pair : map_1)
{
EXPECT_TRUE(map_3.contains(pair.first));
}
EXPECT_EQ(map_3.size(), map_1.size());
map_3.clear();
for (int i = 0; i < 27; i++)
{
map_3.try_emplace(i + 100);
}
auto map_4{map_1};
for(const auto& pair : map_1)
{
EXPECT_TRUE(map_4.contains(pair.first));
}
EXPECT_EQ(map_4.size(), map_1.size());

map_1 = map_2;
for(const auto& pair : map_2)
{
EXPECT_TRUE(map_1.contains(pair.first));
}
map_1.clear();
map_1 = map_3;
for(const auto& pair : map_3)
{
EXPECT_TRUE(map_1.contains(pair.first));
}

// check that we can still add 3 elements (gets us to capacity)
map_1.try_emplace(127);
map_1.try_emplace(128);
map_1.try_emplace(129);
for (int i = 0; i < 30; i++)
{
EXPECT_TRUE(map_1.contains(i + 100));
}
EXPECT_EQ(map_1.size(), 30);

map_1.clear();
map_1 = map_4;
for(const auto& pair : map_4)
{
EXPECT_TRUE(map_1.contains(pair.first));
}
map_1.clear();
}

TEST(FixedUnorderedMap, ComplexNontrivialMoves)
{
using FM = FixedMap<int, MockMoveableButNotCopyable, 30>;
FM map_1{};
FM map_1_orig{};
for (int i = 0; i < 20; i++)
{
map_1.try_emplace(i + 100);
map_1_orig.try_emplace(i + 100);
}

FM map_2{std::move(map_1)};
for(const auto& pair : map_1_orig)
{
EXPECT_TRUE(map_2.contains(pair.first));
}
FM map_2_orig{};
map_2.clear();
for (int i = 0; i < 11; i++)
{
map_2.try_emplace(i + 100);
map_2_orig.try_emplace(i + 100);
}
FM map_3{};
FM map_3_orig{};
map_3.clear();
for (int i = 0; i < 27; i++)
{
map_3.try_emplace(i + 100);
map_3_orig.try_emplace(i + 100);
}

map_1 = std::move(map_2);
for(const auto& pair : map_2_orig)
{
EXPECT_TRUE(map_1.contains(pair.first));
}
map_1.clear();
map_1 = std::move(map_3);
for(const auto& pair : map_3_orig)
{
EXPECT_TRUE(map_1.contains(pair.first));
}

// check that we can still add 3 elements (gets us to capacity)
map_1.try_emplace(127);
map_1.try_emplace(128);
map_1.try_emplace(129);
for (int i = 0; i < 30; i++)
{
EXPECT_TRUE(map_1.contains(i + 100));
}
EXPECT_EQ(map_1.size(), 30);
map_1.clear();
}

static constexpr int INT_VALUE_10 = 10;
static constexpr int INT_VALUE_20 = 20;
static constexpr int INT_VALUE_30 = 30;
Expand Down
132 changes: 132 additions & 0 deletions test/fixed_unordered_map_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,138 @@ TEST(FixedUnorderedMap, NonAssignable)
}
}


TEST(FixedUnorderedMap, ComplexNontrivialCopies)
{
FixedUnorderedMap<int, MockNonTrivialCopyAssignable, 30> map_1{};
for (int i = 0; i < 20; i++)
{
map_1.try_emplace(i + 100);
}

auto map_2{map_1};
for(const auto& pair : map_1)
{
EXPECT_TRUE(map_2.contains(pair.first));
}
EXPECT_EQ(map_2.size(), map_1.size());
map_2.clear();
for (int i = 0; i < 11; i++)
{
map_2.try_emplace(i + 100);
}
auto map_3{map_1};
for(const auto& pair : map_1)
{
EXPECT_TRUE(map_3.contains(pair.first));
}
EXPECT_EQ(map_3.size(), map_1.size());
map_3.clear();
for (int i = 0; i < 27; i++)
{
map_3.try_emplace(i + 100);
}
auto map_4{map_1};
for(const auto& pair : map_1)
{
EXPECT_TRUE(map_4.contains(pair.first));
}
EXPECT_EQ(map_4.size(), map_1.size());

map_1 = map_2;
for(const auto& pair : map_2)
{
EXPECT_TRUE(map_1.contains(pair.first));
}
map_1.clear();
map_1 = map_3;
for(const auto& pair : map_3)
{
EXPECT_TRUE(map_1.contains(pair.first));
}

// check that we can still add 3 elements (gets us to capacity)
map_1.try_emplace(127);
map_1.try_emplace(128);
map_1.try_emplace(129);
for (int i = 0; i < 30; i++)
{
EXPECT_TRUE(map_1.contains(i + 100));
}
EXPECT_EQ(map_1.size(), 30);

// make sure the underlying storage agrees that we're full
EXPECT_TRUE(map_1.IMPLEMENTATION_DETAIL_DO_NOT_USE_table_.IMPLEMENTATION_DETAIL_DO_NOT_USE_value_storage_.IMPLEMENTATION_DETAIL_DO_NOT_USE_storage_.full());

map_1.clear();
map_1 = map_4;
for(const auto& pair : map_4)
{
EXPECT_TRUE(map_1.contains(pair.first));
}
map_1.clear();
}

TEST(FixedUnorderedMap, ComplexNontrivialMoves)
{
using FUM = FixedUnorderedMap<int, MockMoveableButNotCopyable, 30>;
FUM map_1{};
FUM map_1_orig{};
for (int i = 0; i < 20; i++)
{
map_1.try_emplace(i + 100);
map_1_orig.try_emplace(i + 100);
}

FUM map_2{std::move(map_1)};
for(const auto& pair : map_1_orig)
{
EXPECT_TRUE(map_2.contains(pair.first));
}
FUM map_2_orig{};
map_2.clear();
for (int i = 0; i < 11; i++)
{
map_2.try_emplace(i + 100);
map_2_orig.try_emplace(i + 100);
}
FUM map_3{};
FUM map_3_orig{};
map_3.clear();
for (int i = 0; i < 27; i++)
{
map_3.try_emplace(i + 100);
map_3_orig.try_emplace(i + 100);
}

map_1 = std::move(map_2);
for(const auto& pair : map_2_orig)
{
EXPECT_TRUE(map_1.contains(pair.first));
}
map_1.clear();
map_1 = std::move(map_3);
for(const auto& pair : map_3_orig)
{
EXPECT_TRUE(map_1.contains(pair.first));
}

// check that we can still add 3 elements (gets us to capacity)
map_1.try_emplace(127);
map_1.try_emplace(128);
map_1.try_emplace(129);
for (int i = 0; i < 30; i++)
{
EXPECT_TRUE(map_1.contains(i + 100));
}
EXPECT_EQ(map_1.size(), 30);

// make sure the underlying storage agrees that we're full
EXPECT_TRUE(map_1.IMPLEMENTATION_DETAIL_DO_NOT_USE_table_.IMPLEMENTATION_DETAIL_DO_NOT_USE_value_storage_.IMPLEMENTATION_DETAIL_DO_NOT_USE_storage_.full());

map_1.clear();
}

static constexpr int INT_VALUE_10 = 10;
static constexpr int INT_VALUE_20 = 20;
static constexpr int INT_VALUE_30 = 30;
Expand Down

0 comments on commit 41f5073

Please sign in to comment.