Skip to content
Merged
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
39 changes: 37 additions & 2 deletions include/behaviortree_cpp/basic_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <chrono>
#include <iostream>
#include <functional>
#include <sstream>
#include <string_view>
#include <typeinfo>
#include <unordered_map>
Expand Down Expand Up @@ -246,6 +247,18 @@ constexpr bool IsConvertibleToString()

Expected<std::string> toJsonString(const Any& value);

// Helper trait to check if templated type is a std::vector
template <typename T>
struct is_vector : std::false_type
{
};

template <typename T, typename A>
struct is_vector<std::vector<T, A>> : std::true_type
{
using ValueType = T;
};

/**
* @brief toStr is the reverse operation of convertFromString.
*
Expand All @@ -255,19 +268,41 @@ Expected<std::string> toJsonString(const Any& value);
template <typename T>
[[nodiscard]] std::string toStr(const T& value)
{
auto throw_unspecialized_error = []() {
throw LogicError(StrCat("Function BT::toStr<T>() not specialized for type [",
BT::demangle(typeid(T)), "]"));
};

if constexpr(IsConvertibleToString<T>())
{
return static_cast<std::string>(value);
}
else if constexpr(is_vector<T>::value)
{
try
{
using InnerType = typename is_vector<T>::ValueType;
std::stringstream ss;
for(auto it = value.begin(); it != --value.end(); ++it)
{
ss << toStr<InnerType>(*it) << ';';
}
ss << toStr<InnerType>(value.back());
return ss.str();
}
catch(LogicError&)
{
throw_unspecialized_error();
}
}
else if constexpr(!std::is_arithmetic_v<T>)
{
if(auto str = toJsonString(Any(value)))
{
return *str;
}

throw LogicError(StrCat("Function BT::toStr<T>() not specialized for type [",
BT::demangle(typeid(T)), "]"));
throw_unspecialized_error();
}
else
{
Expand Down
11 changes: 0 additions & 11 deletions include/behaviortree_cpp/blackboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,6 @@ struct StampedValue
Timestamp stamp;
};

// Helper trait to check if templated type is a std::vector
template <typename T>
struct is_vector : std::false_type
{
};

template <typename T, typename A>
struct is_vector<std::vector<T, A>> : std::true_type
{
};

// Helper function to check if a demangled type string is a std::vector<..>
inline bool isVector(const std::string& type_name)
{
Expand Down
7 changes: 7 additions & 0 deletions tests/gtest_ports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

using namespace BT;

TEST(toStr, ConvertsVectors)
{
std::string val_str;
ASSERT_NO_THROW(val_str = BT::toStr(std::vector<int>{ 1, 2, 3, 4 }));
EXPECT_EQ(val_str, "1;2;3;4");
}

class NodeWithPorts : public SyncActionNode
{
public:
Expand Down
Loading