15#include "comms/details/detect.h"
16#include "comms/details/tag.h"
17#include "comms/frame/details/MsgDataLayerOptionsParser.h"
39template <
typename... TOptions>
42 using ParsedOptionsInternal = details::MsgDataLayerOptionsParser<TOptions...>;
65 using Field =
typename ParsedOptionsInternal::FieldType;
126 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
131 TExtraValues... extraValues)
133 using MsgType =
typename std::decay<
decltype(msg)>::type;
136 comms::isMessageBase<MsgType>()
140 comms::isMessage<MsgType>()
143 typename comms::util::LazyShallowConditional<
144 std::is_pointer<MsgType>::value
152 if (setPayloadRequiredInternal(extraValues...)) {
153 auto fromIter = iter;
154 auto es = readInternal(msg, iter, size, Tag(), extraValues...);
155 setMsgPayloadInternal(fromIter,
static_cast<std::size_t
>(std::distance(fromIter, iter)), extraValues...);
159 return readInternal(msg, iter, size, Tag(), extraValues...);
165 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
172 static_cast<void>(msg);
173 static_cast<void>(iter);
174 static_cast<void>(size);
182 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
187 TExtraValues... extraValues)
189 return read(msg, iter, size, extraValues...);
216 template <
typename TAllFields,
typename TMsg,
typename TIter,
typename... TExtraValues>
218 TAllFields& allFields,
222 TExtraValues... extraValues)
226 "Expected TAllFields to be tuple.");
228 using AllFieldsDecayed =
typename std::decay<TAllFields>::type;
229 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(),
"Passed tuple is wrong.");
230 static const std::size_t Idx =
231 std::tuple_size<AllFieldsDecayed>::value -
232 std::tuple_size<AllFields>::value;
234 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
235 "All fields must be read when MsgDataLayer is reached");
237 using IterType =
typename std::decay<
decltype(iter)>::type;
238 using IterTag =
typename std::iterator_traits<IterType>::iterator_category;
239 static_assert(std::is_base_of<std::random_access_iterator_tag, IterTag>::value,
240 "Caching read from non random access iterators are not supported at this moment.");
242 auto& dataField = std::get<Idx>(allFields);
244 using FieldType =
typename std::decay<
decltype(dataField)>::type;
246 std::is_same<Field, FieldType>::value,
247 "Field has wrong type");
249 auto dataIter = iter;
250 auto es =
read(msg, iter, size, extraValues...);
255 auto dataSize =
static_cast<std::size_t
>(std::distance(dataIter, iter));
256 setMsgPayloadInternal(dataIter, dataSize, extraValues...);
258 auto dataEs = dataField.read(dataIter, dataSize);
259 static_cast<void>(dataEs);
267 template <
typename TAllFields,
typename TMsg,
typename TIter,
typename... TExtraValues>
269 TAllFields& allFields,
275 static_cast<void>(allFields);
276 static_cast<void>(msg);
277 static_cast<void>(iter);
278 static_cast<void>(size);
286 template <
typename TAllFields,
typename TMsg,
typename TIter,
typename... TExtraValues>
288 TAllFields& allFields,
292 TExtraValues... extraValues)
314 template <
typename TMsg,
typename TIter>
320 using MsgType =
typename std::decay<
decltype(msg)>::type;
323 comms::isMessage<MsgType>(),
324 "The provided message object must inherit from comms::Message");
328 comms::isMessageBase<MsgType>()
332 comms::isMessage<MsgType>()
335 typename comms::util::LazyShallowConditional<
336 std::is_pointer<MsgType>::value
344 return writeInternal(msg, iter, size, Tag());
362 template <
typename TAllFields,
typename TMsg,
typename TIter>
364 TAllFields& allFields,
370 "Expected TAllFields to be tuple.");
372 using AllFieldsDecayed =
typename std::decay<TAllFields>::type;
373 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(),
"Passed tuple is wrong.");
374 static const std::size_t Idx =
375 std::tuple_size<AllFieldsDecayed>::value -
376 std::tuple_size<AllFields>::value;
378 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
379 "All fields must be written when MsgDataLayer is reached");
381 auto& dataField = std::get<Idx>(allFields);
382 using FieldType =
typename std::decay<
decltype(dataField)>::type;
384 std::is_same<Field, FieldType>::value,
385 "Field has wrong type");
387 using IterType =
typename std::decay<
decltype(iter)>::type;
388 using IterTag =
typename std::iterator_traits<IterType>::iterator_category;
389 return writeWithFieldCachedInternal(dataField, msg, iter, size, IterTag());
405 template <
typename TIter>
408 std::advance(iter, size);
418 template <
typename TMsg,
typename TIter>
421 static_cast<void>(msg);
422 return update(iter, size);
438 template <
typename TAllFields,
typename TIter>
440 TAllFields& allFields,
444 static_cast<void>(allFields);
445 std::advance(iter, size);
464 template <
typename TAllFields,
typename TMsg,
typename TIter>
466 TAllFields& allFields,
471 static_cast<void>(allFields);
472 static_cast<void>(msg);
473 std::advance(iter, size);
495 template <
typename TMsg>
496 static constexpr std::size_t
length(
const TMsg& msg)
498 using MsgType =
typename std::decay<
decltype(msg)>::type;
501 comms::isMessage<MsgType>(),
502 "The provided message object must inherit from comms::Message");
505 typename comms::util::LazyShallowConditional<
506 details::FrameLayerHasFieldsImpl<MsgType>::Value
511 return getMsgLength(msg, Tag());
518 template <
typename TAllFields>
520 decltype(std::get<std::tuple_size<typename std::decay<TAllFields>::type>::value - std::tuple_size<AllFields>::value>(allFields))
522 using AllFieldsDecayed =
typename std::decay<TAllFields>::type;
523 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(),
"Passed tuple is wrong.");
524 static const std::size_t Idx =
525 std::tuple_size<AllFieldsDecayed>::value -
526 std::tuple_size<AllFields>::value;
528 return std::get<Idx>(allFields);
532 template <
typename... TParams>
533 using MsgHasLengthTag = comms::details::tag::Tag1<>;
535 template <
typename... TParams>
536 using MsgNoLengthTag = comms::details::tag::Tag2<>;
538 template <
typename... TParams>
539 using MsgDirectLengthTag = comms::details::tag::Tag3<>;
541 template <
typename... TParams>
542 using DirectOpTag = comms::details::tag::Tag4<>;
544 template <
typename... TParams>
545 using InterfaceOpTag = comms::details::tag::Tag5<>;
547 template <
typename... TParams>
548 using PointerOpTag = comms::details::tag::Tag6<>;
550 template <
typename... TParams>
551 using OtherOpTag = comms::details::tag::Tag7<>;
553 template <
typename TMsg,
typename TIter>
559 std::random_access_iterator_tag)
561 return writeWithFieldCachedRandomAccess(field, msg, iter, size);
564 template <
typename TMsg,
typename TIter>
570 std::output_iterator_tag)
572 return writeWithFieldCachedOutput(field, msg, iter, size);
575 template <
typename TMsg,
typename TIter>
576 static ErrorStatus writeWithFieldCachedRandomAccess(
582 auto dataReadIter = iter;
583 auto es =
write(msg, iter, size);
588 auto writtenCount =
static_cast<std::size_t
>(std::distance(dataReadIter, iter));
589 auto dataEs = field.read(dataReadIter, writtenCount);
591 static_cast<void>(dataEs);
595 template <
typename TMsg,
typename TCollection>
599 std::back_insert_iterator<TCollection>& iter,
602 auto es =
write(msg, iter, size);
608 auto dataWriteIter = std::back_inserter(col);
609 auto dataWriteEs =
write(msg, dataWriteIter, size);
611 static_cast<void>(dataWriteEs);
613 auto dataReadIter = col.cbegin();
614 auto dataReadEs = field.read(dataReadIter, col.size());
616 static_cast<void>(dataReadEs);
621 template <
typename TMsg,
typename... TParams>
622 static std::size_t getMsgLength(
const TMsg& msg, MsgHasLengthTag<TParams...>)
624 using MsgType =
typename std::decay<
decltype(msg)>::type;
625 static_assert(MsgType::hasLength(),
"Message interface must define length()");
629 template <
typename TMsg,
typename... TParams>
630 static constexpr std::size_t getMsgLength(
const TMsg& msg, MsgDirectLengthTag<TParams...>)
632 using MsgType =
typename std::decay<
decltype(msg)>::type;
633 static_assert(MsgType::hasFields(),
"FieldsImpl option hasn't been used");
634 return msg.doLength();
637 template <
typename TMsg,
typename... TParams>
638 static constexpr std::size_t getMsgLength(
const TMsg&, MsgNoLengthTag<TParams...>)
643 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
648 TExtraValues... extraValues)
650 using MsgType =
typename std::decay<
decltype(msg)>::type;
653 comms::isMessage<MsgType>(),
654 "The provided message object must inherit from comms::Message");
656 static_assert(MsgType::hasRead(),
657 "Message interface must support polymorphic read operation");
659 using IterType =
typename std::decay<
decltype(iter)>::type;
661 static_assert(std::is_convertible<IterType, typename MsgType::ReadIterator>::value,
662 "The provided iterator is not convertible to ReadIterator defined by Message class");
664 using ReadIter =
typename std::add_lvalue_reference<typename MsgType::ReadIterator>::type;
666 auto result = msg.read(
static_cast<ReadIter
>(iter), size);
668 missingSizeRequiredInternal(extraValues...)) {
670 typename comms::util::LazyShallowConditional<
678 auto msgLen = getMsgLength(msg, Tag());
682 updateMissingSizeInternal(
missingSize, extraValues...);
687 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
692 TExtraValues... extraValues)
694 using MsgType =
typename std::decay<
decltype(msg)>::type;
697 comms::isMessageBase<MsgType>(),
698 "The provided message object must inherit from comms::MessageBase");
700 static_assert(details::frameLayerHasFieldsImpl<MsgType>(),
701 "Message class must use FieldsImpl option");
703 auto result = msg.doRead(iter, size);
705 (missingSizeRequiredInternal(extraValues...))) {
707 auto msgLen = getMsgLength(msg, MsgDirectLengthTag<>());
711 updateMissingSizeInternal(
missingSize, extraValues...);
716 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
722 TExtraValues... extraValues)
724 return readInternalDirect(msg, iter, size, extraValues...);
727 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
733 TExtraValues... extraValues)
735 static_assert(comms::isMessage<TMsg>(),
"Must be interface class");
736 static_assert(TMsg::hasRead(),
737 "Message interface must support polymorphic read operation");
739 return readInternalPolymorphic(msg, iter, size, extraValues...);
742 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
748 TExtraValues... extraValues)
750 return read(*msg, iter, size, extraValues...);
753 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
759 TExtraValues... extraValues)
761 using MsgType =
typename std::decay<
decltype(msg)>::type;
762 static_assert(comms::details::hasElementType<MsgType>(),
763 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
764 return read(*msg, iter, size, extraValues...);
767 template <
typename TMsg,
typename TIter,
typename... TParams>
772 DirectOpTag<TParams...>)
774 return msg.doWrite(iter, size);
777 template <
typename TMsg,
typename TIter,
typename... TParams>
782 InterfaceOpTag<TParams...>)
784 using MsgType =
typename std::decay<
decltype(msg)>::type;
786 static_assert(MsgType::hasWrite(),
787 "Message interface must support polymorphic write operation");
789 using IterType =
typename std::decay<
decltype(iter)>::type;
791 static_assert(std::is_convertible<IterType, typename MsgType::WriteIterator>::value,
792 "The provided iterator is not convertible to WriteIterator defined by Message class");
794 using WriteIter =
typename std::add_lvalue_reference<typename MsgType::WriteIterator>::type;
796 return msg.write(
static_cast<WriteIter
>(iter), size);
799 template <
typename TMsg,
typename TIter,
typename... TParams>
804 PointerOpTag<TParams...>)
806 return write(*msg, iter, size);
809 template <
typename TMsg,
typename TIter,
typename... TParams>
814 OtherOpTag<TParams...>)
816 using MsgType =
typename std::decay<
decltype(msg)>::type;
817 static_assert(comms::details::hasElementType<MsgType>(),
818 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
820 return write(*msg, iter, size);
823 static constexpr bool missingSizeRequiredInternal()
828 template <
typename... TExtraValues>
829 static bool missingSizeRequiredInternal(details::MissingSizeRetriever<>, TExtraValues...)
834 template <
typename T,
typename... TExtraValues>
835 static bool missingSizeRequiredInternal(T, TExtraValues... extraValues)
838 !details::isMissingSizeRetriever<T>(),
839 "Mustn't be missing size retriever");
840 return missingSizeRequiredInternal(extraValues...);
843 static void updateMissingSizeInternal(std::size_t val)
845 static_cast<void>(val);
848 template <
typename... TExtraValues>
849 static void updateMissingSizeInternal(
851 details::MissingSizeRetriever<> retriever,
852 TExtraValues... extraValues)
854 retriever.setValue(val);
855 updateMissingSizeInternal(val, extraValues...);
858 template <
typename T,
typename... TExtraValues>
859 static void updateMissingSizeInternal(std::size_t val, T retriever, TExtraValues... extraValues)
861 static_cast<void>(retriever);
863 !details::isMissingSizeRetriever<
typename std::decay<
decltype(retriever)>::type>(),
864 "Mustn't be missing size retriever");
865 updateMissingSizeInternal(val, extraValues...);
868 static constexpr bool setPayloadRequiredInternal()
873 template <
typename TIter,
typename... TExtraValues>
874 static bool setPayloadRequiredInternal(details::MsgPayloadRetriever<TIter>, TExtraValues...)
879 template <
typename T,
typename... TExtraValues>
880 static bool setPayloadRequiredInternal(T, TExtraValues... extraValues)
883 !details::isMsgPayloadRetriever<T>(),
884 "Mustn't be message payload retriever");
885 return setPayloadRequiredInternal(extraValues...);
888 template <
typename TIter>
889 static void setMsgPayloadInternal(TIter iter, std::size_t len)
891 static_cast<void>(iter);
892 static_cast<void>(len);
895 template <
typename TIter,
typename TOtherIter,
typename... TExtraValues>
896 static void setMsgPayloadInternal(
899 details::MsgPayloadRetriever<TOtherIter> retriever,
900 TExtraValues... extraValues)
902 retriever.setValue(iter, len);
903 setMsgPayloadInternal(iter, len, extraValues...);
906 template <
typename TIter,
typename T,
typename... TExtraValues>
907 static void setMsgPayloadInternal(
911 TExtraValues... extraValues)
913 static_cast<void>(retriever);
915 !details::isMsgPayloadRetriever<
typename std::decay<
decltype(retriever)>::type>(),
916 "Mustn't be message payload retriever");
917 setMsgPayloadInternal(iter, len, extraValues...);
924struct MsgDataLayerCheckHelper
926 static const bool Value =
false;
929template <
typename... TExtraOpts>
930struct MsgDataLayerCheckHelper<
MsgDataLayer<TExtraOpts...> >
932 static const bool Value =
true;
943 return details::MsgDataLayerCheckHelper<T>::Value;
946template <
typename... TExtraOpts>
954template <
typename... TExtraOpts>
956const MsgDataLayer<TExtraOpts...>&
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Contains definition of comms::Field class.
Contains definition of comms::frame::FrameLayerBase.
Provides common base class for the custom messages with default implementation.
Contains definition of Message object interface and various base classes for custom messages.
Contains various tuple type manipulation classes and functions.
Base class to all the field classes.
Definition Field.h:33
Message data layer.
Definition MsgDataLayer.h:41
MsgDataLayer()=default
Default constructor.
static ErrorStatus readFromData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as read().
Definition MsgDataLayer.h:183
static constexpr std::size_t length()
Get remaining length of wrapping transport information.
Definition MsgDataLayer.h:482
static comms::ErrorStatus update(const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:419
constexpr bool isMsgDataLayer()
Compile time check of whether the provided type is a variant of MsgDataLayer.
Definition MsgDataLayer.h:941
std::tuple< Field > AllFields
All fields of the remaining transport layers, contains only Field.
Definition MsgDataLayer.h:68
static const std::size_t NumOfLayers
Static constant indicating amount of transport layers used.
Definition MsgDataLayer.h:79
typename ParsedOptionsInternal::FieldType Field
Raw data field type.
Definition MsgDataLayer.h:65
MsgDataLayer(const MsgDataLayer &)=default
Copy constructor.
static comms::ErrorStatus update(TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:406
~MsgDataLayer() noexcept=default
Destructor.
static ErrorStatus readFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents while caching the read transport information fields.
Definition MsgDataLayer.h:217
void AllMessages
Default value of AllMessages type.
Definition MsgDataLayer.h:72
static ErrorStatus readUntilDataFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields with caching until data layer.
Definition MsgDataLayer.h:268
static auto accessCachedField(TAllFields &allFields) -> decltype(std::get< std::tuple_size< typename std::decay< TAllFields >::type >::value - std::tuple_size< AllFields >::value >(allFields))
Access appropriate field from "cached" bundle of all the frame fields.
Definition MsgDataLayer.h:519
void MsgFactory
Default value of MsgFactory type.
Definition MsgDataLayer.h:76
static ErrorStatus readUntilData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields until data layer.
Definition MsgDataLayer.h:166
static ErrorStatus readFromDataFeildsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as readFieldsCached().
Definition MsgDataLayer.h:287
static constexpr std::size_t length(const TMsg &msg)
Get remaining length of wrapping transport information + length of the provided message.
Definition MsgDataLayer.h:496
static ErrorStatus write(const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents.
Definition MsgDataLayer.h:315
static ErrorStatus updateFieldsCached(TAllFields &allFields, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:439
static ErrorStatus read(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents.
Definition MsgDataLayer.h:127
ThisLayer & thisLayer()
Get access to this layer object.
Definition MsgDataLayer.h:49
static ErrorStatus writeFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents while caching the written transport information fields.
Definition MsgDataLayer.h:363
static ErrorStatus updateFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:465
MsgDataLayer(MsgDataLayer &&)=default
Move constructor.
const ThisLayer & thisLayer() const
Get "const" access to this layer object.
Definition MsgDataLayer.h:55
static constexpr bool canSplitRead()
Compile time check whether split read "until" and "from" data layer is allowed.
Definition MsgDataLayer.h:102
details::MissingSizeRetriever missingSize(std::size_t &val)
Add "missing size" output parameter to frame's "read" operation.
Definition FrameLayerBase.h:1559
FrameLayerBase< TField, TNextLayer, TDerived, TOptions... > & toFrameLayerBase(FrameLayerBase< TField, TNextLayer, TDerived, TOptions... > &layer)
Upcast protocol layer in order to have access to its internal types.
Definition FrameLayerBase.h:1519
comms::option::def::MsgType< TMsg > MsgType
Same as comms::option::def::MsgType.
Definition options.h:1487
comms::frame::MsgDataLayer< TOptions... > MsgDataLayer
Alias to the comms::frame::MsgDataLayer.
Definition MsgDataLayer.h:25
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
@ Success
Used to indicate successful outcome of the operation.
Replacement to std::conditional.
Definition type_traits.h:29
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:36
Replacement to some types from standard type_traits.