38 #include <type_traits> 40 #include <boost/utility/string_ref.hpp> 66 const uint32_t
size = *(
reinterpret_cast<const uint32_t*
>( &raw[0] ));
67 const char* data = (&raw[4]);
81 std::swap(
_storage.raw_string, other._storage.raw_string);
82 std::swap(
_type, other._type);
86 _storage.raw_data = other._storage.raw_data;
95 const uint32_t
size = *(
reinterpret_cast<const uint32_t*
>( &raw[0] ));
96 const char* data = (&raw[4]);
106 template<
typename T>
Variant(
const T& value);
109 Variant(
const char* buffer,
size_t length);
113 template<
typename T> T
convert( )
const;
115 template<
typename T> T
extract( )
const;
117 template <
typename T>
void assign(
const T& value);
119 void assign(
const char* buffer,
size_t length);
141 static_assert (std::numeric_limits<T>::is_specialized ||
142 std::is_same<T, ros::Time>::value ||
143 std::is_same<T, boost::string_ref>::value ||
144 std::is_same<T, std::string>::value ||
145 std::is_same<T, ros::Duration>::value
146 ,
"not a valid type");
171 static_assert (std::numeric_limits<T>::is_specialized ||
172 std::is_same<T, ros::Time>::value ||
173 std::is_same<T, ros::Duration>::value
174 ,
"not a valid type");
176 if(
_type != RosIntrospection::getType<T>() )
180 return *
reinterpret_cast<const T*
>( &
_storage.raw_data[0] );
190 const uint32_t
size = *(
reinterpret_cast<const uint32_t*
>( &
_storage.raw_string[0] ));
191 char* data =
static_cast<char*
>(&
_storage.raw_string[4]);
192 return boost::string_ref(data, size);
201 const uint32_t
size = *(
reinterpret_cast<const uint32_t*
>( &
_storage.raw_string[0] ));
202 char* data =
static_cast<char*
>(&
_storage.raw_string[4]);
203 return std::string(data, size);
210 static_assert (std::numeric_limits<T>::is_specialized ||
211 std::is_same<T, ros::Time>::value ||
212 std::is_same<T, ros::Duration>::value
213 ,
"not a valid type");
216 _type = RosIntrospection::getType<T>() ;
217 *
reinterpret_cast<T *
>( &
_storage.raw_data[0] ) = value;
234 _storage.raw_string =
new char[size+5];
235 *
reinterpret_cast<uint32_t *
>( &
_storage.raw_string[0] ) = size;
236 memcpy(&
_storage.raw_string[4] , buffer, size );
244 assign( value.data(), value.size() );
249 assign( value.data(), value.size() );
256 static_assert (std::numeric_limits<DST>::is_specialized ||
257 std::is_same<DST, ros::Time>::value ||
258 std::is_same<DST, ros::Duration>::value
259 ,
"not a valid type");
269 case INT8: convert_impl<int8_t, DST>(*
reinterpret_cast<const int8_t*
>(
raw_data), target );
break;
271 case INT16: convert_impl<int16_t, DST>(*
reinterpret_cast<const int16_t*
>(
raw_data), target );
break;
272 case INT32: convert_impl<int32_t, DST>(*
reinterpret_cast<const int32_t*
>(
raw_data), target );
break;
273 case INT64: convert_impl<int64_t, DST>(*
reinterpret_cast<const int64_t*
>(
raw_data), target );
break;
277 case UINT8: convert_impl<uint8_t, DST>(*
reinterpret_cast<const uint8_t*
>(
raw_data), target );
break;
279 case UINT16: convert_impl<uint16_t, DST>(*
reinterpret_cast<const uint16_t*
>(
raw_data), target );
break;
280 case UINT32: convert_impl<uint32_t, DST>(*
reinterpret_cast<const uint32_t*
>(
raw_data), target );
break;
281 case UINT64: convert_impl<uint64_t, DST>(*
reinterpret_cast<const uint64_t*
>(
raw_data), target );
break;
283 case FLOAT32: convert_impl<float, DST>(*
reinterpret_cast<const float*
>(
raw_data), target );
break;
284 case FLOAT64: convert_impl<double, DST>(*
reinterpret_cast<const double*
>(
raw_data), target );
break;
287 throw TypeException(
"String will not be converted to a numerical value implicitly");
292 throw TypeException(
"ros::Duration and ros::Time can be converted only to double (will be seconds)");
295 default:
throw TypeException(
"Variant::convert -> cannot convert type" + std::to_string(
_type));
break;
310 case INT8: convert_impl<int8_t, double>(*
reinterpret_cast<const int8_t*
>(
raw_data), target );
break;
312 case INT16: convert_impl<int16_t, double>(*
reinterpret_cast<const int16_t*
>(
raw_data), target );
break;
313 case INT32: convert_impl<int32_t, double>(*
reinterpret_cast<const int32_t*
>(
raw_data), target );
break;
314 case INT64: convert_impl<int64_t, double>(*
reinterpret_cast<const int64_t*
>(
raw_data), target );
break;
318 case UINT8: convert_impl<uint8_t, double>(*
reinterpret_cast<const uint8_t*
>(
raw_data), target );
break;
320 case UINT16: convert_impl<uint16_t, double>(*
reinterpret_cast<const uint16_t*
>(
raw_data), target );
break;
321 case UINT32: convert_impl<uint32_t, double>(*
reinterpret_cast<const uint32_t*
>(
raw_data), target );
break;
322 case UINT64: convert_impl<uint64_t, double>(*
reinterpret_cast<const uint64_t*
>(
raw_data), target );
break;
324 case FLOAT32: convert_impl<float, double>(*
reinterpret_cast<const float*
>(
raw_data), target );
break;
325 case FLOAT64:
return extract<double>();
328 throw TypeException(
"String will not be converted to a double implicitly");
333 target = tmp.
toSec();
338 target = tmp.
toSec();
341 default:
throw TypeException(
"Variant::convert -> cannot convert type" + std::to_string(
_type));
351 throw TypeException(
"Variant::convert -> cannot convert ros::Time");
353 return extract<ros::Time>();
360 throw TypeException(
"Variant::convert -> cannot convert ros::Duration");
362 return extract<ros::Duration>();
370 throw TypeException(
"Variant::convert -> cannot convert to std::string");
372 return extract<std::string>();
void clearStringIfNecessary()
void assign(const T &value)
BuiltinType getTypeID() const
Variant & operator=(const Variant &other)
Variant(const Variant &other)
union RosIntrospection::Variant::@2 _storage
std::array< uint8_t, 8 > raw_data
span_constexpr std::size_t size(span< T, Extent > const &spn)