1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// SPDX-FileCopyrightText: 2024 - 2025 Kohei Yoshida
//
// SPDX-License-Identifier: MIT
#include "test_main.hpp"
namespace {
/**
* This value is not copyable; only moveable.
*/
struct move_data
{
std::string value;
move_data() = default;
move_data(const move_data&) = delete;
move_data(move_data&&) = default;
move_data& operator=(const move_data&) = delete;
move_data& operator=(move_data&&) = default;
move_data(std::string _value) : value(std::move(_value))
{}
move_data(const char* _value) : value(_value)
{}
bool operator==(const move_data& r) const noexcept
{
return value == r.value;
}
bool operator<(const move_data& r) const noexcept
{
return value < r.value;
}
};
} // anonymous namespace
void st_test_move_constructor()
{
MDDS_TEST_FUNC_SCOPE;
using db_type = mdds::segment_tree<float, move_data>;
db_type db;
db.insert(-2, 10, "-2:10");
db.insert(5, 20, "5:20");
db.insert(6, 15, "6:15");
db.build_tree();
// Since the value type is only moveable, this must trigger the move
// constructor, not the copy constructor.
db_type db_moved(std::move(db));
{
TEST_ASSERT(db_moved.valid_tree());
TEST_ASSERT(db_moved.size() == 3);
auto results = db_moved.search(19);
TEST_ASSERT(results.size() == 1);
const auto& v = *results.begin();
TEST_ASSERT(v.start == 5);
TEST_ASSERT(v.end == 20);
TEST_ASSERT(v.value == "5:20");
TEST_ASSERT(std::next(results.begin()) == results.end());
}
db_type db_assigned;
db_assigned = std::move(db_moved); // move assignment
{
TEST_ASSERT(db_assigned.valid_tree());
TEST_ASSERT(db_assigned.size() == 3);
auto results = db_assigned.search(19);
TEST_ASSERT(results.size() == 1);
const auto& v = *results.begin();
TEST_ASSERT(v.start == 5);
TEST_ASSERT(v.end == 20);
TEST_ASSERT(v.value == "5:20");
TEST_ASSERT(std::next(results.begin()) == results.end());
}
}
void st_test_move_equality()
{
MDDS_TEST_FUNC_SCOPE;
using db_type = mdds::segment_tree<float, move_data>;
db_type db1;
db1.insert(-2, 10, "-2:10");
db1.insert(5, 20, "5:20");
db1.insert(6, 15, "6:15");
db_type db2;
db2.insert(-2, 10, "-2:10");
db2.insert(5, 20, "5:20");
db2.insert(6, 15, "6:15");
TEST_ASSERT(db1 == db2);
db2.insert(8, 22, "8:22");
TEST_ASSERT(db1 != db2);
db1.insert(8, 22, "8:22");
TEST_ASSERT(db1 == db2);
db1.erase_if([](float, float, const move_data& v) { return v.value == "-2:10"; });
TEST_ASSERT(db1 != db2);
db2.erase_if([](float, float, const move_data& v) { return v.value == "-2:10"; });
TEST_ASSERT(db1 == db2);
db1.build_tree();
TEST_ASSERT(db1 != db2);
db2.build_tree();
TEST_ASSERT(db1 == db2);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|