COMMS
Template library intended to help with implementation of communication protocols.
|
#include "comms/field/Variant.h"
Defines a "variant" field, that can contain any of the provided ones.
The Variant object contains uninitialised buffer that can fit any of the provided field types (as second template parameter). At any given point of time this space can be initialised and used to contain at most one of the specified field types. It resembles a classic union, but disallows set value of one field type and read it as other. The Variant field abstraction provides expected single field API functions, such as length(), read(), write(), valid().
Refer to Variant Fields for tutorial and usage examples.
TFieldBase | Base class for this field, expected to be a variant of comms::Field. |
TMembers | All supported field types bundled together in std::tuple. This parameter is used to determine the size of the contained buffer to be able to fit any of the specified types. |
TOptions | Zero or more options that modify/refine default behaviour of the field. Supported options are:
|
Public Types | |
using | CommsTag = typename BaseImpl::CommsTag |
Tag indicating type of the field. | |
using | Endian = typename BaseImpl::Endian |
Endian used for serialisation. | |
using | FieldBase = TFieldBase |
Base class provided in the first template parameter. | |
using | FieldType = typename ParsedOptions::FieldType |
Type of actual extending field specified via comms::option::def::FieldType. | |
using | Members = typename BaseImpl::Members |
All the supported types. | |
using | ParsedOptions = details::OptionsParser< TOptions... > |
All the options provided to this class bundled into struct. | |
using | ValueType = typename BaseImpl::ValueType |
Value type. | |
using | VersionType = typename BaseImpl::VersionType |
Version type. | |
Public Member Functions | |
Variant ()=default | |
Default constructor. | |
Variant (const ValueType &val) | |
Constructor. | |
Variant (ValueType &&val) | |
Constructor. | |
template<std::size_t TIdx> | |
std::tuple_element< TIdx, Members >::type & | accessField () |
Access already constructed field at specifed index (known at compile time). | |
template<std::size_t TIdx> | |
const std::tuple_element< TIdx, Members >::type & | accessField () const |
Access already constructed field at specifed index (known at compile time). | |
bool | canWrite () const |
Check of whether the field has a consistent value for writing. | |
std::size_t | currentField () const |
Get index of the current field (within the Members tuple). | |
template<typename TFunc > | |
void | currentFieldExec (TFunc &&func) |
Execute provided function object with current field as parameter. | |
template<typename TFunc > | |
void | currentFieldExec (TFunc &&func) const |
Execute provided function object with current field as parameter (const variant). | |
bool | currentFieldValid () const |
Check whether the field contains a valid instance of other field. | |
template<std::size_t TIdx> | |
void | deinitField () |
Destruct previously initialised (via initField()) contained field. | |
const ValueType & | getValue () const |
Get value. | |
VersionType | getVersion () const |
Get version of the field. | |
template<std::size_t TIdx, typename... TArgs> | |
std::tuple_element< TIdx, Members >::type & | initField (TArgs &&... args) |
Construct and initialise specified contained field in the internal buffer. | |
std::size_t | length () const |
Get length required to serialise contained fields. | |
template<typename TIter > | |
ErrorStatus | read (TIter &iter, std::size_t size) |
Read field value from input data sequence. | |
template<typename TIter > | |
void | readNoStatus (TIter &iter)=delete |
Read operation without error check and status report is not supported. | |
bool | refresh () |
Refresh the field's value. | |
void | reset () |
Invalidate current state. | |
void | selectField (std::size_t idx) |
Select type of the variant field. | |
template<typename U > | |
void | setValue (U &&val) |
Set value. | |
bool | setVersion (VersionType version) |
Default implementation of version update. | |
bool | valid () const |
Check validity of all the contained field. | |
ValueType & | value () |
Get access to the internal storage buffer. | |
const ValueType & | value () const |
Get access to the internal storage buffer. | |
template<typename TIter > | |
ErrorStatus | write (TIter &iter, std::size_t size) const |
Write current field value to output data sequence. | |
template<typename TIter > | |
void | writeNoStatus (TIter &iter) const |
Write current field value to output data sequence without error check and status report. | |
Static Public Member Functions | |
static constexpr bool | canWrite () |
Default check of whether the field has a consistent value for writing. | |
static constexpr bool | hasEmptySerialization () |
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used. | |
static constexpr bool | hasFailOnInvalid () |
Compile time inquiry of whether comms::option::def::FailOnInvalid option has been used. | |
static constexpr bool | hasFieldType () |
Compile time inquiry of whether comms::option::def::FieldType option has been used. | |
static constexpr bool | hasIgnoreInvalid () |
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used. | |
static constexpr bool | hasNonDefaultRefresh () |
Compile time check if this class has non-default refresh functionality. | |
static constexpr bool | hasReadNoStatus () |
Compile time check of whether the field has proper readNoStatus() member function. | |
static constexpr bool | hasVarLength () |
Default check of whether the field has variable length definition via comms::option::def::VarLength option. | |
static constexpr bool | hasWriteNoStatus () |
Compile time check of whether the field has proper writeNoStatus() member function. | |
static constexpr bool | isVersionDependent () |
Compile time check if this class is version dependent. | |
static constexpr std::size_t | maxLength () |
Get maximal length that is required to serialise all possible contained fields. | |
static constexpr std::size_t | minLength () |
Get minimal length that is required to serialise all possible contained fields. | |
static constexpr bool | valid () |
Default validity check. | |
Static Protected Member Functions | |
template<typename T , typename TIter > | |
static T | readData (TIter &iter) |
Read data from input buffer. | |
template<typename T , std::size_t TSize, typename TIter > | |
static T | readData (TIter &iter) |
Read partial data from input buffer. | |
template<typename T , typename TIter > | |
static void | writeData (T value, TIter &iter) |
Write data into the output buffer. | |
template<std::size_t TSize, typename T , typename TIter > | |
static void | writeData (T value, TIter &iter) |
Write partial data into the output buffer. | |
Related Symbols | |
(Note that these are not member symbols.) | |
#define | COMMS_VARIANT_MEMBERS_ACCESS(...) |
Add convenience access enum and functions to the members of comms::field::Variant field. | |
#define | COMMS_VARIANT_MEMBERS_ACCESS_NOTEMPLATE(...) |
Similar to COMMS_VARIANT_MEMBERS_ACCESS(), but dedicated for non-template classes. | |
#define | COMMS_VARIANT_MEMBERS_NAMES(...) |
Provide names for member fields of comms::field::Variant field. | |
template<typename T > | |
constexpr bool | isVariant () |
Compile time check function of whether a provided type is any variant of comms::field::Variant. | |
template<typename TFieldBase , typename TMembers , typename... TOptions> | |
bool | operator!= (const Variant< TFieldBase, TMembers, TOptions... > &field1, const Variant< TFieldBase, TMembers, TOptions... > &field2) |
Non-equality comparison operator. | |
template<typename TFieldBase , typename TMembers , typename... TOptions> | |
bool | operator< (const Variant< TFieldBase, TMembers, TOptions... > &field1, const Variant< TFieldBase, TMembers, TOptions... > &field2) |
Order comparison operator. | |
template<typename TFieldBase , typename TMembers , typename... TOptions> | |
bool | operator== (const Variant< TFieldBase, TMembers, TOptions... > &field1, const Variant< TFieldBase, TMembers, TOptions... > &field2) |
Equality comparison operator. | |
template<typename TFieldBase , typename TMembers , typename... TOptions> | |
const Variant< TFieldBase, TMembers, TOptions... > & | toFieldBase (const Variant< TFieldBase, TMembers, TOptions... > &field) |
Upcast type of the field definition to its parent comms::field::Variant type in order to have access to its internal types. | |
template<typename TFieldBase , typename TMembers , typename... TOptions> | |
Variant< TFieldBase, TMembers, TOptions... > & | toFieldBase (Variant< TFieldBase, TMembers, TOptions... > &field) |
Upcast type of the field definition to its parent comms::field::Variant type in order to have access to its internal types. | |
using comms::field::Variant< TFieldBase, TMembers, TOptions >::FieldType = typename ParsedOptions::FieldType |
Type of actual extending field specified via comms::option::def::FieldType.
void if comms::option::def::FieldType hasn't been applied.
using comms::field::Variant< TFieldBase, TMembers, TOptions >::Members = typename BaseImpl::Members |
All the supported types.
Same as TMemebers template argument, i.e. it is std::tuple of all the wrapped fields.
using comms::field::Variant< TFieldBase, TMembers, TOptions >::ValueType = typename BaseImpl::ValueType |
Value type.
Type of the internal buffer used to store contained field, should not be used in normal operation.
|
default |
Default constructor.
Invokes default constructor of every wrapped field
std::tuple_element< TIdx, Members >::type & comms::field::Variant< TFieldBase, TMembers, TOptions >::accessField | ( | ) |
Access already constructed field at specifed index (known at compile time).
Use this function to get a reference to the contained field type
TIdx | Index of the field type witin the Members tuple. |
const std::tuple_element< TIdx, Members >::type & comms::field::Variant< TFieldBase, TMembers, TOptions >::accessField | ( | ) | const |
Access already constructed field at specifed index (known at compile time).
Use this function to get a const reference to the contained field type.
TIdx | Index of the field type witin the Members tuple. |
|
staticconstexprinherited |
Default check of whether the field has a consistent value for writing.
std::size_t comms::field::Variant< TFieldBase, TMembers, TOptions >::currentField | ( | ) | const |
void comms::field::Variant< TFieldBase, TMembers, TOptions >::currentFieldExec | ( | TFunc && | func | ) |
Execute provided function object with current field as parameter.
The provided function object must define all the public operator() member functions to handle all possible types.
NOTE, that every operator() is expecting to receive an index of the type within the holding tuple as a template parameter. If the index information is not needed it may be either ignored or static_assert-ed upon.
The operator() may also receive a member field type as a template parameter.
The TField will be the actual type of the contained field. If the Variant field doesn't contain any valid field, the functor will NOT be called.
void comms::field::Variant< TFieldBase, TMembers, TOptions >::currentFieldExec | ( | TFunc && | func | ) | const |
Execute provided function object with current field as parameter (const variant).
Similar to other currentFieldExec() variant, but with const. Note, the constness of the parameter.
The TField will be the actual type of the contained field. If the Variant field doesn't contain any valid field, the functor will NOT be called.
bool comms::field::Variant< TFieldBase, TMembers, TOptions >::currentFieldValid | ( | ) | const |
Check whether the field contains a valid instance of other field.
Returns true if and only if currentField() returns a valid index inside the Members tuple.
void comms::field::Variant< TFieldBase, TMembers, TOptions >::deinitField | ( | ) |
Destruct previously initialised (via initField()) contained field.
TIdx | Index of the field type witin the Members tuple. |
const ValueType & comms::field::Variant< TFieldBase, TMembers, TOptions >::getValue | ( | ) | const |
Get value.
Should not be used in normal operation
VersionType comms::field::Variant< TFieldBase, TMembers, TOptions >::getVersion | ( | ) | const |
Get version of the field.
Exists only if comms::option::def::VersionStorage option has been provided and/or any of the member fields is version dependent.
|
staticconstexprinherited |
Default check of whether the field has variable length definition via comms::option::def::VarLength option.
std::tuple_element< TIdx, Members >::type & comms::field::Variant< TFieldBase, TMembers, TOptions >::initField | ( | TArgs &&... | args | ) |
Construct and initialise specified contained field in the internal buffer.
If the field already contains a valid field it must be cleared via explicit deinitField() or reset() calls.
TIdx | Index of the field type witin the Members tuple. |
TArgs | Types of the agurments for the field's constructor |
[in] | args | Arguments for the constructed field. |
std::size_t comms::field::Variant< TFieldBase, TMembers, TOptions >::length | ( | ) | const |
Get length required to serialise contained fields.
If the field doesn't contain a valid instance of other field, the reported length is 0, otherwise the length of the contained field is reported.
|
staticconstexpr |
Get maximal length that is required to serialise all possible contained fields.
|
staticconstexpr |
Get minimal length that is required to serialise all possible contained fields.
ErrorStatus comms::field::Variant< TFieldBase, TMembers, TOptions >::read | ( | TIter & | iter, |
std::size_t | size | ||
) |
Read field value from input data sequence.
Invokes read() member function over every possible field in order of definition until comms::ErrorStatus::Success is returned.
[in,out] | iter | Iterator to read the data. |
[in] | size | Number of bytes available for reading. |
|
staticprotectedinherited |
Read data from input buffer.
Use this function to read data from the intput buffer maintained by the caller. The endianness of the data will be as specified in options of the class.
T | Return type |
TIter | Type of input iterator |
[in,out] | iter | Input iterator. |
|
staticprotectedinherited |
Read partial data from input buffer.
Use this function to read data from the intput buffer maintained by the caller. The endianness of the data will be as specified in options of the class.
T | Return type |
TSize | number of bytes to read |
TIter | Type of input iterator |
[in,out] | iter | Input iterator. |
bool comms::field::Variant< TFieldBase, TMembers, TOptions >::refresh | ( | ) |
Refresh the field's value.
Invokes refresh() member function of the current field if such exists, otherwise returns false.
void comms::field::Variant< TFieldBase, TMembers, TOptions >::reset | ( | ) |
Invalidate current state.
Destructs currently contained field if such exists.
void comms::field::Variant< TFieldBase, TMembers, TOptions >::selectField | ( | std::size_t | idx | ) |
Select type of the variant field.
If the same index has been selected before, the function does nothing, otherwise the currently selected member field is destructed, and the new one is default constructed.
If provided index is equal or exceeds the size of the Members tuple, no new field is constructed.
[in] | idx | Index of the type within Members tuple. |
void comms::field::Variant< TFieldBase, TMembers, TOptions >::setValue | ( | U && | val | ) |
Set value.
Should not be used in normal operation
bool comms::field::Variant< TFieldBase, TMembers, TOptions >::setVersion | ( | VersionType | version | ) |
Default implementation of version update.
|
staticconstexprinherited |
Default validity check.
Always returns true, can be overriden by the derived class
bool comms::field::Variant< TFieldBase, TMembers, TOptions >::valid | ( | ) | const |
Check validity of all the contained field.
Returns false if doesn't contain any field.
ValueType & comms::field::Variant< TFieldBase, TMembers, TOptions >::value | ( | ) |
Get access to the internal storage buffer.
Should not be used in normal operation.
const ValueType & comms::field::Variant< TFieldBase, TMembers, TOptions >::value | ( | ) | const |
Get access to the internal storage buffer.
Should not be used in normal operation.
ErrorStatus comms::field::Variant< TFieldBase, TMembers, TOptions >::write | ( | TIter & | iter, |
std::size_t | size | ||
) | const |
Write current field value to output data sequence.
Invokes write() member function of the contained field if such exists. If the Variant field doesn't contain any valid field, the function doesn't advance the iterator, but returns comms::ErrorStatus::Success.
[in,out] | iter | Iterator to write the data. |
[in] | size | Maximal number of bytes that can be written. |
|
staticprotectedinherited |
Write data into the output buffer.
Use this function to write data to the the buffer maintained by the caller. The endianness of the data will be as specified in the options provided to the class.
T | Type of the value to write. Must be integral. |
Type | of output iterator |
[in] | value | Integral type value to be written. |
[in,out] | iter | Output iterator. |
|
staticprotectedinherited |
Write partial data into the output buffer.
Use this function to write partial data to the buffer maintained by the caller. The endianness of the data will be as specified the class options.
TSize | Length of the value in bytes known in compile time. |
T | Type of the value to write. Must be integral. |
TIter | Type of output iterator |
[in] | value | Integral type value to be written. |
[in,out] | iter | Output iterator. |
void comms::field::Variant< TFieldBase, TMembers, TOptions >::writeNoStatus | ( | TIter & | iter | ) | const |
Write current field value to output data sequence without error check and status report.
Similar to write(), but doesn't perform any correctness checks and doesn't report any failures.
[in,out] | iter | Iterator to write the data. |
|
related |
Add convenience access enum and functions to the members of comms::field::Variant field.
Very similar to COMMS_VARIANT_MEMBERS_NAMES(), but does NOT require definition of Base inner member type (for some compilers) and does NOT define inner Field_* types for used member fields.
[in] | ... | List of fields' names. |
|
related |
Similar to COMMS_VARIANT_MEMBERS_ACCESS(), but dedicated for non-template classes.
The COMMS_VARIANT_MEMBERS_ACCESS() macro is a generic one, which can be used in any class (template, or non-template). However, some compilers (such as g++-4.9 and below, clang-4.0 and below) may fail to compile it even though it uses valid C++11 constructs. If the compilation fails and the class it is being used in is NOT a template one, please use COMMS_VARIANT_MEMBERS_ACCESS_NOTEMPLATE() instead.
|
related |
Provide names for member fields of comms::field::Variant field.
All the possible field types the comms::field::Variant field can contain are bundled in std::tuple and provided as a template parameter to the definition of the comms::field::Variant field.
However, it would be convenient to provide names and easier access to all the poisble variants. The COMMS_VARIANT_MEMBERS_NAMES() macro does exactly that when used inside the field class definition. Just inherit from the comms::field::Variant class and use the macro inside with the names for the member fields:
NOTE that there is a required to have Base member type that specifies base class used.
Usage of COMMS_FIELD_MEMBERS_NAMES() macro is equivalent to having the following types and functions definitions:
NOTE, that provided names member1, member2, and member3, have found their way to the following definitions:
See Variant Fields for more examples and details
[in] | ... | List of member fields' names. |
|
related |
Compile time check function of whether a provided type is any variant of comms::field::Variant.
T | Any type. |
|
related |
Non-equality comparison operator.
[in] | field1 | First field. |
[in] | field2 | Second field. |
|
related |
Order comparison operator.
[in] | field1 | First field. |
[in] | field2 | Second field. |
|
related |
Equality comparison operator.
[in] | field1 | First field. |
[in] | field2 | Second field. |