Refactor C++17 message_packet

This commit is contained in:
John Wellbelove 2022-05-25 11:52:47 +01:00
parent e864fe62d5
commit 047fc3eb90
3 changed files with 81 additions and 152 deletions

View File

@ -90,63 +90,46 @@ namespace etl
{
}
//********************************************
explicit message_packet(const etl::imessage& msg)
: data()
{
if (accepts(msg))
{
add_new_message(msg);
valid = true;
}
else
{
valid = false;
}
ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
}
//********************************************
explicit message_packet(etl::imessage&& msg)
: data()
{
if (accepts(msg))
{
add_new_message(etl::move(msg));
valid = true;
}
else
{
valid = false;
}
ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
}
//********************************************
template <typename TMessage, typename = etl::enable_if_t<!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::message_packet<TMessageTypes...>> &&
!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::imessage> &&
!etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, int>>
!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::imessage> &&
!etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, int>>
explicit message_packet(TMessage&& msg)
: data()
, valid(true)
{
// Not etl::message_packet, not etl::imessage and in typelist.
constexpr bool Enabled = (!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::message_packet<TMessageTypes...>> &&
!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::imessage> &&
etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>);
!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::imessage> &&
etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>);
ETL_STATIC_ASSERT(Enabled, "Message not in packet type list");
}
//********************************************
template <typename TMessage, etl::enable_if_t<etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, int>>
explicit message_packet(TMessage&& msg)
template <typename TMessage>
explicit message_packet(TMessage&& msg, etl::enable_if_t<!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::message_packet<TMessageTypes...>>, int*> p = nullptr)
: data()
, valid(true)
{
add_new_message<TMessage>(etl::forward<TMessage>(msg));
if constexpr (etl::is_same_v<etl::remove_reference_t<TMessage>, etl::imessage>)
{
if (accepts(msg))
{
add_new_message(etl::forward<TMessage>(msg));
valid = true;
}
else
{
valid = false;
}
ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
}
else
{
add_new_message_type<TMessage>(etl::forward<TMessage>(msg));
}
}
//**********************************************
@ -295,17 +278,19 @@ namespace etl
}
//********************************************
template <typename TMessage, etl::enable_if_t<etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, int>>
void add_new_message(TMessage&& msg)
/// Only enabled for types that are in the typelist.
//********************************************
template <typename TMessage>
etl::enable_if_t<etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, void>
add_new_message_type(TMessage&& msg)
{
(add_new_message_type<TMessageTypes, etl::remove_reference_t<TMessage>::ID>(etl::forward<TMessage>(msg)) || ...);
void* p = data;
new (p) etl::remove_reference_t<TMessage>((etl::forward<TMessage>(msg)));
}
typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;
bool valid;
private:
//********************************************
template <typename TType>
bool add_new_message_type(const etl::imessage& msg)
@ -322,22 +307,6 @@ namespace etl
}
}
//********************************************
template <typename TType, etl::message_id_t Id>
bool add_new_message_type(const etl::imessage& msg)
{
if (TType::ID == Id)
{
void* p = data;
new (p) TType(static_cast<const TType&>(msg));
return true;
}
else
{
return false;
}
}
//********************************************
template <typename TType>
bool add_new_message_type(etl::imessage&& msg)
@ -353,22 +322,6 @@ namespace etl
return false;
}
}
//********************************************
template <typename TType, etl::message_id_t Id>
bool add_new_message_type(etl::imessage&& msg)
{
if (TType::ID == Id)
{
void* p = data;
new (p) TType(static_cast<TType&&>(msg));
return true;
}
else
{
return false;
}
}
};
#else

View File

@ -78,40 +78,6 @@ namespace etl
{
}
//********************************************
explicit message_packet(const etl::imessage& msg)
: data()
{
if (accepts(msg))
{
add_new_message(msg);
valid = true;
}
else
{
valid = false;
}
ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
}
//********************************************
explicit message_packet(etl::imessage&& msg)
: data()
{
if (accepts(msg))
{
add_new_message(etl::move(msg));
valid = true;
}
else
{
valid = false;
}
ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
}
//********************************************
template <typename TMessage, typename = etl::enable_if_t<!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::message_packet<TMessageTypes...>> &&
!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::imessage> &&
@ -129,12 +95,29 @@ namespace etl
}
//********************************************
template <typename TMessage, etl::enable_if_t<etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, int>>
explicit message_packet(TMessage&& msg)
template <typename TMessage>
explicit message_packet(TMessage&& msg, etl::enable_if_t<!etl::is_same_v<etl::remove_reference_t<TMessage>, etl::message_packet<TMessageTypes...>>, int*> p = nullptr)
: data()
, valid(true)
{
add_new_message<TMessage>(etl::forward<TMessage>(msg));
if constexpr(etl::is_same_v<etl::remove_reference_t<TMessage>, etl::imessage>)
{
if (accepts(msg))
{
add_new_message(etl::forward<TMessage>(msg));
valid = true;
}
else
{
valid = false;
}
ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
}
else
{
add_new_message_type<TMessage>(etl::forward<TMessage>(msg));
}
}
//**********************************************
@ -283,17 +266,19 @@ namespace etl
}
//********************************************
template <typename TMessage, etl::enable_if_t<etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, int>>
void add_new_message(TMessage&& msg)
/// Only enabled for types that are in the typelist.
//********************************************
template <typename TMessage>
etl::enable_if_t<etl::is_one_of_v<etl::remove_reference_t<TMessage>, TMessageTypes...>, void>
add_new_message_type(TMessage&& msg)
{
(add_new_message_type<TMessageTypes, etl::remove_reference_t<TMessage>::ID>(etl::forward<TMessage>(msg)) || ...);
void* p = data;
new (p) etl::remove_reference_t<TMessage>((etl::forward<TMessage>(msg)));
}
typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;
bool valid;
private:
//********************************************
template <typename TType>
bool add_new_message_type(const etl::imessage& msg)
@ -310,22 +295,6 @@ namespace etl
}
}
//********************************************
template <typename TType, etl::message_id_t Id>
bool add_new_message_type(const etl::imessage& msg)
{
if (TType::ID == Id)
{
void* p = data;
new (p) TType(static_cast<const TType&>(msg));
return true;
}
else
{
return false;
}
}
//********************************************
template <typename TType>
bool add_new_message_type(etl::imessage&& msg)
@ -341,22 +310,6 @@ namespace etl
return false;
}
}
//********************************************
template <typename TType, etl::message_id_t Id>
bool add_new_message_type(etl::imessage&& msg)
{
if (TType::ID == Id)
{
void* p = data;
new (p) TType(static_cast<TType&&>(msg));
return true;
}
else
{
return false;
}
}
};
#else

View File

@ -285,6 +285,29 @@ namespace
CHECK_EQUAL("3", static_cast<Message3&>(packet3.get()).x);
}
//*************************************************************************
TEST(message_packet_move_construction_from_base)
{
Message1 message1(1);
Message2 message2(2.2);
Message3 message3("3");
Message4 message4;
Packet packet1(static_cast<etl::imessage&&>(message1));
Packet packet2(static_cast<etl::imessage&&>(message2));
Packet packet3(static_cast<etl::imessage&&>(message3));
CHECK_THROW(Packet packet4(static_cast<etl::imessage&>(message4)), etl::unhandled_message_exception);
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
CHECK_EQUAL(MESSAGE2, packet2.get().get_message_id());
CHECK_EQUAL(MESSAGE3, packet3.get().get_message_id());
CHECK_EQUAL(1, static_cast<Message1&>(packet1.get()).x);
CHECK_EQUAL(2.2, static_cast<Message2&>(packet2.get()).x);
CHECK_EQUAL("3", static_cast<Message3&>(packet3.get()).x);
}
//*************************************************************************
TEST(message_packet_copy_constructor)
{