mirror of
https://github.com/moveit/moveit_task_constructor.git
synced 2025-11-04 14:49:57 +08:00
Property: provide a fallback serialize() implementation
... in case operator<< is not defined for type T
This commit is contained in:
parent
cf84f261a0
commit
2106c51c9d
@ -49,6 +49,14 @@
|
||||
namespace moveit {
|
||||
namespace task_constructor {
|
||||
|
||||
// hasSerialize<T>::value provides a true/false constexpr depending on whether operator<< is supported.
|
||||
// This uses SFINAE, extracted from https://jguegant.github.io/blogs/tech/sfinae-introduction.html
|
||||
template <typename T, typename = std::ostream&>
|
||||
struct hasSerialize : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct hasSerialize<T, decltype(std::declval<std::ostringstream&>() << std::declval<T>())> : std::true_type {};
|
||||
|
||||
class Property;
|
||||
class PropertyMap;
|
||||
|
||||
@ -74,13 +82,18 @@ class Property {
|
||||
const Property::SerializeFunction &serialize);
|
||||
|
||||
template <typename T>
|
||||
static std::string serialize(const boost::any& value) {
|
||||
static typename std::enable_if<hasSerialize<T>::value, std::string>::type serialize(const boost::any& value) {
|
||||
if (value.empty()) return "";
|
||||
std::ostringstream oss;
|
||||
oss << boost::any_cast<T>(value);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static typename std::enable_if<!hasSerialize<T>::value, std::string>::type serialize(const boost::any& value) {
|
||||
throw std::runtime_error (std::string("no operator<< for type ") + typeid(T).name());
|
||||
}
|
||||
|
||||
public:
|
||||
/// base class for Property exceptions
|
||||
class error;
|
||||
|
||||
@ -80,9 +80,13 @@ TEST(Property, reset) {
|
||||
TEST(Property, serialize) {
|
||||
PropertyMap props;
|
||||
props.declare<int>("int");
|
||||
EXPECT_STREQ(props.property("int").serialize().c_str(), "");
|
||||
EXPECT_EQ(props.property("int").serialize(), "");
|
||||
props.set("int", 42);
|
||||
EXPECT_STREQ(props.property("int").serialize().c_str(), "42");
|
||||
EXPECT_EQ(props.property("int").serialize(), "42");
|
||||
|
||||
// std::map doesn't provide operator<< serialization
|
||||
props.declare<std::map<int, int>>("map", std::map<int, int>());
|
||||
EXPECT_THROW(props.property("map").serialize(), std::runtime_error);
|
||||
}
|
||||
|
||||
class InitFromTest : public ::testing::Test {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user