3333
3434namespace rmw_cyclonedds_cpp
3535{
36-
37- struct CDRCursor
36+ template < typename Derived>
37+ struct CDRCursorBase
3838{
39- CDRCursor () = default ;
40- ~CDRCursor () = default ;
41-
42- // don't want to accidentally copy
43- explicit CDRCursor (CDRCursor const &) = delete;
44- void operator =(CDRCursor const & x) = delete ;
45-
46- // virtual functions to be implemented
47- // get the cursor's current offset.
48- virtual size_t offset () const = 0;
49- // advance the cursor.
50- virtual void advance (size_t n_bytes) = 0;
51- // Copy bytes to the current cursor location (if needed) and advance the cursor
52- virtual void put_bytes (const void * data, size_t size) = 0;
53- virtual bool ignores_data () const = 0;
54- // Move the logical origin this many places
55- virtual void rebase (ptrdiff_t relative_origin) = 0;
56-
5739 void align (size_t n_bytes)
5840 {
5941 assert (n_bytes > 0 );
60- size_t start_offset = offset ();
42+ size_t start_offset = static_cast <Derived *>( this )-> offset ();
6143 if (n_bytes == 1 || start_offset % n_bytes == 0 ) {
6244 return ;
6345 }
64- advance (n_bytes - start_offset % n_bytes);
65- assert (offset () - start_offset < n_bytes);
66- assert (offset () % n_bytes == 0 );
46+ static_cast <Derived *>( this )-> advance (n_bytes - start_offset % n_bytes);
47+ assert (static_cast <Derived *>( this )-> offset () - start_offset < n_bytes);
48+ assert (static_cast <Derived *>( this )-> offset () % n_bytes == 0 );
6749 }
68- ptrdiff_t operator -(const CDRCursor & other) const
50+
51+ ptrdiff_t operator -(const CDRCursorBase & other) const
6952 {
70- return static_cast <ptrdiff_t >(offset ()) - static_cast <ptrdiff_t >(other.offset ());
53+ return static_cast <ptrdiff_t >(static_cast <Derived *>(this )->offset ()) -
54+ static_cast <ptrdiff_t >(static_cast <Derived &>(other).offset ());
7155 }
7256};
7357
74- struct SizeCursor : public CDRCursor
58+ struct SizeCursor final : public CDRCursorBase<SizeCursor>
7559{
7660 SizeCursor ()
7761 : SizeCursor(0 ) {}
7862 explicit SizeCursor (size_t initial_offset)
7963 : m_offset(initial_offset) {}
80- explicit SizeCursor (CDRCursor & c)
64+ explicit SizeCursor (SizeCursor & c)
8165 : m_offset(c.offset()) {}
8266
8367 size_t m_offset;
84- size_t offset () const final {return m_offset;}
85- void advance (size_t n_bytes) final {m_offset += n_bytes;}
86- void put_bytes (const void *, size_t n_bytes) final {advance (n_bytes);}
87- bool ignores_data () const final {return true ;}
88- void rebase (ptrdiff_t relative_origin) override
68+ size_t offset () const {return m_offset;}
69+ void advance (size_t n_bytes) {m_offset += n_bytes;}
70+ void put_bytes (const void *, size_t n_bytes) {advance (n_bytes);}
71+ bool ignores_data () const {return true ;}
72+ void rebase (ptrdiff_t relative_origin)
8973 {
9074 // we're moving the *origin* so this has to change in the *opposite* direction
9175 m_offset -= relative_origin;
9276 }
9377};
9478
95- struct DataCursor : public CDRCursor
79+ struct DataCursor final : public CDRCursorBase<DataCursor>
9680{
9781 const void * origin;
9882 void * position;
9983
10084 explicit DataCursor (void * position)
10185 : origin(position), position(position) {}
10286
103- size_t offset () const final {return (const byte *)position - (const byte *)origin;}
104- void advance (size_t n_bytes) final
87+ size_t offset () const {return (const byte *)position - (const byte *)origin;}
88+ void advance (size_t n_bytes)
10589 {
10690 std::memset (position, ' \0 ' , n_bytes);
10791 position = byte_offset (position, n_bytes);
10892 }
109- void put_bytes (const void * bytes, size_t n_bytes) final
93+ void put_bytes (const void * bytes, size_t n_bytes)
11094 {
11195 if (n_bytes == 0 ) {
11296 return ;
11397 }
11498 std::memcpy (position, bytes, n_bytes);
11599 position = byte_offset (position, n_bytes);
116100 }
117- bool ignores_data () const final {return false ;}
118- void rebase (ptrdiff_t relative_origin) final {origin = byte_offset (origin, relative_origin);}
101+ bool ignores_data () const {return false ;}
102+ void rebase (ptrdiff_t relative_origin) {origin = byte_offset (origin, relative_origin);}
119103};
120104
121105enum class EncodingVersion
@@ -236,6 +220,7 @@ class CDRWriter : public BaseCDRWriter
236220 serialize_top_level (&cursor, request);
237221 }
238222
223+ template <typename CDRCursor>
239224 void serialize_top_level (
240225 CDRCursor * cursor, const void * data) const
241226 {
@@ -257,6 +242,7 @@ class CDRWriter : public BaseCDRWriter
257242 }
258243 }
259244
245+ template <typename CDRCursor>
260246 void serialize_top_level (
261247 CDRCursor * cursor, const cdds_request_wrapper_t & request) const
262248 {
@@ -275,6 +261,7 @@ class CDRWriter : public BaseCDRWriter
275261 }
276262
277263protected:
264+ template <typename CDRCursor>
278265 void put_rtps_header (CDRCursor * cursor) const
279266 {
280267 // beginning of message
@@ -297,6 +284,7 @@ class CDRWriter : public BaseCDRWriter
297284 cursor->put_bytes (rtps_header.data (), rtps_header.size ());
298285 }
299286
287+ template <typename CDRCursor>
300288 void serialize_u32 (CDRCursor * cursor, size_t value) const
301289 {
302290 assert (value <= std::numeric_limits<uint32_t >::max ());
@@ -429,6 +417,7 @@ class CDRWriter : public BaseCDRWriter
429417 return sizeof_ < max_align ? sizeof_ : max_align;
430418 }
431419
420+ template <typename CDRCursor>
432421 void serialize (CDRCursor * cursor, const void * data, const PrimitiveValueType & value_type) const
433422 {
434423 cursor->align (get_cdr_alignof_primitive (value_type.type_kind ()));
@@ -470,6 +459,7 @@ class CDRWriter : public BaseCDRWriter
470459 }
471460 }
472461
462+ template <typename CDRCursor>
473463 void serialize (CDRCursor * cursor, const void * data, const U8StringValueType & value_type) const
474464 {
475465 auto str = value_type.data (data);
@@ -479,6 +469,7 @@ class CDRWriter : public BaseCDRWriter
479469 cursor->put_bytes (&terminator, 1 );
480470 }
481471
472+ template <typename CDRCursor>
482473 void serialize (CDRCursor * cursor, const void * data, const U16StringValueType & value_type) const
483474 {
484475 auto str = value_type.data (data);
@@ -497,12 +488,14 @@ class CDRWriter : public BaseCDRWriter
497488 }
498489 }
499490
491+ template <typename CDRCursor>
500492 void serialize (CDRCursor * cursor, const void * data, const ArrayValueType & value_type) const
501493 {
502494 serialize_many (
503495 cursor, value_type.get_data (data), value_type.array_size (), value_type.element_value_type ());
504496 }
505497
498+ template <typename CDRCursor>
506499 void serialize (
507500 CDRCursor * cursor, const void * data,
508501 const SpanSequenceValueType & value_type) const
@@ -513,6 +506,7 @@ class CDRWriter : public BaseCDRWriter
513506 cursor, value_type.sequence_contents (data), count, value_type.element_value_type ());
514507 }
515508
509+ template <typename CDRCursor>
516510 void serialize (
517511 CDRCursor * cursor, const void * data,
518512 const BoolVectorValueType & value_type) const
@@ -529,37 +523,17 @@ class CDRWriter : public BaseCDRWriter
529523 }
530524 }
531525
526+ template <typename CDRCursor>
532527 void serialize (CDRCursor * cursor, const void * data, const AnyValueType * value_type) const
533528 {
534529 if (lookup_trivially_serialized (cursor->offset (), value_type)) {
535530 cursor->put_bytes (data, value_type->sizeof_type ());
536531 } else {
537- // value_type->apply([&](const auto & vt) {return serialize(cursor, data, vt);});
538- if (auto s = dynamic_cast <const PrimitiveValueType *>(value_type)) {
539- return serialize (cursor, data, *s);
540- }
541- if (auto s = dynamic_cast <const U8StringValueType *>(value_type)) {
542- return serialize (cursor, data, *s);
543- }
544- if (auto s = dynamic_cast <const U16StringValueType *>(value_type)) {
545- return serialize (cursor, data, *s);
546- }
547- if (auto s = dynamic_cast <const StructValueType *>(value_type)) {
548- return serialize (cursor, data, *s);
549- }
550- if (auto s = dynamic_cast <const ArrayValueType *>(value_type)) {
551- return serialize (cursor, data, *s);
552- }
553- if (auto s = dynamic_cast <const SpanSequenceValueType *>(value_type)) {
554- return serialize (cursor, data, *s);
555- }
556- if (auto s = dynamic_cast <const BoolVectorValueType *>(value_type)) {
557- return serialize (cursor, data, *s);
558- }
559- unreachable ();
532+ value_type->apply ([&](const auto & vt) {return serialize (cursor, data, vt);});
560533 }
561534 }
562535
536+ template <typename CDRCursor>
563537 void serialize_many (
564538 CDRCursor * cursor, const void * data, size_t count,
565539 const AnyValueType * vt) const
@@ -594,6 +568,7 @@ class CDRWriter : public BaseCDRWriter
594568 }
595569 }
596570
571+ template <typename CDRCursor>
597572 void serialize (
598573 CDRCursor * cursor, const void * struct_data,
599574 const StructValueType & struct_info) const
0 commit comments