Skip to content

Commit fc2e898

Browse files
Merge pull request #40 from damien-robotsix/custom_container_handling
fix: handling of custom containers that has a TypeDefinition
2 parents 4ce21e0 + f2dcee6 commit fc2e898

File tree

6 files changed

+200
-71
lines changed

6 files changed

+200
-71
lines changed

data_tamer_cpp/include/data_tamer/channel.hpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace DataTamer
1111
{
12+
using SerializeMe::has_TypeDefinition;
1213

1314
// Utility
1415
inline std::chrono::nanoseconds NsecSinceEpoch()
@@ -73,7 +74,7 @@ class LogChannel : public std::enable_shared_from_this<LogChannel>
7374
* @param value pointer to the value
7475
* @return the ID to be used to unregister or enable/disable this value.
7576
*/
76-
template <typename T>
77+
template <typename T, bool = true>
7778
RegistrationID registerValue(const std::string& name, const T* value);
7879

7980
/**
@@ -85,7 +86,8 @@ class LogChannel : public std::enable_shared_from_this<LogChannel>
8586
* @param value pointer to the vectors of values.
8687
* @return the ID to be used to unregister or enable/disable the values.
8788
*/
88-
template <template <class, class> class Container, class T, class... TArgs>
89+
template <template <class, class> class Container, class T, class... TArgs,
90+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool> = true>
8991
RegistrationID registerValue(const std::string& name,
9092
const Container<T, TArgs...>* value);
9193

@@ -98,7 +100,8 @@ class LogChannel : public std::enable_shared_from_this<LogChannel>
98100
* @param value pointer to the array of values.
99101
* @return the ID to be used to unregister or enable/disable the values.
100102
*/
101-
template <typename T, size_t N>
103+
template <typename T, size_t N,
104+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool> = true>
102105
RegistrationID registerValue(const std::string& name, const std::array<T, N>* value);
103106

104107
/**
@@ -259,7 +262,7 @@ inline void LogChannel::updateTypeRegistry()
259262
}
260263
}
261264

262-
template <typename T>
265+
template <typename T, bool>
263266
inline RegistrationID LogChannel::registerValue(const std::string& name,
264267
const T* value_ptr)
265268
{
@@ -288,7 +291,8 @@ inline RegistrationID LogChannel::registerCustomValue(const std::string& name,
288291
return registerValueImpl(name, ValuePtr(value_ptr, serializer), serializer);
289292
}
290293

291-
template <template <class, class> class Container, class T, class... TArgs>
294+
template <template <class, class> class Container, class T, class... TArgs,
295+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool>>
292296
inline RegistrationID LogChannel::registerValue(const std::string& prefix,
293297
const Container<T, TArgs...>* vect)
294298
{
@@ -304,7 +308,8 @@ inline RegistrationID LogChannel::registerValue(const std::string& prefix,
304308
}
305309
}
306310

307-
template <typename T, size_t N>
311+
template <typename T, size_t N,
312+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool>>
308313
inline RegistrationID LogChannel::registerValue(const std::string& prefix,
309314
const std::array<T, N>* vect)
310315
{

data_tamer_cpp/include/data_tamer/contrib/SerializeMe.hpp

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -68,46 +68,79 @@ using SpanBytes = Span<uint8_t>;
6868
using SpanBytesConst = Span<uint8_t const>;
6969
using StringSize = uint16_t;
7070

71-
//------------- Forward declarations of BufferSize ------------------
71+
// Check if a Function like this is implemented:
72+
//
73+
// template <typename Func> std::string_view TypeDefinition(T&, Func&);
74+
75+
template <typename T, class = void>
76+
struct has_TypeDefinition : std::false_type
77+
{
78+
};
79+
80+
const auto EmptyFuncion = [](const char*, void*) {};
81+
using EmptyFunc = decltype(EmptyFuncion);
82+
83+
template <typename T1, typename T2>
84+
using enable_if_same_t = std::enable_if_t<std::is_same_v<T1, T2>>;
7285

7386
template <typename T>
87+
struct has_TypeDefinition<
88+
T, enable_if_same_t<std::string_view,
89+
decltype(TypeDefinition(std::declval<T&>(),
90+
std::declval<EmptyFunc&>()))>>
91+
: std::true_type
92+
{
93+
};
94+
95+
//------------- Forward declarations of BufferSize ------------------
96+
97+
template <typename T, bool = true>
7498
size_t BufferSize(const T& val);
7599

76100
template <>
77101
size_t BufferSize(const std::string& str);
78102

79-
template <class T, size_t N>
103+
template <class T, size_t N,
104+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool> = true>
80105
size_t BufferSize(const std::array<T, N>& v);
81106

82-
template <template <class, class> class Container, class T, class... TArgs>
107+
template <
108+
template <class, class> class Container, class T, class... TArgs,
109+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool> = true>
83110
size_t BufferSize(const Container<T, TArgs...>& vect);
84111

85112
//---------- Forward declarations of DeserializeFromBuffer -----------
86113

87-
template <typename T>
114+
template <typename T, bool = true>
88115
void DeserializeFromBuffer(SpanBytesConst& buffer, T& dest);
89116

90117
template <>
91118
void DeserializeFromBuffer(SpanBytesConst& buffer, std::string& str);
92119

93-
template <class T, size_t N>
120+
template <class T, size_t N,
121+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool> = true>
94122
void DeserializeFromBuffer(SpanBytesConst& buffer, std::array<T, N>& v);
95123

96-
template <template <class, class> class Container, class T, class... TArgs>
124+
template <
125+
template <class, class> class Container, class T, class... TArgs,
126+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool> = true>
97127
void DeserializeFromBuffer(SpanBytesConst& buffer, Container<T, TArgs...>& dest);
98128

99129
//---------- Forward declarations of SerializeIntoBuffer -----------
100130

101-
template <typename T>
131+
template <typename T, bool = true>
102132
void SerializeIntoBuffer(SpanBytes& buffer, const T& value);
103133

104134
template <>
105135
void SerializeIntoBuffer(SpanBytes& buffer, const std::string& str);
106136

107-
template <class T, size_t N>
137+
template <class T, size_t N,
138+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool> = true>
108139
void SerializeIntoBuffer(SpanBytes& buffer, const std::array<T, N>& v);
109140

110-
template <template <class, class> class Container, class T, class... TArgs>
141+
template <
142+
template <class, class> class Container, class T, class... TArgs,
143+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool> = true>
111144
void SerializeIntoBuffer(SpanBytes& buffer, const Container<T, TArgs...>& vect);
112145

113146
//-----------------------------------------------------------------------
@@ -150,8 +183,8 @@ inline void Span<T>::trimFront(size_t offset)
150183
#endif // __s390x__
151184
#if !defined(SERIALIZE_LITTLEENDIAN)
152185
#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
153-
#if(defined(__BIG_ENDIAN__) || \
154-
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
186+
#if (defined(__BIG_ENDIAN__) || \
187+
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
155188
#define SERIALIZE_LITTLEENDIAN 0
156189
#else
157190
#define SERIALIZE_LITTLEENDIAN 1
@@ -228,31 +261,6 @@ inline T EndianSwap(T t)
228261
std::runtime_error("Problem with IndianSwap");
229262
}
230263
}
231-
232-
// Check if a Function like this is implemented:
233-
//
234-
// template <typename Func> std::string_view TypeDefinition(T&, Func&);
235-
236-
template <typename T, class = void>
237-
struct has_TypeDefinition : std::false_type
238-
{
239-
};
240-
241-
const auto EmptyFuncion = [](const char*, void*) {};
242-
using EmptyFunc = decltype(EmptyFuncion);
243-
244-
template <typename T1, typename T2>
245-
using enable_if_same_t = std::enable_if_t<std::is_same_v<T1, T2>>;
246-
247-
template <typename T>
248-
struct has_TypeDefinition<
249-
T, enable_if_same_t<std::string_view,
250-
decltype(TypeDefinition(std::declval<T&>(),
251-
std::declval<EmptyFunc&>()))>>
252-
: std::true_type
253-
{
254-
};
255-
256264
template <typename T>
257265
inline constexpr bool is_number()
258266
{
@@ -314,7 +322,7 @@ inline constexpr bool is_vector()
314322
//-----------------------------------------------------------------------
315323
//-----------------------------------------------------------------------
316324

317-
template <typename T>
325+
template <typename T, bool>
318326
inline size_t BufferSize(const T& val)
319327
{
320328
static_assert(is_number<T>() || has_TypeDefinition<T>(), "Missing TypeDefinition");
@@ -341,13 +349,15 @@ inline size_t BufferSize(const std::string& str)
341349
return sizeof(StringSize) + str.size();
342350
}
343351

344-
template <class T, size_t N>
352+
template <class T, size_t N,
353+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool>>
345354
inline size_t BufferSize(const std::array<T, N>&)
346355
{
347356
return BufferSize(T{}) * N;
348357
}
349358

350-
template <template <class, class> class Container, class T, class... TArgs>
359+
template <template <class, class> class Container, class T, class... TArgs,
360+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool>>
351361
inline size_t BufferSize(const Container<T, TArgs...>& vect)
352362
{
353363
if constexpr(std::is_trivially_copyable_v<T> && is_vector<Container<T, TArgs...>>())
@@ -369,7 +379,7 @@ inline size_t BufferSize(const Container<T, TArgs...>& vect)
369379
//-----------------------------------------------------------------------
370380
//-----------------------------------------------------------------------
371381

372-
template <typename T>
382+
template <typename T, bool>
373383
inline void DeserializeFromBuffer(SpanBytesConst& buffer, T& dest)
374384
{
375385
static_assert(is_number<T>() || has_TypeDefinition<T>(), "Missing TypeDefinition");
@@ -412,7 +422,8 @@ inline void DeserializeFromBuffer(SpanBytesConst& buffer, std::string& dest)
412422
buffer.trimFront(size);
413423
}
414424

415-
template <typename T, size_t N>
425+
template <typename T, size_t N,
426+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool>>
416427
inline void DeserializeFromBuffer(SpanBytesConst& buffer, std::array<T, N>& dest)
417428
{
418429
if(N * BufferSize(T{}) > buffer.size())
@@ -434,7 +445,8 @@ inline void DeserializeFromBuffer(SpanBytesConst& buffer, std::array<T, N>& dest
434445
}
435446
}
436447

437-
template <template <class, class> class Container, class T, class... TArgs>
448+
template <template <class, class> class Container, class T, class... TArgs,
449+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool>>
438450
inline void DeserializeFromBuffer(SpanBytesConst& buffer, Container<T, TArgs...>& dest)
439451
{
440452
uint32_t num_values = 0;
@@ -475,7 +487,7 @@ inline void DeserializeFromBuffer(SpanBytesConst& buffer, Container<T, TArgs...>
475487
//-----------------------------------------------------------------------
476488
//-----------------------------------------------------------------------
477489

478-
template <typename T>
490+
template <typename T, bool>
479491
inline void SerializeIntoBuffer(SpanBytes& buffer, T const& value)
480492
{
481493
static_assert(is_number<T>() || has_TypeDefinition<T>(), "Missing TypeDefinition");
@@ -488,9 +500,10 @@ inline void SerializeIntoBuffer(SpanBytes& buffer, T const& value)
488500
throw std::runtime_error("SerializeIntoBuffer: buffer overflow");
489501
}
490502
#if SERIALIZE_LITTLEENDIAN == 0
491-
*(reinterpret_cast<T*>(buffer.data())) = EndianSwap<T>(value);
503+
T swapped = EndianSwap<T>(value);
504+
std::memcpy(buffer.data(), &swapped, S);
492505
#else
493-
*(reinterpret_cast<T*>(buffer.data())) = value;
506+
std::memcpy(buffer.data(), &value, S);
494507
#endif
495508
buffer.trimFront(S); // NOLINT
496509
}
@@ -523,7 +536,8 @@ inline void SerializeIntoBuffer(SpanBytes& buffer, std::string const& str)
523536
buffer.trimFront(size);
524537
}
525538

526-
template <typename T, size_t N>
539+
template <typename T, size_t N,
540+
std::enable_if_t<!has_TypeDefinition<std::array<T, N>>::value, bool>>
527541
inline void SerializeIntoBuffer(SpanBytes& buffer, std::array<T, N> const& vect)
528542
{
529543
if(N > std::numeric_limits<uint32_t>::max())
@@ -553,7 +567,8 @@ inline void SerializeIntoBuffer(SpanBytes& buffer, std::array<T, N> const& vect)
553567
}
554568
}
555569

556-
template <template <class, class> class Container, class T, class... TArgs>
570+
template <template <class, class> class Container, class T, class... TArgs,
571+
std::enable_if_t<!has_TypeDefinition<Container<T, TArgs...>>::value, bool>>
557572
inline void SerializeIntoBuffer(SpanBytes& buffer, Container<T, TArgs...> const& vect)
558573
{
559574
const auto num_values = static_cast<uint32_t>(vect.size());

data_tamer_cpp/include/data_tamer/custom_types.hpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,6 @@ template <typename T>
151151
inline CustomSerializerT<T>::CustomSerializerT(std::string type_name)
152152
: _name(std::move(type_name))
153153
{
154-
static_assert(!SerializeMe::container_info<T>().is_container, "Don't pass containers a "
155-
"template type");
156-
157154
bool is_fixed_size = true;
158155
GetFixedSize<T>(is_fixed_size, _fixed_size);
159156
if(!is_fixed_size)
@@ -198,8 +195,6 @@ inline CustomSerializer::Ptr TypesRegistry::getSerializer()
198195
{
199196
static_assert(!IsNumericType<T>(), "You don't need to create a serializer for a "
200197
"numerical type.");
201-
static_assert(!SerializeMe::container_info<T>().is_container, "Don't pass containers "
202-
"as template type");
203198

204199
std::scoped_lock lk(_mutex);
205200
T dummy;
@@ -221,8 +216,6 @@ inline CustomSerializer::Ptr TypesRegistry::addType(const std::string& type_name
221216
{
222217
static_assert(!IsNumericType<T>(), "You don't need to create a serializer for a "
223218
"numerical type.");
224-
static_assert(!SerializeMe::container_info<T>().is_container, "Don't pass containers "
225-
"as template type");
226219

227220
std::scoped_lock lk(_mutex);
228221
if(skip_if_present && _types.count(type_name) != 0)

0 commit comments

Comments
 (0)