Skip to content

Commit e3b0cd7

Browse files
committed
Support vector<Any> -> vector<typename T::value_type> conversion
Don't check port type alignment for vector<Any>
1 parent 1fcb624 commit e3b0cd7

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

include/behaviortree_cpp/tree_node.h

+26
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030

3131
namespace BT
3232
{
33+
// Helper trait to check if a type is a std::vector
34+
template <typename T>
35+
struct is_vector : std::false_type {};
36+
37+
template <typename T, typename A>
38+
struct is_vector<std::vector<T, A>> : std::true_type {};
3339

3440
/// This information is used mostly by the XMLParser.
3541
struct TreeNodeManifest
@@ -521,6 +527,26 @@ inline Expected<Timestamp> TreeNode::getInputStamped(const std::string& key,
521527

522528
if(!entry->value.empty())
523529
{
530+
// Support vector<Any> -> vector<typename T::value_type> conversion.
531+
// Only want to compile this path when T is a vector type.
532+
if constexpr (is_vector<T>::value)
533+
{
534+
if (!std::is_same_v<T, std::vector<Any>> && any_value.type() == typeid(std::vector<Any>))
535+
{
536+
// If the object was originally placed on the blackboard as a vector<Any>, attempt to unwrap the vector
537+
// elements according to the templated type.
538+
auto any_vec = any_value.cast<std::vector<Any>>();
539+
if (!any_vec.empty() && any_vec.front().type() != typeid(typename T::value_type))
540+
{
541+
return nonstd::make_unexpected("Invalid cast requested from vector<Any> to vector<typename T::value_type>."
542+
" Element type does not align.");
543+
}
544+
destination = T();
545+
std::transform(any_vec.begin(), any_vec.end(), std::back_inserter(destination),
546+
[](Any &element) { return element.cast<typename T::value_type>(); });
547+
return Timestamp{ entry->sequence_id, entry->stamp };
548+
}
549+
}
524550
if(!std::is_same_v<T, std::string> && any_value.isString())
525551
{
526552
destination = parseString<T>(any_value.cast<std::string>());

src/xml_parsing.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -786,8 +786,10 @@ TreeNode::Ptr XMLParser::PImpl::createNodeFromXML(const XMLElement* element,
786786

787787
// special case related to convertFromString
788788
bool const string_input = (prev_info->type() == typeid(std::string));
789+
// special case related to unwrapping vector<Any> objects.
790+
bool const vec_any_input = (prev_info->type() == typeid(std::vector<Any>));
789791

790-
if(port_type_mismatch && !string_input)
792+
if(port_type_mismatch && !string_input && !vec_any_input)
791793
{
792794
blackboard->debugMessage();
793795

0 commit comments

Comments
 (0)