COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
Optional.h
Go to the documentation of this file.
1//
2// Copyright 2015 - 2024 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
10
11#pragma once
12
13#include "comms/Assert.h"
14#include "comms/ErrorStatus.h"
15#include "details/OptionsParser.h"
16#include "OptionalMode.h"
17#include "basic/Optional.h"
18#include "details/AdaptBasicField.h"
19
20namespace comms
21{
22
23namespace field
24{
25
43template <typename TField, typename... TOptions>
44class Optional : public details::AdaptBasicFieldT<basic::Optional<TField>, TOptions...>
45{
46 using BaseImpl = details::AdaptBasicFieldT<basic::Optional<TField>, TOptions...>;
47public:
49 using Endian = typename BaseImpl::Endian;
50
52 using VersionType = typename BaseImpl::VersionType;
53
55 using ParsedOptions = details::OptionsParser<TOptions...>;
56
58 using CommsTag = typename BaseImpl::CommsTag;
59
61 using Field = TField;
62
65
69
73 using FieldType = typename ParsedOptions::FieldType;
74
77 Optional() = default;
78
81 explicit Optional(const Field& fieldSrc)
82 : BaseImpl(fieldSrc)
83 {
84 }
85
88 explicit Optional(Field&& fieldSrc)
89 : BaseImpl(std::move(fieldSrc))
90 {
91 }
92
94 Optional(const Optional&) = default;
95
97 Optional(Optional&&) = default;
98
100 ~Optional() noexcept = default;
101
103 Optional& operator=(const Optional&) = default;
104
106 Optional& operator=(Optional&&) = default;
107
110 static constexpr bool hasFailOnInvalid()
111 {
112 return ParsedOptions::HasFailOnInvalid;
113 }
114
117 static constexpr bool hasIgnoreInvalid()
118 {
119 return ParsedOptions::HasIgnoreInvalid;
120 }
121
124 static constexpr bool hasEmptySerialization()
125 {
126 return ParsedOptions::HasEmptySerialization;
127 }
128
131 static constexpr bool hasFieldType()
132 {
133 return ParsedOptions::HasFieldType;
134 }
135
139 bool isTentative() const
140 {
141 return BaseImpl::getMode() == Mode::Tentative;
142 }
143
148 {
149 BaseImpl::setMode(Mode::Tentative);
150 }
151
155 bool isMissing() const
156 {
157 return BaseImpl::getMode() == Mode::Missing;
158 }
159
164 {
165 BaseImpl::setMode(Mode::Missing);
166 }
167
171 bool doesExist() const
172 {
173 return BaseImpl::getMode() == Mode::Exists;
174 }
175
180 {
181 BaseImpl::setMode(Mode::Exists);
182 }
183
186 {
187 return BaseImpl::field();
188 }
189
191 const Field& field() const
192 {
193 return BaseImpl::field();
194 }
195
198 {
199 return BaseImpl::value();
200 }
201
203 const ValueType& value() const
204 {
205 return BaseImpl::value();
206 }
207
210 const ValueType& getValue() const
211 {
212 return BaseImpl::getValue();
213 }
214
217 template <typename U>
218 void setValue(U&& val)
219 {
220 BaseImpl::setValue(std::forward<U>(val));
221 }
222
224 Mode getMode() const
225 {
226 return BaseImpl::getMode();
227 }
228
230 void setMode(Mode val)
231 {
232 BaseImpl::setMode(val);
233 }
234
240 std::size_t length() const
241 {
242 return BaseImpl::length();
243 }
244
247 static constexpr std::size_t minLength()
248 {
249 return BaseImpl::minLength();
250 }
251
254 static constexpr std::size_t maxLength()
255 {
256 return BaseImpl::maxLength();
257 }
258
263 bool valid() const
264 {
265 return BaseImpl::valid();
266 }
267
273 bool refresh()
274 {
275 return BaseImpl::refresh();
276 }
277
293 template <typename TIter>
294 ErrorStatus read(TIter& iter, std::size_t len)
295 {
296 return BaseImpl::read(iter, len);
297 }
298
301 static constexpr bool hasReadNoStatus()
302 {
303 return BaseImpl::hasReadNoStatus();
304 }
305
311 template <typename TIter>
312 void readNoStatus(TIter& iter)
313 {
314 BaseImpl::readNoStatus(iter);
315 }
316
318 bool canWrite() const
319 {
320 return BaseImpl::canWrite();
321 }
322
333 template <typename TIter>
334 ErrorStatus write(TIter& iter, std::size_t len) const
335 {
336 return BaseImpl::write(iter, len);
337 }
338
341 static constexpr bool hasWriteNoStatus()
342 {
343 return BaseImpl::hasWriteNoStatus();
344 }
345
351 template <typename TIter>
352 void writeNoStatus(TIter& iter) const
353 {
354 BaseImpl::writeNoStatus(iter);
355 }
356
358 static constexpr bool isVersionDependent()
359 {
360 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
361 }
362
364 static constexpr bool hasNonDefaultRefresh()
365 {
366 return BaseImpl::hasNonDefaultRefresh();
367 }
368
372 {
373 return BaseImpl::getVersion();
374 }
375
379 {
380 return BaseImpl::setVersion(version);
381 }
382
383protected:
384 using BaseImpl::readData;
385 using BaseImpl::writeData;
386
387private:
388 static_assert(!ParsedOptions::HasInvalidByDefault,
389 "comms::option::def::InvalidByDefault option is not applicable to Optional field");
390};
391
397template <typename TField, typename... TOptions>
399 const Optional<TField, TOptions...>& field1,
400 const Optional<TField, TOptions...>& field2) noexcept
401{
402 if (field1.getMode() != field2.getMode()) {
403 return false;
404 }
405
406 if (field1.isMissing()) {
407 return true;
408 }
409
410 return field1.field() == field2.field();
411}
412
418template <typename TField, typename... TOptions>
420 const Optional<TField, TOptions...>& field1,
421 const Optional<TField, TOptions...>& field2) noexcept
422{
423 return !(field1 == field2);
424}
425
431template <typename TField, typename... TOptions>
433 const Optional<TField, TOptions...>& field1,
434 const Optional<TField, TOptions...>& field2) noexcept
435{
436 if (field1.isMissing()) {
437 return !field2.isMissing();
438 }
439
440 if (field2.isMissing()) {
441 return false;
442 }
443
444 return field1.field() < field2.field();
445}
446
452template <typename TField, typename... TOptions>
454 const Optional<TField, TOptions...>& field1,
455 const Optional<TField, TOptions...>& field2) noexcept
456{
457 return (field2 < field1);
458}
459
465template <typename TField, typename... TOptions>
467 const Optional<TField, TOptions...>& field1,
468 const Optional<TField, TOptions...>& field2) noexcept
469{
470 return (field1 < field2) || (field1 == field2);
471}
472
478template <typename TField, typename... TOptions>
480 const Optional<TField, TOptions...>& field1,
481 const Optional<TField, TOptions...>& field2) noexcept
482{
483 return field2 <= field1;
484}
485
491template <typename T>
492constexpr bool isOptional()
493{
494 return std::is_same<typename T::CommsTag, tag::Optional>::value;
495}
496
500template <typename TField, typename... TOptions>
501inline
502Optional<TField, TOptions...>&
504{
505 return field;
506}
507
511template <typename TField, typename... TOptions>
512inline
513const Optional<TField, TOptions...>&
515{
516 return field;
517}
518
519} // namespace field
520
521} // namespace comms
522
523
This file contains classes required for generic custom assertion functionality.
This file contain definition of error statuses used by comms module.
Contains definition of the mode used for comms::field::Optional fields.
Adaptor class to any other field, that makes the field optional.
Definition Optional.h:45
bool operator<(const Optional< TField, TOptions... > &field1, const Optional< TField, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition Optional.h:432
bool operator<=(const Optional< TField, TOptions... > &field1, const Optional< TField, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition Optional.h:466
ErrorStatus read(TIter &iter, std::size_t len)
Read field value from input data sequence.
Definition Optional.h:294
Optional()=default
Default constructor.
Optional(const Field &fieldSrc)
Construct the field.
Definition Optional.h:81
bool operator>(const Optional< TField, TOptions... > &field1, const Optional< TField, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition Optional.h:453
VersionType getVersion() const
Get version of the field.
Definition Optional.h:371
constexpr bool isOptional()
Compile time check function of whether a provided type is any variant of comms::field::Optional.
Definition Optional.h:492
void setExists()
Set mode to Mode::Exists.
Definition Optional.h:179
TField Field
Type of the field.
Definition Optional.h:61
const ValueType & getValue() const
Get value.
Definition Optional.h:210
const Field & field() const
Get an access to the wrapped field object.
Definition Optional.h:191
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition Optional.h:352
Optional(Field &&fieldSrc)
Construct the field.
Definition Optional.h:88
bool isTentative() const
Check whether mode is equivalent to Mode::Tentative.
Definition Optional.h:139
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition Optional.h:312
bool operator>=(const Optional< TField, TOptions... > &field1, const Optional< TField, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition Optional.h:479
Field & field()
Get an access to the wrapped field object.
Definition Optional.h:185
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition Optional.h:55
bool operator!=(const Optional< TField, TOptions... > &field1, const Optional< TField, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition Optional.h:419
void setMissing()
Set mode to Mode::Missing.
Definition Optional.h:163
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition Optional.h:58
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition Optional.h:131
Optional< TField, TOptions... > & toFieldBase(Optional< TField, TOptions... > &field)
Upcast type of the field definition to its parent comms::field::Optional type in order to have access...
Definition Optional.h:503
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition Optional.h:358
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition Optional.h:254
void setValue(U &&val)
Set value.
Definition Optional.h:218
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition Optional.h:117
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition Optional.h:318
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition Optional.h:301
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition Optional.h:364
const ValueType & value() const
Get an access to the wrapped field object.
Definition Optional.h:203
ValueType & value()
Get an access to the wrapped field object.
Definition Optional.h:197
bool doesExist() const
Check whether mode is equivalent to Mode::Exists.
Definition Optional.h:171
Mode getMode() const
Get current optional mode.
Definition Optional.h:224
Optional(const Optional &)=default
Copy constructor.
const Optional< TField, TOptions... > & toFieldBase(const Optional< TField, TOptions... > &field)
Upcast type of the field definition to its parent comms::field::Optional type in order to have access...
Definition Optional.h:514
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition Optional.h:49
std::size_t length() const
Get length required to serialise the current field value.
Definition Optional.h:240
~Optional() noexcept=default
Destructor.
void setMode(Mode val)
Get optional mode.
Definition Optional.h:230
bool operator==(const Optional< TField, TOptions... > &field1, const Optional< TField, TOptions... > &field2) noexcept
Equality comparison operator.
Definition Optional.h:398
static constexpr bool hasFailOnInvalid()
Compile time inquiry of whether comms::option::def::FailOnInvalid option has been used.
Definition Optional.h:110
bool valid() const
Check validity of the field value.
Definition Optional.h:263
bool isMissing() const
Check whether mode is equivalent to Mode::Missing.
Definition Optional.h:155
Field ValueType
Value type of this field, equal to Field.
Definition Optional.h:64
typename BaseImpl::VersionType VersionType
Version type.
Definition Optional.h:52
ErrorStatus write(TIter &iter, std::size_t len) const
Write current field value to output data sequence.
Definition Optional.h:334
bool refresh()
Refresh the field's value.
Definition Optional.h:273
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition Optional.h:341
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition Optional.h:247
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition Optional.h:124
bool setVersion(VersionType version)
Default implementation of version update.
Definition Optional.h:378
Optional(Optional &&)=default
Move constructor.
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition Optional.h:73
void setTentative()
Set mode to Mode::Tentative.
Definition Optional.h:147
OptionalMode
Mode to be used by comms::field::Optional.
Definition OptionalMode.h:22
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:64
STL namespace.