COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
Optional.h
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
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
16namespace comms
17{
18
19namespace field
20{
21
22namespace basic
23{
24
25template <typename TField>
26class Optional : public
28 comms::option::def::Endian<typename TField::Endian>,
29 comms::option::def::VersionType<typename TField::VersionType>
30 >
31{
32 using BaseImpl =
36 >;
37
38public:
39
40 using Field = TField;
41 using ValueType = TField;
42 using Mode = field::OptionalMode;
43 using VersionType = typename BaseImpl::VersionType;
44 using CommsTag = comms::field::tag::Optional;
45
46 Optional() = default;
47
48 explicit Optional(const Field& fieldSrc, Mode mode = Mode::Tentative)
49 : field_(fieldSrc),
50 mode_(mode)
51 {
52 }
53
54 explicit Optional(Field&& fieldSrc, Mode mode = Mode::Tentative)
55 : field_(std::move(fieldSrc)),
56 mode_(mode)
57 {
58 }
59
60 Optional(const Optional&) = default;
61
62 Optional(Optional&&) = default;
63
64 ~Optional() noexcept = default;
65
66 Optional& operator=(const Optional&) = default;
67
68 Optional& operator=(Optional&&) = default;
69
70 Field& field()
71 {
72 return field_;
73 }
74
75 const Field& field() const
76 {
77 return field_;
78 }
79
80 ValueType& value()
81 {
82 return field();
83 }
84
85 const ValueType& value() const
86 {
87 return field();
88 }
89
90 const ValueType& getValue() const
91 {
92 return value();
93 }
94
95 template <typename T>
96 void setValue(T&& val)
97 {
98 value() = std::forward<T>(val);
99 }
100
101 Mode getMode() const
102 {
103 return mode_;
104 }
105
106 void setMode(Mode val)
107 {
108 COMMS_ASSERT(val < Mode::NumOfModes);
109 mode_ = val;
110 }
111
112 std::size_t length() const
113 {
114 if (mode_ != Mode::Exists) {
115 return 0U;
116 }
117
118 return field_.length();
119 }
120
121 static constexpr std::size_t minLength()
122 {
123 return 0U;
124 }
125
126 static constexpr std::size_t maxLength()
127 {
128 return Field::maxLength();
129 }
130
131 bool valid() const
132 {
133 if (mode_ == Mode::Missing) {
134 return true;
135 }
136
137 return field_.valid();
138 }
139
140 bool refresh() {
141 if (mode_ != Mode::Exists) {
142 return false;
143 }
144 return field_.refresh();
145 }
146
147 template <typename TIter>
148 ErrorStatus read(TIter& iter, std::size_t len)
149 {
150 if (mode_ == Mode::Missing) {
152 }
153
154 if ((mode_ == Mode::Tentative) && (0U == len)) {
155 mode_ = Mode::Missing;
157 }
158
159 auto es = field_.read(iter, len);
160 if (es == comms::ErrorStatus::Success) {
161 mode_ = Mode::Exists;
162 }
163 return es;
164 }
165
166 static constexpr bool hasReadNoStatus()
167 {
168 return false;
169 }
170
171 bool canWrite() const
172 {
173 if (mode_ != Mode::Exists) {
174 return true;
175 }
176
177 return field_.canWrite();
178 }
179
180 template <typename TIter>
181 ErrorStatus write(TIter& iter, std::size_t len) const
182 {
183 if (mode_ != Mode::Exists) {
185 }
186
187 return field_.write(iter, len);
188 }
189
190 static constexpr bool hasWriteNoStatus()
191 {
193 }
194
195 template <typename TIter>
196 void writeNoStatus(TIter& iter) const
197 {
198 if (mode_ != Mode::Exists) {
199 return;
200 }
201
202 field_.writeNoStatus(iter);
203 }
204
205 static constexpr bool isVersionDependent()
206 {
208 }
209
210 static constexpr bool hasNonDefaultRefresh()
211 {
213 }
214
215 bool setVersion(VersionType version)
216 {
217 return field_.setVersion(static_cast<typename Field::VersionType>(version));
218 }
219
220private:
221 Field field_;
222 Mode mode_ = Mode::Tentative;
223};
224
225} // namespace basic
226
227} // namespace field
228
229} // namespace comms
230
231
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:1159