@@ -58,6 +58,84 @@ class PropertyMap;
58
58
// / initializer function, using given name from the passed property map
59
59
boost::any fromName (const PropertyMap& other, const std::string& other_name);
60
60
61
+ // hasSerialize<T>::value provides a true/false constexpr depending on whether operator<< is supported.
62
+ // This uses SFINAE, extracted from https://jguegant.github.io/blogs/tech/sfinae-introduction.html
63
+ template <typename T, typename = std::ostream&>
64
+ struct hasSerialize : std::false_type
65
+ {};
66
+
67
+ template <typename T>
68
+ struct hasSerialize <T, decltype (std::declval<std::ostream&>() << std::declval<T>())> : std::true_type
69
+ {};
70
+
71
+ template <typename T, typename = std::istream&>
72
+ struct hasDeserialize : std::false_type
73
+ {};
74
+
75
+ template <typename T>
76
+ struct hasDeserialize <T, decltype (std::declval<std::istream&>() >> std::declval<T&>())> : std::true_type
77
+ {};
78
+
79
+ class PropertySerializerBase
80
+ {
81
+ public:
82
+ using SerializeFunction = std::string (*)(const boost::any&);
83
+ using DeserializeFunction = boost::any (*)(const std::string&);
84
+
85
+ static std::string dummySerialize (const boost::any& /* unused*/ ) { return " " ; }
86
+ static boost::any dummyDeserialize (const std::string& /* unused*/ ) { return boost::any (); }
87
+
88
+ protected:
89
+ static bool insert (const std::type_index& type_index, const std::string& type_name, SerializeFunction serialize,
90
+ DeserializeFunction deserialize);
91
+ };
92
+
93
+ // / utility class to register serializer/deserializer functions for a property of type T
94
+ template <typename T>
95
+ class PropertySerializer : protected PropertySerializerBase
96
+ {
97
+ public:
98
+ PropertySerializer () { insert (typeid (T), typeName<T>(), &serialize, &deserialize); }
99
+
100
+ template <class Q = T>
101
+ static typename std::enable_if<ros::message_traits::IsMessage<Q>::value, std::string>::type typeName () {
102
+ return ros::message_traits::DataType<T>::value ();
103
+ }
104
+
105
+ template <class Q = T>
106
+ static typename std::enable_if<!ros::message_traits::IsMessage<Q>::value, std::string>::type typeName () {
107
+ return typeid (T).name ();
108
+ }
109
+
110
+ private:
111
+ /* * Serialization based on std::[io]stringstream */
112
+ template <class Q = T>
113
+ static typename std::enable_if<hasSerialize<Q>::value, std::string>::type serialize (const boost::any& value) {
114
+ std::ostringstream oss;
115
+ oss << boost::any_cast<T>(value);
116
+ return oss.str ();
117
+ }
118
+ template <class Q = T>
119
+ static typename std::enable_if<hasSerialize<Q>::value && hasDeserialize<Q>::value, boost::any>::type
120
+ deserialize (const std::string& wired) {
121
+ std::istringstream iss (wired);
122
+ T value;
123
+ iss >> value;
124
+ return value;
125
+ }
126
+
127
+ /* * No serialization available */
128
+ template <class Q = T>
129
+ static typename std::enable_if<!hasSerialize<Q>::value, std::string>::type serialize (const boost::any& value) {
130
+ return dummySerialize (value);
131
+ }
132
+ template <class Q = T>
133
+ static typename std::enable_if<!hasSerialize<Q>::value || !hasDeserialize<Q>::value, boost::any>::type
134
+ deserialize (const std::string& wire) {
135
+ return dummyDeserialize (wire);
136
+ }
137
+ };
138
+
61
139
/* * Property is a wrapper for a boost::any value, also providing a default value and a description.
62
140
*
63
141
* Properties can be configured to be initialized from another PropertyMap - if still undefined.
@@ -122,6 +200,16 @@ class Property
122
200
// / function callback used to initialize property value from another PropertyMap
123
201
using InitializerFunction = std::function<boost::any(const PropertyMap&)>;
124
202
203
+ template <typename T>
204
+ static Property fromMsg (const moveit_task_constructor_msgs::Property& msg) {
205
+ auto requested_type{ typeid (T).name () };
206
+ if (msg.type != requested_type) {
207
+ throw type_error{ requested_type, msg.type };
208
+ }
209
+ PropertySerializer<T>(); // register serializer/deserializer
210
+ return Property (typeid (T), msg.description , msg.value );
211
+ };
212
+
125
213
// / set current value and default value
126
214
void setValue (const boost::any& value);
127
215
void setCurrentValue (const boost::any& value);
@@ -185,84 +273,6 @@ class Property
185
273
InitializerFunction initializer_;
186
274
};
187
275
188
- // hasSerialize<T>::value provides a true/false constexpr depending on whether operator<< is supported.
189
- // This uses SFINAE, extracted from https://jguegant.github.io/blogs/tech/sfinae-introduction.html
190
- template <typename T, typename = std::ostream&>
191
- struct hasSerialize : std::false_type
192
- {};
193
-
194
- template <typename T>
195
- struct hasSerialize <T, decltype (std::declval<std::ostream&>() << std::declval<T>())> : std::true_type
196
- {};
197
-
198
- template <typename T, typename = std::istream&>
199
- struct hasDeserialize : std::false_type
200
- {};
201
-
202
- template <typename T>
203
- struct hasDeserialize <T, decltype (std::declval<std::istream&>() >> std::declval<T&>())> : std::true_type
204
- {};
205
-
206
- class PropertySerializerBase
207
- {
208
- public:
209
- using SerializeFunction = std::string (*)(const boost::any&);
210
- using DeserializeFunction = boost::any (*)(const std::string&);
211
-
212
- static std::string dummySerialize (const boost::any& /* unused*/ ) { return " " ; }
213
- static boost::any dummyDeserialize (const std::string& /* unused*/ ) { return boost::any (); }
214
-
215
- protected:
216
- static bool insert (const std::type_index& type_index, const std::string& type_name, SerializeFunction serialize,
217
- DeserializeFunction deserialize);
218
- };
219
-
220
- // / utility class to register serializer/deserializer functions for a property of type T
221
- template <typename T>
222
- class PropertySerializer : protected PropertySerializerBase
223
- {
224
- public:
225
- PropertySerializer () { insert (typeid (T), typeName<T>(), &serialize, &deserialize); }
226
-
227
- template <class Q = T>
228
- static typename std::enable_if<ros::message_traits::IsMessage<Q>::value, std::string>::type typeName () {
229
- return ros::message_traits::DataType<T>::value ();
230
- }
231
-
232
- template <class Q = T>
233
- static typename std::enable_if<!ros::message_traits::IsMessage<Q>::value, std::string>::type typeName () {
234
- return typeid (T).name ();
235
- }
236
-
237
- private:
238
- /* * Serialization based on std::[io]stringstream */
239
- template <class Q = T>
240
- static typename std::enable_if<hasSerialize<Q>::value, std::string>::type serialize (const boost::any& value) {
241
- std::ostringstream oss;
242
- oss << boost::any_cast<T>(value);
243
- return oss.str ();
244
- }
245
- template <class Q = T>
246
- static typename std::enable_if<hasSerialize<Q>::value && hasDeserialize<Q>::value, boost::any>::type
247
- deserialize (const std::string& wired) {
248
- std::istringstream iss (wired);
249
- T value;
250
- iss >> value;
251
- return value;
252
- }
253
-
254
- /* * No serialization available */
255
- template <class Q = T>
256
- static typename std::enable_if<!hasSerialize<Q>::value, std::string>::type serialize (const boost::any& value) {
257
- return dummySerialize (value);
258
- }
259
- template <class Q = T>
260
- static typename std::enable_if<!hasSerialize<Q>::value || !hasDeserialize<Q>::value, boost::any>::type
261
- deserialize (const std::string& wire) {
262
- return dummyDeserialize (wire);
263
- }
264
- };
265
-
266
276
/* * PropertyMap is map of (name, Property) pairs.
267
277
*
268
278
* Conveniency methods are provided to setup property initialization for several
@@ -303,7 +313,8 @@ class PropertyMap
303
313
Property& property (const std::string& name);
304
314
const Property& property (const std::string& name) const { return const_cast <PropertyMap*>(this )->property (name); }
305
315
306
- void fillMsgs (std::vector<moveit_task_constructor_msgs::Property>& msg) const ;
316
+ void fillMsgs (std::vector<moveit_task_constructor_msgs::Property>& msgs) const ;
317
+ void fromMsgs (std::vector<moveit_task_constructor_msgs::Property>& msgs);
307
318
308
319
using iterator = std::map<std::string, Property>::iterator;
309
320
using const_iterator = std::map<std::string, Property>::const_iterator;
0 commit comments