Skip to content

Commit

Permalink
Release v5.2
Browse files Browse the repository at this point in the history
  • Loading branch information
arobenko committed Apr 18, 2023
2 parents 0c726eb + 3cfdc90 commit 5307f10
Show file tree
Hide file tree
Showing 79 changed files with 2,168 additions and 902 deletions.
22 changes: 10 additions & 12 deletions doc/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ of available options and other input parameters.

## Choosing C++ Standard

Since CMake v3.1 it became possible to set version of C++ standard by setting
Since CMake **v3.1** it became possible to set version of C++ standard by setting
**CMAKE_CXX_STANDARD** variable. If no value of this variable is set in command
line arguments, default value **11** will be assigned to it. In order to use
c++14 standard in compilation, set the variable value to **14**.
Expand All @@ -29,26 +29,24 @@ generate Makefile-s on Windows by providing additional **-G "NMake Makefiles"**
to **cmake**. In this case use **nmake** utility instead of **make**.

Please review the examples below and use appropriate option that suites your
needs. Remember to add **-DCMAKE_BUILD_TYPE=Release** option for release
builds.
needs.

### Install Headers of the **COMMS** Library Linux Example

### Complete Build Linux Example
```
$> cd /path/to/comms
$> mkdir build && cd build
$> cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/some/install/dir
$> cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/some/install/dir
$> make install
```

### Install Only Headers-only **COMMS** Library Linux Example
This example will skip build of any tool available, it will just install
the **COMMS** library headers in **install/include** subdirectory.
### Build Unittests in Debug Mode Linux Example

```
$> cd /path/to/comms
$> mkdir build && cd build
$> cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/some/install/dir \
-DCC_COMMS_BUILD_UNIT_TESTS=OFF
$> cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/some/install/dir \
-DCC_COMMS_BUILD_UNIT_TESTS=ON
$> make install
```
### Windows + Visual Studio Build Example
Expand All @@ -57,8 +55,8 @@ Generate Makefile-s with **cmake** and use Visual Studio compiler to build.
```
$> cd /path/to/comms
$> mkdir build && cd build
$> cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/some/install/dir \
-G "NMake Makefiles" ..
$> cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/some/install/dir \
-G "NMake Makefiles"
$> nmake install
```

Expand Down
2 changes: 1 addition & 1 deletion doc/CMake.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ If the package was successfully found, the target `cc::comms` needs
to be defined. Linking to `cc::comms` target will add all the relevant
include paths.

Since **v5.1" the comms library can also be found using the following calls:
Since **v5.1** the comms library can also be found using the following calls:
```
find_package(comms NO_MODULE)
find_package(cc_comms NO_MODULE)
Expand Down
53 changes: 53 additions & 0 deletions doxygen/page_prot_stack.dox
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,59 @@
/// COMMS_PROTOCOL_LAYERS_ACCESS(payload, id, size, checksum, sync);
/// };
/// @endcode
/// Since **v5.2** the COMMS library defines @ref COMMS_PROTOCOL_LAYERS_NAMES() and
/// @ref COMMS_PROTOCOL_LAYERS_NAMES_OUTER() macros they are similar to
/// the @ref COMMS_PROTOCOL_LAYERS_NAMES() and @ref COMMS_PROTOCOL_LAYERS_NAMES_OUTER()
/// respectively, but also provide aliases to the layer types. However usage of these
/// macros requires inner **Base** type definition of the base class:
/// @code
/// template <
/// typename TMessage, // common interface class defined by the application
/// typename TInputMessages = AllMessages<TMessage>, // Input messages that need to be recognised
/// typename TAllocationOptions = comms::option::app::EmptyOption, // Extra options for MsgIdLayer
/// typename TPayloadOptions = comms::option::app::EmptyOption // Extra options for payload storage
/// >
/// class ProtocolStack : public
/// MySyncPrefix<TMessage, TInputMessages, TAllocationOptions, TPayloadOptions>
/// {
/// // Base type definition is a requirement
/// using Base = MySyncPrefix<TMessage, TInputMessages, TAllocationOptions, TPayloadOptions>
/// public:
/// COMMS_PROTOCOL_LAYERS_NAMES(payload, id, size, checksum, sync);
/// };
/// @endcode
/// It is equivalent to having the following types and member function being defined:
/// @code
/// template <
/// typename TMessage, // common interface class defined by the application
/// typename TInputMessages = AllMessages<TMessage>, // Input messages that need to be recognised
/// typename TAllocationOptions = comms::option::app::EmptyOption, // Extra options for MsgIdLayer
/// typename TPayloadOptions = comms::option::app::EmptyOption // Extra options for payload storage
/// >
/// struct ProtocolStack : public
/// MySyncPrefix<TMessage, TInputMessages, TAllocationOptions, TPayloadOptions>
/// {
/// using Layer_payload = ...;
/// decltype(auto) layer_payload();
/// decltype(auto) layer_payload() const;
///
/// using Layer_id = ...;
/// decltype(auto) layer_id();
/// decltype(auto) layer_id() const;
///
/// using Layer_size = ...;
/// decltype(auto) layer_size();
/// decltype(auto) layer_size() const;
///
/// using Layer_checksum = ...;
/// decltype(auto) layer_checksum();
/// decltype(auto) layer_checksum() const;
///
/// using Layer_sync = ...;
/// decltype(auto) layer_sync();
/// decltype(auto) layer_sync() const;
/// };
/// @endcode
///
/// @section page_prot_stack_tutorial_new_layers Implementing New Layers
/// Every protocol is unique, and there is a chance that COMMS library doesn't
Expand Down
1 change: 1 addition & 0 deletions doxygen/page_use_prot.dox
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,7 @@
/// MyVariant var;
/// auto& prop1 = var.initField_prop1(); // Initialize as Property1 (1 byte integral value)
/// assert(prop1.field_length().value() == 1U);
/// prop1.deinitField_prop1(); // Must be de-initialized before re-initialization as something else
/// auto& prop3 = var.initField_prop3(); // Re-initialize as Property3 (empty string)
/// assert(prop3.field_length().value() == 0U); // Remaining length of empty string
/// @endcode
Expand Down
8 changes: 8 additions & 0 deletions include/comms/Field.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ class Field : public details::FieldBase<TOptions...>
return true;
}

/// @brief Default check of whether the field has variable length definition
/// via @ref comms::option::def::VarLength option.
/// @return Always @b false.
static constexpr bool hasVarLength()
{
return false;
}

/// @brief Default check of whether the field has a consistent value
/// for writing.
/// @return Always @b true.
Expand Down
9 changes: 9 additions & 0 deletions include/comms/Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Message : public details::MessageInterfaceBuilderT<TOptions...>
public:

/// @brief All the options bundled into struct.
/// @details For internal use only.
using InterfaceOptions = details::MessageInterfaceOptionsParser<TOptions...>;

/// @brief Destructor.
Expand Down Expand Up @@ -172,6 +173,14 @@ class Message : public details::MessageInterfaceBuilderT<TOptions...>
return InterfaceOptions::HasVersionInExtraTransportFields;
}

/// @brief Compile type inquiry of version field index in transport field.
/// @details If @ref comms::option::def::VersionInExtraTransportFields option
/// hasn't been used, the @b std::numeric_limits<std::size_t>::max() is returned.
static constexpr std::size_t versionIdxInTransportFields()
{
return InterfaceOptions::VersionInExtraTransportFields;
}

/// @brief Compile type inquiry whether message interface class defines
/// @ref name() and @ref nameImpl() member functions.
static constexpr bool hasName()
Expand Down
102 changes: 102 additions & 0 deletions include/comms/MessageBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ namespace comms
/// @li @ref comms::option::def::HasDoGetId - Enable implementation of getIdImpl() even if
/// @ref comms::option::def::StaticNumIdImpl option wasn't used. Must be paired with
/// @ref comms::option::def::MsgType.
/// @li @ref comms::option::def::HasName - Notify @ref comms::MessageBase that
/// there is custom doName() member function in the message definition class.
/// @li @ref comms::option::def::FailOnInvalid - Fail the read operation if the contents are invalid.
/// @li @ref comms::option::app::NoReadImpl - Inhibit the implementation of readImpl().
/// @li @ref comms::option::app::NoWriteImpl - Inhibit the implementation of writeImpl().
Expand All @@ -82,8 +84,108 @@ class MessageBase : public details::MessageImplBuilderT<TMessage, TOptions...>
using BaseImpl = details::MessageImplBuilderT<TMessage, TOptions...>;
public:
/// @brief All the options provided to this class bundled into struct.
/// @details For internal use only
using ImplOptions = details::MessageImplOptionsParser<TOptions...>;

/// @brief Type of the actual message provided via
/// @ref comms::option::def::MsgType.
/// @details If @ref comms::option::def::MsgType hasn't been used
/// equals to @b void.
using MsgType = typename ImplOptions::MsgType;

/// @brief Compile type inquiry whether static numeric id has been provided via
/// @ref comms::option::def::StaticNumIdImpl.
static constexpr bool hasStaticMsgId()
{
return ImplOptions::HasStaticMsgId;
}

/// @brief Compile time retrieval of the message id provided via
/// @ref comms::option::def::StaticNumIdImpl
/// @details If comms::option::def::StaticNumIdImpl hasn't been used,
/// @b std::numeric_limits<std::intmax_t>::max() is returned.
static constexpr std::intmax_t staticMsgId()
{
return ImplOptions::MsgId;
}

/// @brief Compile type inquiry whether fields have been provided via
/// @ref comms::option::def::FieldsImpl.
static constexpr bool hasFields()
{
return ImplOptions::HasFieldsImpl;
}

/// @brief Compile time inquiry of whether fail on invalid has been requested
/// @ref comms::option::def::FailOnInvalid option.
static constexpr bool hasFailOnInvalid()
{
return ImplOptions::HasFailOnInvalid;
}

/// @brief Compile time inquiry of whether the actual message type has
/// been provided via @ref comms::option::def::MsgType.
static constexpr bool hasMsgType()
{
return ImplOptions::HasMsgType;
}

/// @brief Compile time inquiry of whether polymoriphic read has been
/// requested via interface options and hasn't been inhibited by
/// the @ref comms::option::app::NoReadImpl.
static constexpr bool hasPolymorphicRead()
{
return BaseImpl::hasRead() && (!ImplOptions::HasNoReadImpl);
}

/// @brief Compile time inquiry of whether polymoriphic write has been
/// requested via interface options and hasn't been inhibited by
/// the @ref comms::option::app::NoWriteImpl.
static constexpr bool hasPolymorphicWrite()
{
return BaseImpl::hasWrite() && (!ImplOptions::HasNoWriteImpl);
}

/// @brief Compile time inquiry of whether polymoriphic validity check has been
/// requested via interface options and hasn't been inhibited by
/// the @ref comms::option::app::NoValidImpl.
static constexpr bool hasPolymorphicValid()
{
return BaseImpl::hasValid() && (!ImplOptions::HasNoValidImpl);
}

/// @brief Compile time inquiry of whether polymoriphic length has been
/// requested via interface options and hasn't been inhibited by
/// the @ref comms::option::app::NoLengthImpl.
static constexpr bool hasPolymorphicLength()
{
return BaseImpl::hasLength() && (!ImplOptions::HasNoLengthImpl);
}

/// @brief Compile time inquiry of whether polymoriphic dispatch has been
/// requested via interface options and hasn't been inhibited by
/// the @ref comms::option::app::NoDispatchImpl.
static constexpr bool hasPolymorphicDispatch()
{
return BaseImpl::hasDispatch() && (!ImplOptions::HasNoDispatchImpl);
}

/// @brief Compile time inquiry of whether @ref comms::MessageBase has
/// notified about custom refresh functionality in the derived class
/// via @ref comms::option::def::HasCustomRefresh.
static constexpr bool hasCustomRefresh()
{
return ImplOptions::HasCustomRefresh;
}

/// @brief Compile time inquiry of whether @ref comms::MessageBase has
/// notified about custom name retrieval function in the derived class
/// via @ref comms::option::def::HasName.
static constexpr bool hasCustomName()
{
return ImplOptions::HasName;
}

#ifdef FOR_DOXYGEN_DOC_ONLY

/// @brief All field classes provided with @ref comms::option::def::FieldsImpl option.
Expand Down
40 changes: 27 additions & 13 deletions include/comms/MsgFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <algorithm>

#include "comms/Assert.h"
#include "comms/MsgFactoryCreateFailureReason.h"
#include "comms/util/Tuple.h"
#include "comms/util/alloc.h"
#include "details/MsgFactoryOptionsParser.h"
Expand Down Expand Up @@ -85,7 +86,7 @@ template <typename TMsgBase, typename TAllMessages, typename... TOptions>
class MsgFactory : private details::MsgFactoryBase<TMsgBase, TAllMessages, TOptions...>
{
using Base = details::MsgFactoryBase<TMsgBase, TAllMessages, TOptions...>;
static_assert(TMsgBase::InterfaceOptions::HasMsgIdType,
static_assert(TMsgBase::hasMsgIdType(),
"Usage of MsgFactory requires Message interface to provide ID type. "
"Use comms::option::def::MsgIdType option in message interface type definition.");

Expand All @@ -110,18 +111,12 @@ class MsgFactory : private details::MsgFactoryBase<TMsgBase, TAllMessages, TOpti
/// @brief All messages provided as template parameter to this class.
using AllMessages = typename Base::AllMessages;

#ifdef FOR_DOXYGEN_DOC_ONLY
// @brief Reason for message creation failure
enum class CreateFailureReason
{
None, ///< No reason
InvalidId, ///< Invalid message id
AllocFailure, ///< Allocation of the object has failied
NumOfValues ///< Number of available values, must be last
};
#else // #ifdef FOR_DOXYGEN_DOC_ONLY
using CreateFailureReason = typename Base::CreateFailureReason;
#endif // #ifdef FOR_DOXYGEN_DOC_ONLY
/// @brief Reason for message creation failure
using CreateFailureReason = MsgFactoryCreateFailureReason;

/// @brief type of generic message.
/// @details If supported a variant of @ref comms::GenericMessage, @b void otherwise
using GenericMessage = typename ParsedOptions::GenericMessage;

/// @brief Create message object given the ID of the message.
/// @details The id to mapping is performed using the chosen (or default)
Expand Down Expand Up @@ -167,6 +162,7 @@ class MsgFactory : private details::MsgFactoryBase<TMsgBase, TAllMessages, TOpti
{
return Base::canAllocate();
}

/// @brief Get number of message types from @ref AllMessages, that have the specified ID.
/// @param id ID of the message.
/// @return Number of message classes that report same ID.
Expand Down Expand Up @@ -212,6 +208,24 @@ class MsgFactory : private details::MsgFactoryBase<TMsgBase, TAllMessages, TOpti
return Base::isDispatchLinearSwitch();
}

/// @brief Compile time inquiry whether factory supports in-place allocation
/// @return @b true in case of in-place allocation, @b false in case of dynamic memory use.
static constexpr bool hasInPlaceAllocation()
{
return ParsedOptions::HasInPlaceAllocation;
}

/// @brief Compile time inquiry whether factory supports @ref comms::GenericMessage allocation
static constexpr bool hasGenericMessageSupport()
{
return ParsedOptions::HasSupportGenericMessage;
}

/// @brief Compile time inquiry whether factory has forced dispatch method
static constexpr bool hasForcedDispatch()
{
return ParsedOptions::HasForcedDispatch;
}
};


Expand Down
26 changes: 26 additions & 0 deletions include/comms/MsgFactoryCreateFailureReason.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Copyright 2022 - 2023 (C). Alex Robenko. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/// @file
/// @brief Contains definition of comms::MsgFactoryCreateFailureReason enum.

#pragma once

namespace comms
{

// @brief Reason for message creation failure
enum class MsgFactoryCreateFailureReason
{
None, ///< No reason
InvalidId, ///< Invalid message id
AllocFailure, ///< Allocation of the object has failied
NumOfValues ///< Number of available values, must be last
};

} // namespace comms

1 change: 0 additions & 1 deletion include/comms/details/MessageImplBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ template <typename TMessage, typename... TOptions>
class MessageImplBuilder
{
using ParsedOptions = MessageImplOptionsParser<TOptions...>;
using InterfaceOptions = typename TMessage::InterfaceOptions;

static_assert(ParsedOptions::HasFieldsImpl, "Option comms::option::def::FieldsImpl must be used");

Expand Down
Loading

0 comments on commit 5307f10

Please sign in to comment.