COMMS
Template library intended to help with implementation of communication protocols.
Field.h
Go to the documentation of this file.
1 //
2 // Copyright 2014 - 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 <type_traits>
14 
15 #include "comms/util/access.h"
16 #include "comms/details/FieldBase.h"
17 #include "comms/details/macro_common.h"
18 #include "comms/details/fields_access.h"
19 #include "comms/details/field_alias.h"
20 
21 namespace comms
22 {
23 
31 template <typename... TOptions>
32 class Field : public details::FieldBase<TOptions...>
33 {
34  using BaseImpl = details::FieldBase<TOptions...>;
35 public:
39  using Endian = typename BaseImpl::Endian;
40 
43 
47  static constexpr bool valid()
48  {
49  return true;
50  }
51 
56  static constexpr bool refresh()
57  {
58  return false;
59  }
60 
63  static constexpr bool isVersionDependent()
64  {
65  return false;
66  }
67 
70  static constexpr bool hasNonDefaultRefresh()
71  {
72  return false;
73  }
74 
77  static constexpr bool hasReadNoStatus()
78  {
79  return true;
80  }
81 
84  static constexpr bool hasWriteNoStatus()
85  {
86  return true;
87  }
88 
92  static constexpr bool hasVarLength()
93  {
94  return false;
95  }
96 
100  static constexpr bool canWrite()
101  {
102  return true;
103  }
104 
109  static constexpr bool setVersion(VersionType)
110  {
111  return false;
112  }
113 
114 protected:
127  template <typename T, typename TIter>
128  static void writeData(T value, TIter& iter)
129  {
130  writeData<sizeof(T), T>(value, iter);
131  }
132 
147  template <std::size_t TSize, typename T, typename TIter>
148  static void writeData(T value, TIter& iter)
149  {
150  static_assert(TSize <= sizeof(T),
151  "Cannot put more bytes than type contains");
152  return util::writeData<TSize, T>(value, iter, Endian());
153  }
154 
168  template <typename T, typename TIter>
169  static T readData(TIter& iter)
170  {
171  return readData<T, sizeof(T)>(iter);
172  }
173 
188  template <typename T, std::size_t TSize, typename TIter>
189  static T readData(TIter& iter)
190  {
191  static_assert(TSize <= sizeof(T),
192  "Cannot get more bytes than type contains");
193  return util::readData<T, TSize>(iter, Endian());
194  }
195 
196 };
197 
236 #define COMMS_FIELD_MEMBERS_ACCESS(...) \
237  COMMS_EXPAND(COMMS_DEFINE_FIELD_ENUM(__VA_ARGS__)) \
238  COMMS_FIELD_VALUE_ACCESS_FUNC { \
239  auto& val = comms::field::toFieldBase(*this).value(); \
240  using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
241  static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
242  "Invalid number of names for fields tuple"); \
243  return val; \
244  } \
245  COMMS_FIELD_VALUE_ACCESS_CONST_FUNC { \
246  auto& val = comms::field::toFieldBase(*this).value(); \
247  using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
248  static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
249  "Invalid number of names for fields tuple"); \
250  return val; \
251  } \
252  COMMS_EXPAND(COMMS_DO_FIELD_ACC_FUNC(ValueType, value(), __VA_ARGS__))
253 
266 #define COMMS_FIELD_MEMBERS_ACCESS_NOTEMPLATE(...) \
267  COMMS_EXPAND(COMMS_DEFINE_FIELD_ENUM(__VA_ARGS__)) \
268  COMMS_EXPAND(COMMS_DO_FIELD_ACC_FUNC_NOTEMPLATE(__VA_ARGS__))
269 
380 #define COMMS_FIELD_MEMBERS_NAMES(...) \
381  COMMS_EXPAND(COMMS_FIELD_MEMBERS_ACCESS(__VA_ARGS__)) \
382  COMMS_EXPAND(COMMS_DO_FIELD_TYPEDEF(typename Base::ValueType, Field_, FieldIdx_, __VA_ARGS__))
383 
390 #define COMMS_FIELD_ALIAS(f_, ...) COMMS_DO_ALIAS(field_, f_, __VA_ARGS__)
391 
392 } // namespace comms
393 
Contains functions for raw data access / (de)serialization.
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 void writeData(T value, TIter &iter)
Write data into the output buffer.
Definition: Field.h:128
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 refresh()
Default refresh functionality.
Definition: Field.h:56
static T readData(TIter &iter)
Read data from input buffer.
Definition: Field.h:169
static constexpr bool hasReadNoStatus()
Default check of whether the field has readNoStatus() member function.
Definition: Field.h:77
typename BaseImpl::Endian Endian
Endian type.
Definition: Field.h:39
typename BaseImpl::VersionType VersionType
Version type.
Definition: Field.h:42
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
static void writeData(T value, TIter &iter)
Write partial data into the output buffer.
Definition: Field.h:148
static T readData(TIter &iter)
Read partial data from input buffer.
Definition: Field.h:189
static constexpr bool valid()
Default validity check.
Definition: Field.h:47
static constexpr bool hasVarLength()
Default check of whether the field has variable length definition via comms::option::def::VarLength o...
Definition: Field.h:92
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition: options.h:1797
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition: options.h:1438
Main namespace for all classes / functions of COMMS library.