COMMS
Template library intended to help with implementation of communication protocols.
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 
20 namespace comms
21 {
22 
23 namespace field
24 {
25 
43 template <typename TField, typename... TOptions>
44 class Optional : public details::AdaptBasicFieldT<basic::Optional<TField>, TOptions...>
45 {
46  using BaseImpl = details::AdaptBasicFieldT<basic::Optional<TField>, TOptions...>;
47 public:
49  using Endian = typename BaseImpl::Endian;
50 
53 
55  using ParsedOptions = details::OptionsParser<TOptions...>;
56 
58  using CommsTag = typename BaseImpl::CommsTag;
59 
61  using Field = TField;
62 
64  using ValueType = Field;
65 
68  using Mode = OptionalMode;
69 
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 
163  void setMissing()
164  {
165  BaseImpl::setMode(Mode::Missing);
166  }
167 
171  bool doesExist() const
172  {
173  return BaseImpl::getMode() == Mode::Exists;
174  }
175 
179  void setExists()
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 
383 protected:
384  using BaseImpl::readData;
385  using BaseImpl::writeData;
386 
387 private:
388  static_assert(!ParsedOptions::HasInvalidByDefault,
389  "comms::option::def::InvalidByDefault option is not applicable to Optional field");
390 };
391 
397 template <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 
418 template <typename TField, typename... TOptions>
420  const Optional<TField, TOptions...>& field1,
421  const Optional<TField, TOptions...>& field2) noexcept
422 {
423  return !(field1 == field2);
424 }
425 
431 template <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 
452 template <typename TField, typename... TOptions>
454  const Optional<TField, TOptions...>& field1,
455  const Optional<TField, TOptions...>& field2) noexcept
456 {
457  return (field2 < field1);
458 }
459 
465 template <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 
478 template <typename TField, typename... TOptions>
480  const Optional<TField, TOptions...>& field1,
481  const Optional<TField, TOptions...>& field2) noexcept
482 {
483  return field2 <= field1;
484 }
485 
491 template <typename T>
492 constexpr bool isOptional()
493 {
494  return std::is_same<typename T::CommsTag, tag::Optional>::value;
495 }
496 
500 template <typename TField, typename... TOptions>
501 inline
502 Optional<TField, TOptions...>&
504 {
505  return field;
506 }
507 
511 template <typename TField, typename... TOptions>
512 inline
513 const 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
ValueType & value()
Get an access to the wrapped field object.
Definition: Optional.h:197
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 & value() const
Get an access to the wrapped field object.
Definition: Optional.h:203
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
const Field & field() const
Get an access to the wrapped field object.
Definition: Optional.h:191
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
const ValueType & getValue() const
Get value.
Definition: Optional.h:210
Field & field()
Get an access to the wrapped field object.
Definition: Optional.h:185
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
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
comms::option::def::HasCustomVersionUpdate HasCustomVersionUpdate
Same as comms::option::def::HasCustomVersionUpdate.
Definition: options.h:1800
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition: options.h:1797
comms::option::def::FieldType< TMsg > FieldType
Same as comms::option::def::FieldType.
Definition: options.h:1463
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition: options.h:1438
T readData(TIter &iter, const traits::endian::Big &endian)
Same as readBig<T, TIter>()
Definition: access.h:766
void writeData(T value, TIter &iter, const traits::endian::Big &endian)
Same as writeBig<T, TIter>()
Definition: access.h:698
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