18#include "comms/details/tag.h"
20COMMS_MSVC_WARNING_PUSH
21COMMS_MSVC_WARNING_DISABLE(4127)
32template <std::
size_t TLenFieldIdx,
typename TBase>
35 using BaseImpl = TBase;
37 using ValueType =
typename BaseImpl::ValueType;
39 static_assert(TLenFieldIdx < std::tuple_size<ValueType>::value,
"Bad index");
40 using LengthFieldType =
typename std::tuple_element<TLenFieldIdx, ValueType>::type;
45 refreshLengthInternal();
48 static constexpr std::size_t maxLength()
50 return MaxPossibleLen;
53 template <std::
size_t TFromIdx>
54 static constexpr std::size_t maxLengthFrom()
57 typename comms::util::LazyShallowConditional<
58 TLenFieldIdx < TFromIdx
63 return maxLengthFromInternal<TFromIdx>(Tag());
66 template <std::
size_t TUntilIdx>
67 static constexpr std::size_t maxLengthUntil()
70 typename comms::util::LazyShallowConditional<
71 TUntilIdx <= TLenFieldIdx
77 return maxLengthUntilInternal<TUntilIdx>(Tag());
80 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
81 static constexpr std::size_t maxLengthFromUntil()
84 typename comms::util::LazyShallowConditional<
85 (TUntilIdx <= TLenFieldIdx) || (TLenFieldIdx < TFromIdx)
91 return maxLengthFromUntilInternal<TFromIdx, TUntilIdx>(Tag());
96 bool updated = BaseImpl::refresh();
97 return refreshLengthInternal() || updated;
100 template <
typename TIter>
103 return readFromUntilAndUpdateLen<0, std::tuple_size<ValueType>::value>(iter, len);
106 template <std::
size_t TFromIdx,
typename TIter>
109 return readFromUntilAndUpdateLen<TFromIdx, std::tuple_size<ValueType>::value>(iter, len);
112 template <std::
size_t TFromIdx,
typename TIter>
113 ErrorStatus readFromAndUpdateLen(TIter& iter, std::size_t& len)
115 return readFromAndUpdateLen<TFromIdx, std::tuple_size<ValueType>::value>(iter, len);
118 template <std::
size_t TUntilIdx,
typename TIter>
119 ErrorStatus readUntil(TIter& iter, std::size_t len)
121 return readFromUntilAndUpdateLen<0U, TUntilIdx>(iter, len);
124 template <std::
size_t TUntilIdx,
typename TIter>
125 ErrorStatus readUntilAndUpdateLen(TIter& iter, std::size_t& len)
127 return readFromUntilAndUpdateLen<0, TUntilIdx>(iter, len);
130 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
131 ErrorStatus readFromUntil(TIter& iter, std::size_t len)
133 return readFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
136 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
137 ErrorStatus readFromUntilAndUpdateLen(TIter& iter, std::size_t& len)
140 typename comms::util::LazyShallowConditional<
141 (TUntilIdx <= TLenFieldIdx)
146 return readFromUntilInternal<TFromIdx, TUntilIdx>(iter, len, Tag());
149 template <
typename TIter>
150 void readNoStatus(TIter& iter) =
delete;
152 template <std::
size_t TFromIdx,
typename TIter>
153 void readFromNoStatus(TIter& iter) =
delete;
155 template <std::
size_t TUntilIdx,
typename TIter>
156 void readUntilNoStatus(TIter& iter) =
delete;
158 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
159 void readFromUntilNoStatus(TIter& iter) =
delete;
161 static constexpr bool hasNonDefaultRefresh()
166 bool setVersion(VersionType version)
168 bool updated = BaseImpl::setVersion(version);
169 return refreshLengthInternal() || updated;
172 bool canWrite()
const
174 if (!BaseImpl::canWrite()) {
178 std::size_t expLen = BaseImpl::template lengthFrom<TLenFieldIdx + 1>();
179 if (
static_cast<std::size_t
>(LengthFieldType::maxValue()) < expLen) {
183 LengthFieldType lenField;
184 lenField.setValue(expLen);
185 return lenField.canWrite();
188 template <
typename TIter>
195 return BaseImpl::write(iter, len);
198 static constexpr bool hasWriteNoStatus()
203 template <
typename TIter>
208 return BaseImpl::valid() && canWrite();
212 template <
typename... TParams>
213 using BaseRedirectTag = comms::details::tag::Tag1<>;
215 template <
typename... TParams>
216 using LocalTag = comms::details::tag::Tag2<>;
218 template <
typename... TParams>
219 using PerformOpTag = comms::details::tag::Tag3<>;
221 template <
typename... TParams>
222 using SkipOpTag = comms::details::tag::Tag4<>;
224 template <std::size_t TFromIdx,
typename... TParams>
225 static constexpr std::size_t maxLengthFromInternal(BaseRedirectTag<TParams...>)
227 return BaseImpl::template maxLengthFrom<TFromIdx>();
230 template <std::size_t TFromIdx,
typename... TParams>
231 static constexpr std::size_t maxLengthFromInternal(LocalTag<TParams...>)
233 return MaxPossibleLen;
236 template <std::size_t TUntilIdx,
typename... TParams>
237 static constexpr std::size_t maxLengthUntilInternal(BaseRedirectTag<TParams...>)
239 return BaseImpl::template maxLengthUntil<TUntilIdx>();
242 template <std::size_t TUntilIdx,
typename... TParams>
243 static constexpr std::size_t maxLengthUntilInternal(LocalTag<TParams...>)
245 return MaxPossibleLen;
248 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename... TParams>
249 static constexpr std::size_t maxLengthFromUntilInternal(BaseRedirectTag<TParams...>)
251 return BaseImpl::template maxLengthFromUntil<TFromIdx, TUntilIdx>();
254 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename... TParams>
255 static constexpr std::size_t maxLengthFromUntilInternal(LocalTag<TParams...>)
257 return MaxPossibleLen;
260 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename TIter,
typename... TParams>
261 ErrorStatus readFromUntilInternal(TIter& iter, std::size_t& len, BaseRedirectTag<TParams...>)
263 return BaseImpl::template readFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
266 template <std::size_t TFromIdx,
typename TIter,
typename... TParams>
267 ErrorStatus readEarlierFieldsInternal(TIter& iter, std::size_t& len, PerformOpTag<TParams...>)
269 return BaseImpl::template readFromUntilAndUpdateLen<TFromIdx, TLenFieldIdx>(iter, len);
272 template <std::size_t TFromIdx,
typename TIter,
typename... TParams>
273 ErrorStatus readEarlierFieldsInternal(TIter& iter, std::size_t& len, SkipOpTag<TParams...>)
275 static_cast<void>(iter);
276 static_cast<void>(len);
277 return ErrorStatus::Success;
280 template <
typename TIter,
typename... TParams>
281 ErrorStatus readRemLengthFieldInternal(TIter& iter, std::size_t& len, std::size_t& remLen, PerformOpTag<TParams...>)
283 auto& mems = BaseImpl::value();
284 auto& lenField = std::get<TLenFieldIdx>(mems);
286 auto beforeLenReadIter = iter;
287 auto es = lenField.read(iter, len);
292 auto lenFieldLen =
static_cast<std::size_t
>(std::distance(beforeLenReadIter, iter));
296 remLen =
static_cast<std::size_t
>(lenField.getValue());
297 return ErrorStatus::Success;
300 template <
typename TIter,
typename... TParams>
301 ErrorStatus readRemLengthFieldInternal(TIter& iter, std::size_t& len, std::size_t& remLen, SkipOpTag<TParams...>)
303 static_cast<void>(iter);
304 static_cast<void>(len);
305 auto& mems = BaseImpl::value();
306 auto& lenField = std::get<TLenFieldIdx>(mems);
307 remLen = lenField.value();
308 return ErrorStatus::Success;
311 template <std::size_t TUntilIdx,
typename... TParams>
312 void skipUntilFieldInternal(std::size_t& reqLen, PerformOpTag<TParams...>)
314 static_assert(TLenFieldIdx < TUntilIdx,
"Invalid assumption");
315 auto fieldsLen = BaseImpl::template lengthFromUntil<TLenFieldIdx + 1, TUntilIdx>();
320 template <std::size_t TUntilIdx,
typename... TParams>
321 void skipUntilFieldInternal(std::size_t& reqLen, SkipOpTag<TParams...>)
323 static_cast<void>(reqLen);
326 template <std::size_t TFromIdx, std::size_t TUntilIdx,
typename TIter,
typename... TParams>
327 ErrorStatus readFromUntilInternal(TIter& iter, std::size_t& len, LocalTag<TParams...>)
329 static_assert(TLenFieldIdx < TUntilIdx,
"Invalid function invocation");
330 using EarlierFieldsTag =
331 typename comms::util::LazyShallowConditional<
332 (TFromIdx < TLenFieldIdx)
338 auto es = readEarlierFieldsInternal<TFromIdx>(iter, len, EarlierFieldsTag());
344 typename comms::util::LazyShallowConditional<
345 (TFromIdx <= TLenFieldIdx)
351 std::size_t reqLen = 0U;
352 es = readRemLengthFieldInternal(iter, len, reqLen, LenTag());
358 typename comms::util::LazyShallowConditional<
359 (TLenFieldIdx < TFromIdx)
365 skipUntilFieldInternal<TFromIdx>(reqLen, SkipTag());
367 static const std::size_t NextIdx = (TFromIdx <= TLenFieldIdx) ? TLenFieldIdx + 1 : TFromIdx;
369 if ((std::tuple_size<ValueType>::value <= TUntilIdx) &&
374 auto remLen = std::min(len, reqLen);
375 es = BaseImpl::template readFromUntilAndUpdateLen<NextIdx, TUntilIdx>(iter, remLen);
376 auto consumed = reqLen - remLen;
383 if (std::tuple_size<ValueType>::value <= TUntilIdx) {
385 std::advance(iter, remLen);
391 bool refreshLengthInternal()
393 auto& mems = BaseImpl::value();
394 auto& lenField = std::get<TLenFieldIdx>(mems);
395 std::size_t expLen = BaseImpl::template lengthFrom<TLenFieldIdx + 1>();
396 std::size_t actLen =
static_cast<std::size_t
>(lenField.getValue());
397 if (expLen == actLen) {
401 lenField.setValue(expLen);
406 static const std::size_t MaxPossibleLen = 0xffff;
415COMMS_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:1826
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1797
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.
@ InvalidMsgData
Used to indicate that a message has invalid data.
Replacement to some types from standard type_traits.