Suggest: Use ADL(or probably better, CPO) to implement some utility types
Closed this issue · 3 comments
This is useful in some (though uncommon) use case.
For example, I'm building an app that uses CycloneDDS merely as the way to pass around variable-size raw buffer. Something like this, (not standard IDL)
module BufferType {
template<size_t N>
struct Buffer {
char data[N];
};
};
So that user can instantiate messages of different buffer size like
dds::pub::DataWriter<BufferType::Buffer<128U>> writer_buffer(publisher, topic_buffer);
dds::pub::DataWriter<BufferType::Buffer<256U>> writer_buffer(publisher, topic_buffer);
This doesn't work out of box, so I have to make some manual modifications to the auto-generated .h
and .cpp
file. Mostly,
-
Add
template<size_t N>
to the generated message typetemplate <size_t N> class Buffer { private: std::array<char, N> data_ = {}; ...
I also changed where this message is used in the same file.
-
Previously, in the generated header, some static methods of
TopicTraits
is specialized upon the message type
to describe the message, includinggetTypeName
,isKeyless
. But this doesn't support partially specialized
static methods.So what I did was add some hidden friends inside the message class,
template <size_t N> class Buffer { private: std::array<char, N> data_ = {}; friend constexpr const char *getTypeName(::BufferType::Buffer<N> *) { return "::BufferType::Buffer<N>"; // A constexpr string manipulation is needed // to replace `N` with the actual number } friend constexpr bool isKeyless(::BufferType::Buffer<N> *) { return true; } ...
, and change their calling site from
org::eclipse::cyclonedds::topic::TopicTraits<TopicType>::getTypeName()
to
getTypeName(static_cast<T*>(nullptr))
This works, but might not be the best way. Maybe using CPO we can do better.
I like it, I am surprised you can make this work with such small tweaks to the output of the IDL compiler :)
I do wonder if it wouldn't make more sense to treat the data as-if it were a CDR blob, because then you could use the C++ binding's serialized sample operations. (Via write_cdr
and taking data into a CDRSamplesHolder
.) That would also eliminate the need to have different types for different sizes. But that's just a thought.
I discussed this with my colleague today, and we believe the problem is in the design of TopicTraits
. it's better to be an CPO via function. I'll see if I can come up with a PR later on that.
WRT the CDR blob
, could you please provide more detail? We are open to any new methods that can solve the problem. Thank you!
I guess this echos your response in another ticket. eclipse-cyclonedds/cyclonedds#1749 (comment)
Update: We changed the code to use CDRBlob as the buffer to hold custom serialization format and it worked well. Closing this ticket now.