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