Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/rfl/Box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,12 @@ class Box {
T* get() const { return ptr_.get(); }

/// Copy assignment operator - only available when C == Copyability::COPYABLE.
/// Replaces the contained object with a deep copy of the other one. The copy
/// is made before the old object is destroyed, so the other Box may be part
/// of the object it replaces.
/// @param other The Box to copy from
/// @return Reference to this Box
Box& operator=(const Box<T>& other) requires (C == Copyability::COPYABLE) {
Box& operator=(const Box& other) requires (C == Copyability::COPYABLE) {
if(this != &other) {
ptr_ = std::make_unique<T>(*other);
}
Expand Down
42 changes: 42 additions & 0 deletions tests/generic/test_box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,46 @@ TEST(generic, copyable_box) {
EXPECT_NE(lesser_leaf_tree1.value, lesser_leaf_tree2.value);

}

TEST(generic, copyable_box_copy_assignment) {
const auto make_leaf = [](const double _value) {
return rfl::make_copyable_box<DecisionTree>(
DecisionTree{DecisionTree::Leaf{.value = _value}});
};

const auto value_of = [](const rfl::CopyableBox<DecisionTree>& _box) {
return rfl::get<DecisionTree::Leaf>(_box->leaf_or_node.get().variant())
.value;
};

const auto box1 = make_leaf(3.0);
auto box2 = make_leaf(5.0);

box2 = box1;

EXPECT_EQ(value_of(box2), 3.0);
EXPECT_NE(box1.get(), box2.get());

const DecisionTree::Node node1{.critical_value = 10.0,
.lesser = make_leaf(1.0),
.greater = make_leaf(2.0)};
auto node2 = DecisionTree::Node{.critical_value = 20.0,
.lesser = make_leaf(4.0),
.greater = make_leaf(5.0)};

node2 = node1;

EXPECT_EQ(node2.critical_value.get(), 10.0);
EXPECT_EQ(value_of(node2.lesser), 1.0);
EXPECT_EQ(value_of(node2.greater), 2.0);
EXPECT_NE(node1.lesser.get(), node2.lesser.get());

// The source may be part of the value it replaces.
auto root = rfl::make_copyable_box<DecisionTree>(
DecisionTree{.leaf_or_node = node1});
root = rfl::get<DecisionTree::Node>(root->leaf_or_node.get().variant())
.lesser;

EXPECT_EQ(value_of(root), 1.0);
}
} // namespace test_copyable_box