COMMS
Template library intended to help with implementation of communication protocols.
Public Types | Public Member Functions | Static Public Member Functions | Static Protected Member Functions | Related Functions | List of all members
comms::field::Variant< TFieldBase, TMembers, TOptions > Class Template Reference

#include "comms/field/Variant.h"

Detailed Description

template<typename TFieldBase, typename TMembers, typename... TOptions>
class comms::field::Variant< TFieldBase, TMembers, TOptions >

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.

Template Parameters
TFieldBaseBase class for this field, expected to be a variant of comms::Field.
TMembersAll 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.
TOptionsZero or more options that modify/refine default behaviour of the field.
Supported options are:
See also
COMMS_VARIANT_MEMBERS_NAMES()
COMMS_VARIANT_MEMBERS_ACCESS()
COMMS_VARIANT_MEMBERS_ACCESS_NOTEMPLATE()
Inheritance diagram for comms::field::Variant< TFieldBase, TMembers, TOptions >:
comms::Field< TOptions >

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. More...
 
using Members = typename BaseImpl::Members
 All the supported types. More...
 
using ParsedOptions = details::OptionsParser< TOptions... >
 All the options provided to this class bundled into struct.
 
using ValueType = typename BaseImpl::ValueType
 Value type. More...
 
using VersionType = typename BaseImpl::VersionType
 Version type.
 

Public Member Functions

 Variant ()=default
 Default constructor. More...
 
 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). More...
 
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). More...
 
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). More...
 
template<typename TFunc >
void currentFieldExec (TFunc &&func)
 Execute provided function object with current field as parameter. More...
 
template<typename TFunc >
void currentFieldExec (TFunc &&func) const
 Execute provided function object with current field as parameter (const variant). More...
 
bool currentFieldValid () const
 Check whether the field contains a valid instance of other field. More...
 
template<std::size_t TIdx>
void deinitField ()
 Destruct previously initialised (via initField()) contained field. More...
 
const ValueTypegetValue () const
 Get value. More...
 
VersionType getVersion () const
 Get version of the field. More...
 
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. More...
 
std::size_t length () const
 Get length required to serialise contained fields. More...
 
template<typename TIter >
ErrorStatus read (TIter &iter, std::size_t size)
 Read field value from input data sequence. More...
 
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. More...
 
void reset ()
 Invalidate current state. More...
 
void selectField (std::size_t idx)
 Select type of the variant field. More...
 
template<typename U >
void setValue (U &&val)
 Set value. More...
 
bool setVersion (VersionType version)
 Default implementation of version update. More...
 
bool valid () const
 Check validity of all the contained field. More...
 
ValueTypevalue ()
 Get access to the internal storage buffer. More...
 
const ValueTypevalue () const
 Get access to the internal storage buffer. More...
 
template<typename TIter >
ErrorStatus write (TIter &iter, std::size_t size) const
 Write current field value to output data sequence. More...
 
template<typename TIter >
void writeNoStatus (TIter &iter) const
 Write current field value to output data sequence without error check and status report. More...
 

Static Public Member Functions

static constexpr bool canWrite ()
 Default check of whether the field has a consistent value for writing. More...
 
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. More...
 
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. More...
 
static constexpr std::size_t minLength ()
 Get minimal length that is required to serialise all possible contained fields. More...
 
static constexpr bool valid ()
 Default validity check. More...
 

Static Protected Member Functions

template<typename T , typename TIter >
static T readData (TIter &iter)
 Read data from input buffer. More...
 
template<typename T , std::size_t TSize, typename TIter >
static T readData (TIter &iter)
 Read partial data from input buffer. More...
 
template<typename T , typename TIter >
static void writeData (T value, TIter &iter)
 Write data into the output buffer. More...
 
template<std::size_t TSize, typename T , typename TIter >
static void writeData (T value, TIter &iter)
 Write partial data into the output buffer. More...
 

Related Functions

(Note that these are not member functions.)

#define COMMS_VARIANT_MEMBERS_ACCESS(...)
 Add convenience access enum and functions to the members of comms::field::Variant field. More...
 
#define COMMS_VARIANT_MEMBERS_ACCESS_NOTEMPLATE(...)
 Similar to COMMS_VARIANT_MEMBERS_ACCESS(), but dedicated for non-template classes. More...
 
#define COMMS_VARIANT_MEMBERS_NAMES(...)
 Provide names for member fields of comms::field::Variant field. More...
 
template<typename T >
constexpr bool isVariant ()
 Compile time check function of whether a provided type is any variant of comms::field::Variant. More...
 
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. More...
 
template<typename TFieldBase , typename TMembers , typename... TOptions>
bool operator< (const Variant< TFieldBase, TMembers, TOptions... > &field1, const Variant< TFieldBase, TMembers, TOptions... > &field2)
 Order comparison operator. More...
 
template<typename TFieldBase , typename TMembers , typename... TOptions>
bool operator== (const Variant< TFieldBase, TMembers, TOptions... > &field1, const Variant< TFieldBase, TMembers, TOptions... > &field2)
 Equality comparison operator. More...
 
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.
 

Member Typedef Documentation

◆ FieldType

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

◆ Members

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

◆ ValueType

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

Constructor & Destructor Documentation

◆ Variant()

template<typename TFieldBase , typename TMembers , typename... TOptions>
comms::field::Variant< TFieldBase, TMembers, TOptions >::Variant ( )
default

Default constructor.

Invokes default constructor of every wrapped field

Member Function Documentation

◆ accessField() [1/2]

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<std::size_t TIdx>
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

Template Parameters
TIdxIndex of the field type witin the Members tuple.
Returns
Reference to the contained field.
Precondition
currentField() == TIdx
std::size_t currentField() const
Get index of the current field (within the Members tuple).
Definition: Variant.h:305

◆ accessField() [2/2]

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<std::size_t TIdx>
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.

Template Parameters
TIdxIndex of the field type witin the Members tuple.
Returns
Const reference to the contained field.
Precondition
currentField() == TIdx

◆ canWrite()

template<typename... TOptions>
static constexpr bool comms::Field< TOptions >::canWrite ( )
staticconstexprinherited

Default check of whether the field has a consistent value for writing.

Returns
Always true.

◆ currentField()

template<typename TFieldBase , typename TMembers , typename... TOptions>
std::size_t comms::field::Variant< TFieldBase, TMembers, TOptions >::currentField ( ) const

Get index of the current field (within the Members tuple).

If the Variant field doesn't contain any valid field, the returned index is equivalent to size of the Members tuple.

◆ currentFieldExec() [1/2]

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<typename TFunc >
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.

struct MyFunc
{
template <std::size_t TIdx>
void operator()(Type1& field) {...}
template <std::size_t TIdx>
void operator()(Type2& field) {...}
...
}

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.

struct MyFunc
{
template <std::size_t TIdx, typename TField>
void operator()(TField& field)
{
... // do somethign with the field
}
}

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.

◆ currentFieldExec() [2/2]

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<typename TFunc >
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.

struct MyFunc
{
template <std::size_t TIdx, typename TField>
void operator()(const TField& field)
{
... // do somethign with the field
}
}

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.

◆ currentFieldValid()

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

◆ deinitField()

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<std::size_t TIdx>
void comms::field::Variant< TFieldBase, TMembers, TOptions >::deinitField ( )

Destruct previously initialised (via initField()) contained field.

Template Parameters
TIdxIndex of the field type witin the Members tuple.
TArgsTypes of the agurments for the field's constructor
Parameters
[in]argsArguments for the constructed field.
Precondition
The field must contain an expected member field
assert(currentField() == TIdx);

◆ getValue()

template<typename TFieldBase , typename TMembers , typename... TOptions>
const ValueType& comms::field::Variant< TFieldBase, TMembers, TOptions >::getValue ( ) const

Get value.

Should not be used in normal operation

◆ getVersion()

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

◆ hasVarLength()

template<typename... TOptions>
static constexpr bool comms::Field< TOptions >::hasVarLength ( )
staticconstexprinherited

Default check of whether the field has variable length definition via comms::option::def::VarLength option.

Returns
Always false.

◆ initField()

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<std::size_t TIdx, typename... TArgs>
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.

Template Parameters
TIdxIndex of the field type witin the Members tuple.
TArgsTypes of the agurments for the field's constructor
Parameters
[in]argsArguments for the constructed field.
Precondition
The field must NOT contain any other member field
assert(!currentFieldValid());
bool currentFieldValid() const
Check whether the field contains a valid instance of other field.
Definition: Variant.h:445
Returns
Reference to the constructed field.

◆ length()

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

Returns
Number of bytes it will take to serialise the field value.

◆ maxLength()

template<typename TFieldBase , typename TMembers , typename... TOptions>
static constexpr std::size_t comms::field::Variant< TFieldBase, TMembers, TOptions >::maxLength ( )
staticconstexpr

Get maximal length that is required to serialise all possible contained fields.

Returns
Maximal number of bytes required serialise the field value.

◆ minLength()

template<typename TFieldBase , typename TMembers , typename... TOptions>
static constexpr std::size_t comms::field::Variant< TFieldBase, TMembers, TOptions >::minLength ( )
staticconstexpr

Get minimal length that is required to serialise all possible contained fields.

Returns
Always returns 0.

◆ read()

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<typename TIter >
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.

Parameters
[in,out]iterIterator to read the data.
[in]sizeNumber of bytes available for reading.
Returns
Status of read operation.
Postcondition
Iterator is advanced.

◆ readData() [1/2]

template<typename... TOptions>
template<typename T , typename TIter >
static T comms::Field< TOptions >::readData ( TIter &  iter)
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.

Template Parameters
TReturn type
TIterType of input iterator
Parameters
[in,out]iterInput iterator.
Returns
The integral type value.
Precondition
TSize <= sizeof(T)
The iterator must be valid and can be successfully dereferenced and incremented at least sizeof(T) times.
Postcondition
The iterator is advanced.
Note
Thread safety: Safe for distinct stream buffers, unsafe otherwise.

◆ readData() [2/2]

template<typename... TOptions>
template<typename T , std::size_t TSize, typename TIter >
static T comms::Field< TOptions >::readData ( TIter &  iter)
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.

Template Parameters
TReturn type
TSizenumber of bytes to read
TIterType of input iterator
Parameters
[in,out]iterInput iterator.
Returns
The integral type value.
Precondition
TSize <= sizeof(T)
The iterator must be valid and can be successfully dereferenced and incremented at least TSize times.
Postcondition
The internal pointer of the stream buffer is advanced.
Note
Thread safety: Safe for distinct stream buffers, unsafe otherwise.

◆ refresh()

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

Returns
true if the value has been updated, false otherwise

◆ reset()

template<typename TFieldBase , typename TMembers , typename... TOptions>
void comms::field::Variant< TFieldBase, TMembers, TOptions >::reset ( )

Invalidate current state.

Destructs currently contained field if such exists.

◆ selectField()

template<typename TFieldBase , typename TMembers , typename... TOptions>
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.

Parameters
[in]idxIndex of the type within Members tuple.

◆ setValue()

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<typename U >
void comms::field::Variant< TFieldBase, TMembers, TOptions >::setValue ( U &&  val)

Set value.

Should not be used in normal operation

◆ setVersion()

template<typename TFieldBase , typename TMembers , typename... TOptions>
bool comms::field::Variant< TFieldBase, TMembers, TOptions >::setVersion ( VersionType  version)

Default implementation of version update.

Returns
true in case the field contents have changed, false otherwise

◆ valid() [1/2]

template<typename... TOptions>
static constexpr bool comms::Field< TOptions >::valid ( )
staticconstexprinherited

Default validity check.

Always returns true, can be overriden by the derived class

Returns
Always true

◆ valid() [2/2]

template<typename TFieldBase , typename TMembers , typename... TOptions>
bool comms::field::Variant< TFieldBase, TMembers, TOptions >::valid ( ) const

Check validity of all the contained field.

Returns false if doesn't contain any field.

◆ value() [1/2]

template<typename TFieldBase , typename TMembers , typename... TOptions>
ValueType& comms::field::Variant< TFieldBase, TMembers, TOptions >::value ( )

Get access to the internal storage buffer.

Should not be used in normal operation.

◆ value() [2/2]

template<typename TFieldBase , typename TMembers , typename... TOptions>
const ValueType& comms::field::Variant< TFieldBase, TMembers, TOptions >::value ( ) const

Get access to the internal storage buffer.

Should not be used in normal operation.

◆ write()

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<typename TIter >
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.

Parameters
[in,out]iterIterator to write the data.
[in]sizeMaximal number of bytes that can be written.
Returns
Status of write operation.
Postcondition
Iterator is advanced.

◆ writeData() [1/2]

template<typename... TOptions>
template<typename T , typename TIter >
static void comms::Field< TOptions >::writeData ( value,
TIter &  iter 
)
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.

Template Parameters
TType of the value to write. Must be integral.
Typeof output iterator
Parameters
[in]valueIntegral type value to be written.
[in,out]iterOutput iterator.
Precondition
The iterator must be valid and can be successfully dereferenced and incremented at least sizeof(T) times.
Postcondition
The iterator is advanced.
Note
Thread safety: Safe for distinct buffers, unsafe otherwise.

◆ writeData() [2/2]

template<typename... TOptions>
template<std::size_t TSize, typename T , typename TIter >
static void comms::Field< TOptions >::writeData ( value,
TIter &  iter 
)
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.

Template Parameters
TSizeLength of the value in bytes known in compile time.
TType of the value to write. Must be integral.
TIterType of output iterator
Parameters
[in]valueIntegral type value to be written.
[in,out]iterOutput iterator.
Precondition
TSize <= sizeof(T)
The iterator must be valid and can be successfully dereferenced and incremented at least TSize times.
Postcondition
The iterator is advanced.
Note
Thread safety: Safe for distinct buffers, unsafe otherwise.

◆ writeNoStatus()

template<typename TFieldBase , typename TMembers , typename... TOptions>
template<typename TIter >
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.

Parameters
[in,out]iterIterator to write the data.
Postcondition
Iterator is advanced.

Friends And Related Function Documentation

◆ COMMS_VARIANT_MEMBERS_ACCESS

template<typename TFieldBase , typename TMembers , typename... TOptions>
#define COMMS_VARIANT_MEMBERS_ACCESS (   ...)
related
Value:
COMMS_EXPAND(COMMS_DEFINE_FIELD_ENUM(__VA_ARGS__)) \
COMMS_AS_VARIANT_FUNC { \
auto& var = comms::field::toFieldBase(*this); \
using Var = typename std::decay<decltype(var)>::type; \
static_assert(std::tuple_size<typename Var::Members>::value == FieldIdx_numOfValues, \
"Invalid number of names for variant field"); \
return var; \
}\
COMMS_AS_VARIANT_CONST_FUNC { \
auto& var = comms::field::toFieldBase(*this); \
using Var = typename std::decay<decltype(var)>::type; \
static_assert(std::tuple_size<typename Var::Members>::value == FieldIdx_numOfValues, \
"Invalid number of names for variant field"); \
return var; \
} \
COMMS_DO_VARIANT_MEM_ACC_FUNC(asVariant(), __VA_ARGS__)
Bundle< TFieldBase, TMembers, TOptions... > & toFieldBase(Bundle< TFieldBase, TMembers, TOptions... > &field)
Upcast type of the field definition to its parent comms::field::Bundle type in order to have access t...
Definition: Bundle.h:805

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.

Parameters
[in]...List of fields' names.
Warning
Some compilers, such as clang or early versions of g++ may have problems compiling code generated by this macro even though it uses valid C++11 constructs in attempt to automatically identify the type of the base class. If the compilation fails, and this macro resides inside a NON-template class, please use COMMS_VARIANT_MEMBERS_ACCESS_NOTEMPLATE() macro instead. In case this macro needs to reside inside a template class, then there is a need to define inner Base type, which specifies exact type of the comms::field::Variant class. For example:
template <typename... TExtraOptions>
class MyField : public
MyFieldBase,
std::tuple<Field1, Field2, Field3>,
TExtraOptions...
>
{
// Duplicate the base class definition
using Base =
MyFieldBase,
std::tuple<Field1, Field2, Field3>,
TExtraOptions...
>;
public:
COMMS_VARIANT_MEMBERS_ACCESS(member1, member2, member3);
};
Defines a "variant" field, that can contain any of the provided ones.
Definition: Variant.h:79
#define COMMS_VARIANT_MEMBERS_ACCESS(...)
Add convenience access enum and functions to the members of comms::field::Variant field.
Definition: Variant.h:748

◆ COMMS_VARIANT_MEMBERS_ACCESS_NOTEMPLATE

template<typename TFieldBase , typename TMembers , typename... TOptions>
#define COMMS_VARIANT_MEMBERS_ACCESS_NOTEMPLATE (   ...)
related
Value:
COMMS_EXPAND(COMMS_DEFINE_FIELD_ENUM(__VA_ARGS__)) \
COMMS_DO_VARIANT_MEM_ACC_FUNC_NOTEMPLATE(__VA_ARGS__)

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.

◆ COMMS_VARIANT_MEMBERS_NAMES

template<typename TFieldBase , typename TMembers , typename... TOptions>
#define COMMS_VARIANT_MEMBERS_NAMES (   ...)
related
Value:
COMMS_EXPAND(COMMS_VARIANT_MEMBERS_ACCESS(__VA_ARGS__)) \
COMMS_EXPAND(COMMS_DO_FIELD_TYPEDEF(typename Base::Members, Field_, FieldIdx_, __VA_ARGS__))

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.

using Field1 = ...;
using Field2 = ...;
using Field3 = ...;
using MyField =
MyFieldBase,
std::tuple<Field1, Field2, Field3>
>;
MyField field;
auto& field1 = field.initField<0>(); // Initialise the field to contain Field1 value
field1.value() = ...;
Base class to all the field classes.
Definition: Field.h:33
std::tuple_element< TIdx, Members >::type & initField(TArgs &&... args)
Construct and initialise specified contained field in the internal buffer.
Definition: Variant.h:400

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:

class MyField : public comms::field::Variant<...>
{
// (Re)definition of the base class as inner Base type is
// the required of COMMS_VARIANT_MEMBERS_NAMES() macro.
using Base = comms::field::Variant<...>;
public:
COMMS_FIELD_MEMBERS_NAMES(member1, member2, member3);
}
#define COMMS_FIELD_MEMBERS_NAMES(...)
Provide names for member fields of composite fields, such as comms::field::Bundle or comms::field::Bi...
Definition: Field.h:380

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:

class MyField : public comms::field::Variant<...>
{
public:
// Access indices for member fields
enum FieldIdx {
FieldIdx_member1,
FieldIdx_member2,
FieldIdx_member3,
FieldIdx_numOfValues
};
// Initialise as first member (Field1)
template <typename... TArgs>
Field1& initField_member1(TArgs&&... args)
{
rerturn initField<FieldIdx_member1>(std::forward<TArgs>(args)...);
}
// De-initialise first member (Field1)
void deinitField_member1()
{
rerturn deinitField<FieldIdx_member1>();
}
// Accessor to the stored field as first member (Field1)
Field1& accessField_member1()
{
return accessField<FieldIdx_member1>();
}
// Const variant of the accessor to the stored field as first member (Field1)
const Field1& accessField_member1() const
{
return accessField<FieldIdx_member1>();
}
// Initialise as second member (Field2)
template <typename... TArgs>
Field2& initField_member2(TArgs&&... args)
{
rerturn initField<FieldIdx_member2>(std::forward<TArgs>(args)...);
}
// De-initialise second member (Field2)
void deinitField_member2()
{
rerturn deinitField<FieldIdx_member2>();
}
// Accessor to the stored field as second member (Field2)
Field2& accessField_member2()
{
return accessField<FieldIdx_member2>();
}
// Const variant of the accessor to the stored field as second member (Field2)
const Field2& accessField_member2() const
{
return accessField<FieldIdx_member2>();
}
// Initialise as third member (Field3)
template <typename... TArgs>
Field3& initField_member3(TArgs&&... args)
{
rerturn initField<FieldIdx_member3>(std::forward<TArgs>(args)...);
}
// De-initialise third member (Field3)
void deinitField_member3()
{
rerturn deinitField<FieldIdx_member3>();
}
// Accessor to the stored field as third member (Field3)
Field3& accessField_member3()
{
return accessField<FieldIdx_member3>();
}
// Const variant of the accessor to the stored field as third member (Field3)
const Field3& accessField_member3() const
{
return accessField<FieldIdx_member3>();
}
// Redefinition of the field types:
using Field_member1 = Field1;
using Field_member2 = Field2;
using Field_member3 = Field3;
};

NOTE, that provided names member1, member2, and member3, have found their way to the following definitions:

  • FieldIdx enum. The names are prefixed with FieldIdx_. The FieldIdx_nameOfValues value is automatically added at the end.
  • Initialisation functions prefixed with initField_
  • De-initialisation functions prefixed with deinitField_
  • Accessor functions prefixed with accessField_
  • Types of fields prefixed with Field_*

See Variant Fields for more examples and details

Parameters
[in]...List of member fields' names.
Note
Defined in "comms/field/Variant.h"
See also
COMMS_VARIANT_MEMBERS_ACCESS()
Variant Fields

◆ isVariant()

template<typename T >
constexpr bool isVariant ( )
related

Compile time check function of whether a provided type is any variant of comms::field::Variant.

Template Parameters
TAny type.
Returns
true in case provided type is any variant of Variant

◆ operator!=()

template<typename TFieldBase , typename TMembers , typename... TOptions>
bool operator!= ( const Variant< TFieldBase, TMembers, TOptions... > &  field1,
const Variant< TFieldBase, TMembers, TOptions... > &  field2 
)
related

Non-equality comparison operator.

Parameters
[in]field1First field.
[in]field2Second field.
Returns
true in case fields are NOT equal, false otherwise.

◆ operator<()

template<typename TFieldBase , typename TMembers , typename... TOptions>
bool operator< ( const Variant< TFieldBase, TMembers, TOptions... > &  field1,
const Variant< TFieldBase, TMembers, TOptions... > &  field2 
)
related

Order comparison operator.

Parameters
[in]field1First field.
[in]field2Second field.

◆ operator==()

template<typename TFieldBase , typename TMembers , typename... TOptions>
bool operator== ( const Variant< TFieldBase, TMembers, TOptions... > &  field1,
const Variant< TFieldBase, TMembers, TOptions... > &  field2 
)
related

Equality comparison operator.

Parameters
[in]field1First field.
[in]field2Second field.
Returns
true in case fields are equal, false otherwise.

The documentation for this class was generated from the following file: