COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
Optional.h
1//
2// Copyright 2015 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#pragma once
11
12#include "comms/Assert.h"
13#include "comms/ErrorStatus.h"
14#include "comms/Field.h"
16#include "comms/field/tag.h"
17
18#include <cstddef>
19#include <utility>
20
21namespace comms
22{
23
24namespace field
25{
26
27namespace basic
28{
29
30template <typename TField>
31class Optional : public
33 comms::option::def::Endian<typename TField::Endian>,
34 comms::option::def::VersionType<typename TField::VersionType>
35 >
36{
37 using BaseImpl =
41 >;
42
43public:
44
45 using Field = TField;
46 using ValueType = TField;
47 using Mode = field::OptionalMode;
48 using VersionType = typename BaseImpl::VersionType;
49 using CommsTag = comms::field::tag::Optional;
50
51 Optional() = default;
52
53 explicit Optional(const Field& fieldSrc, Mode mode = Mode::Tentative)
54 : m_field(fieldSrc),
55 m_mode(mode)
56 {
57 }
58
59 explicit Optional(Field&& fieldSrc, Mode mode = Mode::Tentative)
60 : m_field(std::move(fieldSrc)),
61 m_mode(mode)
62 {
63 }
64
65 Optional(const Optional&) = default;
66
67 Optional(Optional&&) = default;
68
69 ~Optional() noexcept = default;
70
71 Optional& operator=(const Optional&) = default;
72
73 Optional& operator=(Optional&&) = default;
74
75 Field& field()
76 {
77 return m_field;
78 }
79
80 const Field& field() const
81 {
82 return m_field;
83 }
84
85 ValueType& value()
86 {
87 return field();
88 }
89
90 const ValueType& value() const
91 {
92 return field();
93 }
94
95 const ValueType& getValue() const
96 {
97 return value();
98 }
99
100 template <typename T>
101 void setValue(T&& val)
102 {
103 value() = std::forward<T>(val);
104 }
105
106 Mode getMode() const
107 {
108 return m_mode;
109 }
110
111 void setMode(Mode val)
112 {
113 COMMS_ASSERT(val < Mode::NumOfModes);
114 m_mode = val;
115 }
116
117 std::size_t length() const
118 {
119 if (m_mode != Mode::Exists) {
120 return 0U;
121 }
122
123 return m_field.length();
124 }
125
126 static constexpr std::size_t minLength()
127 {
128 return 0U;
129 }
130
131 static constexpr std::size_t maxLength()
132 {
133 return Field::maxLength();
134 }
135
136 bool valid() const
137 {
138 if (m_mode == Mode::Missing) {
139 return true;
140 }
141
142 return m_field.valid();
143 }
144
145 bool refresh() {
146 if (m_mode != Mode::Exists) {
147 return false;
148 }
149 return m_field.refresh();
150 }
151
152 template <typename TIter>
153 ErrorStatus read(TIter& iter, std::size_t len)
154 {
155 if (m_mode == Mode::Missing) {
157 }
158
159 if ((m_mode == Mode::Tentative) && (0U == len)) {
160 m_mode = Mode::Missing;
162 }
163
164 auto es = m_field.read(iter, len);
165 if (es == comms::ErrorStatus::Success) {
166 m_mode = Mode::Exists;
167 }
168 return es;
169 }
170
171 static constexpr bool hasReadNoStatus()
172 {
173 return false;
174 }
175
176 bool canWrite() const
177 {
178 if (m_mode != Mode::Exists) {
179 return true;
180 }
181
182 return m_field.canWrite();
183 }
184
185 template <typename TIter>
186 ErrorStatus write(TIter& iter, std::size_t len) const
187 {
188 if (m_mode != Mode::Exists) {
190 }
191
192 return m_field.write(iter, len);
193 }
194
195 static constexpr bool hasWriteNoStatus()
196 {
198 }
199
200 template <typename TIter>
201 void writeNoStatus(TIter& iter) const
202 {
203 if (m_mode != Mode::Exists) {
204 return;
205 }
206
207 m_field.writeNoStatus(iter);
208 }
209
210 static constexpr bool isVersionDependent()
211 {
213 }
214
215 static constexpr bool hasNonDefaultRefresh()
216 {
218 }
219
220 bool setVersion(VersionType version)
221 {
222 return m_field.setVersion(static_cast<typename Field::VersionType>(version));
223 }
224
225private:
226 Field m_field;
227 Mode m_mode = Mode::Tentative;
228};
229
230} // namespace basic
231
232} // namespace field
233
234} // namespace comms
235
This file contains classes required for generic custom assertion functionality.
#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 comms::Field class.
Contains definition of the mode used for comms::field::Optional fields.
Base class to all the field classes.
Definition Field.h:36
static constexpr bool canWrite()
Default check of whether the field has a consistent value for writing.
Definition Field.h:103
static constexpr bool setVersion(VersionType)
Default version update functionality.
Definition Field.h:112
static constexpr bool isVersionDependent()
Default check of whether the field is version dependent.
Definition Field.h:66
static constexpr bool hasReadNoStatus()
Default check of whether the field has readNoStatus() member function.
Definition Field.h:80
static constexpr bool hasNonDefaultRefresh()
Default check of whether the field has defines refresh functionality.
Definition Field.h:73
static constexpr bool hasWriteNoStatus()
Default check of whether the field has writeNoStatus() member function.
Definition Field.h:87
Contains definition of various tag classes.
OptionalMode
Mode to be used by comms::field::Optional.
Definition OptionalMode.h:24
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.
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:66
STL namespace.
Options to specify endian.
Definition options.h:172
Provide type to be used for versioning.
Definition options.h:1184