@@ -68,46 +68,79 @@ using SpanBytes = Span<uint8_t>;
6868using SpanBytesConst = Span<uint8_t const >;
6969using 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
7386template <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 >
7498size_t BufferSize (const T& val);
7599
76100template <>
77101size_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 >
80105size_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 >
83110size_t BufferSize (const Container<T, TArgs...>& vect);
84111
85112// ---------- Forward declarations of DeserializeFromBuffer -----------
86113
87- template <typename T>
114+ template <typename T, bool = true >
88115void DeserializeFromBuffer (SpanBytesConst& buffer, T& dest);
89116
90117template <>
91118void 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 >
94122void 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 >
97127void DeserializeFromBuffer (SpanBytesConst& buffer, Container<T, TArgs...>& dest);
98128
99129// ---------- Forward declarations of SerializeIntoBuffer -----------
100130
101- template <typename T>
131+ template <typename T, bool = true >
102132void SerializeIntoBuffer (SpanBytes& buffer, const T& value);
103133
104134template <>
105135void 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 >
108139void 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 >
111144void 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-
256264template <typename T>
257265inline 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 >
318326inline 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 >>
345354inline 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 >>
351361inline 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 >
373383inline 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 >>
416427inline 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 >>
438450inline 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 >
479491inline 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 >>
527541inline 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 >>
557572inline void SerializeIntoBuffer (SpanBytes& buffer, Container<T, TArgs...> const & vect)
558573{
559574 const auto num_values = static_cast <uint32_t >(vect.size ());
0 commit comments