Skip to content

Commit

Permalink
Merge pull request #14 from hit9/dev
Browse files Browse the repository at this point in the history
0.4.2: Enable Move for base Node class
  • Loading branch information
hit9 authored Jun 20, 2024
2 parents bd5f831 + 5ed7fea commit bcfb8e5
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
18 changes: 14 additions & 4 deletions bt.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2024 Chao Wang <[email protected]>.
// License: BSD, Version: 0.4.1. https://github.com/hit9/bt.cc
// License: BSD, Version: 0.4.2. https://github.com/hit9/bt.cc
// A lightweight behavior tree library that separates data and behavior.

#ifndef HIT9_BT_H
Expand Down Expand Up @@ -73,7 +73,11 @@ class ITreeBlob {
virtual void reserve(const std::size_t cap) {}

public:
virtual ~ITreeBlob() {}
// virtual destructor is required for unique_ptr.
// this also disables move, but we don't declare default move constructor generation here, since there's no
// member stored here.
virtual ~ITreeBlob() = default;

// Returns a pointer to given NodeBlob B for the node with given id.
// Allocates if not exist.
// Parameter cb is an optional function to be called after the blob is first allocated.
Expand Down Expand Up @@ -196,7 +200,13 @@ class Node {
using Blob = NodeBlob;

explicit Node(std::string_view name = "Node") : name(name) {}
// Destructor is required by unique_ptr.
// And this disabled default generation for move constructors.
virtual ~Node() = default;
// We have to declare move constructor and assignment methods generation explicitly.
// So that the sub classes will support fully move semantics.
Node(Node&&) noexcept = default; // move constructor
Node& operator=(Node&&) noexcept = default; // move assignment operator

// Simple Getters
// ~~~~~~~~~~~~~~
Expand Down Expand Up @@ -852,7 +862,6 @@ class Builder : public _InternalBuilderBase {

public:
Builder() : _InternalBuilderBase() {} // cppcheck-suppress uninitMemberVar
~Builder() {}

// Should be called on the end of the build process.
void End() {
Expand Down Expand Up @@ -882,6 +891,7 @@ class Builder : public _InternalBuilderBase {
return attachInternalNode(make<T>(false, std::forward<Args>(args)...));
}
// Attach a node through move, rarely used.
// The inst should be a node object that supports move semantics.
template <TNode T>
auto& M(T&& inst) {
if constexpr (std::is_base_of_v<LeafNode, T>) // LeafNode
Expand Down Expand Up @@ -1083,7 +1093,7 @@ class Builder : public _InternalBuilderBase {
// .End();
auto& Subtree(RootNode&& subtree) {
onSubtreeAttach(subtree, root);
return M<RootNode>(std::move(subtree)); // move
return M<RootNode>(std::move(subtree)); // move the subtree object
}
};

Expand Down
6 changes: 6 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
0.4.2
-----

* Enable default move constructor and move assigment generation for class Node.
* Remove unnessary destructor for class Builder.

0.4.1
-----

Expand Down
3 changes: 3 additions & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ run:
clean:
make -C build clean

run-benchmark:
cd build && ./bt_benchmark

.PHONY: build
19 changes: 19 additions & 0 deletions tests/misc_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <catch2/catch_template_test_macros.hpp>
#include <catch2/catch_test_macros.hpp>
#include <string>

#include "types.h"

TEST_CASE("Misc/1", "[any node should be movable]") {
J j1{"a really looooooooong name to avoid the string SSO optimization",
"a really looooooooong s string to avoid the string SSO optimization"};
auto addr11 = static_cast<void*>(j1.s.data());
auto addr12 = static_cast<const void*>(j1.Name().data());
J j2(std::move(j1));
auto addr21 = static_cast<void*>(j2.s.data());
auto addr22 = static_cast<const void*>(j2.Name().data());
// The two address of underlying data should be the same if the movement successful done.
REQUIRE(addr11 == addr21);
// And the base class Node's underlying storage should also movable.
REQUIRE(addr12 == addr22);
}
7 changes: 7 additions & 0 deletions tests/types.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <string>

#include "bt.h"

Expand Down Expand Up @@ -146,3 +147,9 @@ class I : public bt::ActionNode {
return bb->shouldPriorityI;
}
};

class J : public bt::ActionNode {
public:
std::string s;
J(const std::string& name, const std::string& s) : bt::ActionNode(name), s(s) {}
};

0 comments on commit bcfb8e5

Please sign in to comment.