15#include "comms/details/tag.h"
22COMMS_MSVC_WARNING_PUSH
23COMMS_MSVC_WARNING_DISABLE(4127)
34template <std::
size_t TLenFieldIdx,
typename TBase>
37 using BaseImpl = TBase;
39 using ValueType =
typename BaseImpl::ValueType;
41 static_assert(TLenFieldIdx < std::tuple_size<ValueType>::value,
"Bad index");
42 using LengthFieldType =
typename std::tuple_element<TLenFieldIdx, ValueType>::type;
47 refreshLengthInternal();
50 static constexpr std::size_t maxLength()
52 return MaxPossibleLen;
55 template <std::
size_t TFromIdx>
56 static constexpr std::size_t maxLengthFrom()
59 typename comms::util::LazyShallowConditional<
60 TLenFieldIdx < TFromIdx
65 return maxLengthFromInternal<TFromIdx>(Tag());
68 template <std::
size_t TUntilIdx>
69 static constexpr std::size_t maxLengthUntil()
72 typename comms::util::LazyShallowConditional<
73 TUntilIdx <= TLenFieldIdx
79 return maxLengthUntilInternal<TUntilIdx>(Tag());
82 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
83 static constexpr std::size_t maxLengthFromUntil()
86 typename comms::util::LazyShallowConditional<
87 (TUntilIdx <= TLenFieldIdx) || (TLenFieldIdx < TFromIdx)
93 return maxLengthFromUntilInternal<TFromIdx, TUntilIdx>(Tag());
98 bool updated = BaseImpl::refresh();
99 return refreshLengthInternal() || updated;
102 template <
typename TIter>
105 return readFromUntilAndUpdateLen<0, std::tuple_size<ValueType>::value>(iter, len);
108 template <std::
size_t TFromIdx,
typename TIter>
111 return readFromUntilAndUpdateLen<TFromIdx, std::tuple_size<ValueType>::value>(iter, len);
114 template <std::
size_t TFromIdx,
typename TIter>
115 ErrorStatus readFromAndUpdateLen(TIter& iter, std::size_t& len)
117 return readFromAndUpdateLen<TFromIdx, std::tuple_size<ValueType>::value>(iter, len);
120 template <std::
size_t TUntilIdx,
typename TIter>
121 ErrorStatus readUntil(TIter& iter, std::size_t len)
123 return readFromUntilAndUpdateLen<0U, TUntilIdx>(iter, len);
126 template <std::
size_t TUntilIdx,
typename TIter>
127 ErrorStatus readUntilAndUpdateLen(TIter& iter, std::size_t& len)
129 return readFromUntilAndUpdateLen<0, TUntilIdx>(iter, len);
132 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
133 ErrorStatus readFromUntil(TIter& iter, std::size_t len)
135 return readFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
138 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
139 ErrorStatus readFromUntilAndUpdateLen(TIter& iter, std::size_t& len)
142 typename comms::util::LazyShallowConditional<
143 (TUntilIdx <= TLenFieldIdx)
148 return readFromUntilInternal<TFromIdx, TUntilIdx>(iter, len, Tag());
151 template <
typename TIter>
152 void readNoStatus(TIter& iter) =
delete;
154 template <std::
size_t TFromIdx,
typename TIter>
155 void readFromNoStatus(TIter& iter) =
delete;
157 template <std::
size_t TUntilIdx,
typename TIter>
158 void readUntilNoStatus(TIter& iter) =
delete;
160 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
161 void readFromUntilNoStatus(TIter& iter) =
delete;
163 static constexpr bool hasNonDefaultRefresh()
168 bool setVersion(VersionType version)
170 bool updated = BaseImpl::setVersion(version);
171 return refreshLengthInternal() || updated;
174 bool canWrite()
const
176 if (!BaseImpl::canWrite()) {
180 std::size_t expLen = BaseImpl::template lengthFrom<TLenFieldIdx + 1>();
181 if (
static_cast<std::size_t
>(LengthFieldType::maxValue()) < expLen) {
185 LengthFieldType lenField;
186 lenField.setValue(expLen);
187 return lenField.canWrite();
190 template <
typename TIter>
197 return BaseImpl::write(iter, len);
200 static constexpr bool hasWriteNoStatus()
205 template <
typename TIter>
210 return BaseImpl::valid() && canWrite();
214 template <
typename... TParams>
215 using BaseRedirectTag = comms::details::tag::Tag1<>;
217 template <
typename... TParams>
218 using LocalTag = comms::details::tag::Tag2<>;
220 template <
typename... TParams>
221 using PerformOpTag = comms::details::tag::Tag3<>;
223 template <
typename... TParams>
224 using SkipOpTag = comms::details::tag::Tag4<>;
226 template <std::size_t TFromIdx,
typename... TParams>
227 static constexpr std::size_t maxLengthFromInternal(BaseRedirectTag<TParams...>)
229 return BaseImpl::template maxLengthFrom<TFromIdx>();
232 template <std::size_t TFromIdx,
typename... TParams>
233 static constexpr std::size_t maxLengthFromInternal(LocalTag<TParams...>)
235 return MaxPossibleLen;
238 template <std::size_t TUntilIdx,
typename... TParams>
239 static constexpr std::size_t maxLengthUntilInternal(BaseRedirectTag<TParams...>)
241 return BaseImpl::template maxLengthUntil<TUntilIdx>();
244 template <std::size_t TUntilIdx,
typename... TParams>
245 static constexpr std::size_t maxLengthUntilInternal(LocalTag<TParams...>)
247 return MaxPossibleLen;
250 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename... TParams>
251 static constexpr std::size_t maxLengthFromUntilInternal(BaseRedirectTag<TParams...>)
253 return BaseImpl::template maxLengthFromUntil<TFromIdx, TUntilIdx>();
256 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename... TParams>
257 static constexpr std::size_t maxLengthFromUntilInternal(LocalTag<TParams...>)
259 return MaxPossibleLen;
262 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename TIter,
typename... TParams>
263 ErrorStatus readFromUntilInternal(TIter& iter, std::size_t& len, BaseRedirectTag<TParams...>)
265 return BaseImpl::template readFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
268 template <std::size_t TFromIdx,
typename TIter,
typename... TParams>
269 ErrorStatus readEarlierFieldsInternal(TIter& iter, std::size_t& len, PerformOpTag<TParams...>)
271 return BaseImpl::template readFromUntilAndUpdateLen<TFromIdx, TLenFieldIdx>(iter, len);
274 template <std::size_t TFromIdx,
typename TIter,
typename... TParams>
275 ErrorStatus readEarlierFieldsInternal(TIter& iter, std::size_t& len, SkipOpTag<TParams...>)
277 static_cast<void>(iter);
278 static_cast<void>(len);
279 return ErrorStatus::Success;
282 template <
typename TIter,
typename... TParams>
283 ErrorStatus readRemLengthFieldInternal(TIter& iter, std::size_t& len, std::size_t& remLen, PerformOpTag<TParams...>)
285 auto& mems = BaseImpl::value();
286 auto& lenField = std::get<TLenFieldIdx>(mems);
288 auto beforeLenReadIter = iter;
289 auto es = lenField.read(iter, len);
294 auto lenFieldLen =
static_cast<std::size_t
>(std::distance(beforeLenReadIter, iter));
298 remLen =
static_cast<std::size_t
>(lenField.getValue());
299 return ErrorStatus::Success;
302 template <
typename TIter,
typename... TParams>
303 ErrorStatus readRemLengthFieldInternal(TIter& iter, std::size_t& len, std::size_t& remLen, SkipOpTag<TParams...>)
305 static_cast<void>(iter);
306 static_cast<void>(len);
307 auto& mems = BaseImpl::value();
308 auto& lenField = std::get<TLenFieldIdx>(mems);
309 remLen = lenField.value();
310 return ErrorStatus::Success;
313 template <std::size_t TUntilIdx,
typename... TParams>
314 void skipUntilFieldInternal(std::size_t& reqLen, PerformOpTag<TParams...>)
316 static_assert(TLenFieldIdx < TUntilIdx,
"Invalid assumption");
317 auto fieldsLen = BaseImpl::template lengthFromUntil<TLenFieldIdx + 1, TUntilIdx>();
322 template <std::size_t TUntilIdx,
typename... TParams>
323 void skipUntilFieldInternal(std::size_t& reqLen, SkipOpTag<TParams...>)
325 static_cast<void>(reqLen);
328 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename TIter,
typename... TParams>
329 ErrorStatus readFromUntilInternal(TIter& iter, std::size_t& len, LocalTag<TParams...>)
331 static_assert(TLenFieldIdx < TUntilIdx,
"Invalid function invocation");
332 using EarlierFieldsTag =
333 typename comms::util::LazyShallowConditional<
334 (TFromIdx < TLenFieldIdx)
340 auto es = readEarlierFieldsInternal<TFromIdx>(iter, len, EarlierFieldsTag());
346 typename comms::util::LazyShallowConditional<
347 (TFromIdx <= TLenFieldIdx)
353 std::size_t reqLen = 0U;
354 es = readRemLengthFieldInternal(iter, len, reqLen, LenTag());
360 typename comms::util::LazyShallowConditional<
361 (TLenFieldIdx < TFromIdx)
367 skipUntilFieldInternal<TFromIdx>(reqLen, SkipTag());
369 static const std::size_t NextIdx = (TFromIdx <= TLenFieldIdx) ? TLenFieldIdx + 1 : TFromIdx;
371 if ((std::tuple_size<ValueType>::value <= TUntilIdx) &&
376 auto remLen = std::min(len, reqLen);
377 es = BaseImpl::template readFromUntilAndUpdateLen<NextIdx, TUntilIdx>(iter, remLen);
378 auto consumed = reqLen - remLen;
385 if (std::tuple_size<ValueType>::value <= TUntilIdx) {
387 std::advance(iter, remLen);
393 bool refreshLengthInternal()
395 auto& mems = BaseImpl::value();
396 auto& lenField = std::get<TLenFieldIdx>(mems);
397 std::size_t expLen = BaseImpl::template lengthFrom<TLenFieldIdx + 1>();
398 std::size_t actLen =
static_cast<std::size_t
>(lenField.getValue());
399 if (expLen == actLen) {
403 lenField.setValue(expLen);
407 static const std::size_t MaxPossibleLen = 0xffff;
416COMMS_MSVC_WARNING_POP
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
This file contain definition of error statuses used by comms module.
Contains definition of various tag classes.
comms::option::def::RemLengthMemberField< TIdx > RemLengthMemberField
Same as comms::option::def::RemLengthMemberField.
Definition options.h:1967
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1930
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
@ Success
Used to indicate successful outcome of the operation.
@ InvalidMsgData
Used to indicate that a message has invalid data.
Replacement to some types from standard type_traits.