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 moveit {
|
||||||
namespace task_constructor {
|
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 Property;
|
||||||
class PropertyMap;
|
class PropertyMap;
|
||||||
|
|
||||||
@ -74,13 +82,18 @@ class Property {
|
|||||||
const Property::SerializeFunction &serialize);
|
const Property::SerializeFunction &serialize);
|
||||||
|
|
||||||
template <typename T>
|
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 "";
|
if (value.empty()) return "";
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << boost::any_cast<T>(value);
|
oss << boost::any_cast<T>(value);
|
||||||
return oss.str();
|
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:
|
public:
|
||||||
/// base class for Property exceptions
|
/// base class for Property exceptions
|
||||||
class error;
|
class error;
|
||||||
|
|||||||
@ -80,9 +80,13 @@ TEST(Property, reset) {
|
|||||||
TEST(Property, serialize) {
|
TEST(Property, serialize) {
|
||||||
PropertyMap props;
|
PropertyMap props;
|
||||||
props.declare<int>("int");
|
props.declare<int>("int");
|
||||||
EXPECT_STREQ(props.property("int").serialize().c_str(), "");
|
EXPECT_EQ(props.property("int").serialize(), "");
|
||||||
props.set("int", 42);
|
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 {
|
class InitFromTest : public ::testing::Test {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user