Skip to content

Allow upcasting #944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c105c75
Enable polymorphic shared_ptr downcasting in Any using type traits
captain-yoshi Apr 2, 2025
14815b5
Enable blackboard matching for types sharing a common base class
captain-yoshi Apr 2, 2025
6183340
Add test fixture for Greeter type hierarchy and type trait registration
captain-yoshi Apr 2, 2025
d644f67
Add unit test for Any/Blackboard type casting
captain-yoshi Apr 2, 2025
f403fb6
Avoid std::is_polymorphic instantiation on incomplete types
captain-yoshi Apr 3, 2025
5829a40
Refactor castPtr() to unify shared_ptr casting logic
captain-yoshi Apr 4, 2025
4a2e42c
Support recursive root base resolution for polymorphic shared_ptr types
captain-yoshi Apr 17, 2025
6f0c367
Adjust any_cast_base<FancyHelloGreeter> to map to HelloGreeter
captain-yoshi Apr 17, 2025
d313bec
Add compile-time base class chain introspection using any_cast_base
captain-yoshi Apr 18, 2025
f90f822
Extend TypeInfo to store and expose base class chain
captain-yoshi Apr 18, 2025
423e970
Add unit test for upcasting base type chain in PortInfo
captain-yoshi Apr 18, 2025
8ac0c1c
Use original typeid for shared_ptr types in TypeInfo::Create()
captain-yoshi Apr 18, 2025
12c1377
Add PortInfo constructors that accept TypeInfo for cleaner initializa…
captain-yoshi Apr 18, 2025
42b1d80
Allow port type mismatch if convertible via base class chain
captain-yoshi Apr 18, 2025
5090086
Improve test coverage for polymorphic port casting
captain-yoshi Apr 18, 2025
eda2683
Make test platform-independent by relaxing exact exception message check
captain-yoshi Apr 18, 2025
cad9a05
Refactor upcasting tests to use clearer Animal hierarchy example
captain-yoshi Apr 19, 2025
5f94fea
Restrict polymorphic upcast to INPUT ports only during type resolution
captain-yoshi Apr 19, 2025
1ce5185
Revert to direct type_index comparison in Blackboard::set()
captain-yoshi Apr 19, 2025
67276dd
Add caching mechanism for derived castPtr() in Any
captain-yoshi Apr 19, 2025
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
52 changes: 50 additions & 2 deletions include/behaviortree_cpp/basic_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,27 @@ class TypeInfo
template <typename T>
static TypeInfo Create()
{
// store the base class typeid if specialized
if constexpr(is_shared_ptr<T>::value)
{
using Elem = typename T::element_type;
using Base = typename any_cast_base<Elem>::type;

if constexpr(!std::is_same_v<Base, void>)
{
using RootBase = root_base_t<Elem>;

static_assert(is_polymorphic_safe_v<RootBase>, "TypeInfo Base trait "
"specialization "
"must be "
"polymorphic");

using Chain = compute_base_chain<Elem>;
auto base_chain = to_type_index_vector(Chain{});

return TypeInfo(typeid(T), GetAnyFromStringFunctor<T>(), std::move(base_chain));
}
}
return TypeInfo{ typeid(T), GetAnyFromStringFunctor<T>() };
}

Expand All @@ -360,6 +381,14 @@ class TypeInfo
: type_info_(type_info), converter_(conv), type_str_(BT::demangle(type_info))
{}

TypeInfo(std::type_index type_info, StringConverter conv,
std::vector<std::type_index>&& base_chain)
: type_info_(type_info)
, converter_(conv)
, type_str_(BT::demangle(type_info))
, base_chain_(std::move(base_chain))
{}

[[nodiscard]] const std::type_index& type() const;

[[nodiscard]] const std::string& typeName() const;
Expand All @@ -385,10 +414,21 @@ class TypeInfo
return converter_;
}

[[nodiscard]] bool isConvertibleFrom(const std::type_index& other) const
{
return std::find(base_chain_.begin(), base_chain_.end(), other) != base_chain_.end();
}

[[nodiscard]] const std::vector<std::type_index>& baseChain() const
{
return base_chain_;
}

private:
std::type_index type_info_;
StringConverter converter_;
std::string type_str_;
std::vector<std::type_index> base_chain_;
};

class PortInfo : public TypeInfo
Expand All @@ -402,6 +442,14 @@ class PortInfo : public TypeInfo
: TypeInfo(type_info, conv), direction_(direction)
{}

PortInfo(PortDirection direction, const TypeInfo& type_info)
: TypeInfo(type_info), direction_(direction)
{}

PortInfo(PortDirection direction, TypeInfo&& type_info)
: TypeInfo(std::move(type_info)), direction_(direction)
{}

[[nodiscard]] PortDirection direction() const;

void setDescription(StringView description);
Expand Down Expand Up @@ -452,7 +500,8 @@ template <typename T = AnyTypeAllowed>
}
else
{
out = { sname, PortInfo(direction, typeid(T), GetAnyFromStringFunctor<T>()) };
auto type_info = TypeInfo::Create<T>();
out = { sname, PortInfo(direction, std::move(type_info)) };
}
if(!description.empty())
{
Expand Down Expand Up @@ -501,7 +550,6 @@ BidirectionalPort(StringView name, StringView description = {})

namespace details
{

template <typename T = AnyTypeAllowed, typename DefaultT = T>
[[nodiscard]] inline std::pair<std::string, PortInfo>
PortWithDefault(PortDirection direction, StringView name, const DefaultT& default_value,
Expand Down
1 change: 0 additions & 1 deletion include/behaviortree_cpp/blackboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace BT
{

/// This type contains a pointer to Any, protected
/// with a locked mutex as long as the object is in scope
using AnyPtrLocked = LockedPtr<Any>;
Expand Down
Loading
Loading