Merge branch 'master' into feature/variadic-variant

# Conflicts:
#	include/etl/mem_cast.h
#	test/test_mem_cast.cpp
#	test/test_mem_cast_ptr.cpp
#	test/vs2019/etl.vcxproj
#	test/vs2019/etl.vcxproj.filters
This commit is contained in:
John Wellbelove 2021-06-14 18:24:59 +01:00
commit afabc049b7
54 changed files with 735 additions and 228 deletions

View File

@ -18,6 +18,8 @@ jobs:
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9"
export CC=clang-9
export CXX=clang++-9
cmake -D BUILD_TESTS=ON ./

View File

@ -99,18 +99,18 @@ public:
//***************************************************************************
// The overridden virtual receive function.
//***************************************************************************
void receive(etl::imessage_router& sender_, const etl::imessage& msg_) override
void receive(const etl::imessage& msg_) override
{
if (accepts(msg_))
{
// Place in queue.
queue.emplace(&sender_, msg_);
queue.emplace(msg_);
std::cout << "Queueing message " << int(msg_.message_id) << std::endl;
std::cout << "Queueing message " << int(msg_.get_message_id()) << std::endl;
}
else
{
std::cout << "Ignoring message " << int(msg_.message_id) << std::endl;
std::cout << "Ignoring message " << int(msg_.get_message_id()) << std::endl;
}
}
@ -121,14 +121,13 @@ public:
{
while (!queue.empty())
{
Item& item = queue.front();
etl::imessage& msg = item.packet.get();
etl::imessage_router& sender = *item.sender;
std::cout << "Processing message " << int(msg.message_id) << std::endl;
message_packet& packet = queue.front();
etl::imessage& msg = packet.get();
std::cout << "Processing message " << int(msg.get_message_id()) << std::endl;
// Call the base class's receive function.
// This will route it to the correct 'on_event' handler.
etl::fsm::receive(sender, msg);
etl::fsm::receive(msg);
queue.pop();
}
@ -136,23 +135,10 @@ public:
private:
//***************************************************************************
// The item to queue.
//***************************************************************************
struct Item
{
Item(etl::imessage_router* sender_, const etl::imessage& msg_)
: sender(sender_),
packet(msg_)
{
}
etl::imessage_router* sender;
etl::message_packet< Message1, Message2, Message3, Message4> packet; // Defines a packet suitable for all possible messages.
};
typedef etl::message_packet< Message1, Message2, Message3, Message4> message_packet;
// The queue of message items.
etl::queue<Item, 10> queue;
etl::queue<message_packet, 10> queue;
};
//*****************************************************************************
@ -178,33 +164,33 @@ public:
}
//***************************************************************************
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message1& msg)
etl::fsm_state_id_t on_event(const Message1& msg)
{
std::cout << " S1 : Received message " << int(msg.message_id) << " : '" << msg.i << "'" << std::endl;
std::cout << " S1 : Received message " << int(msg.get_message_id()) << " : '" << msg.i << "'" << std::endl;
std::cout.flush();
return STATE1;
}
//***************************************************************************
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message2& msg)
etl::fsm_state_id_t on_event(const Message2& msg)
{
std::cout << " S1 : Received message " << int(msg.message_id) << " : '" << msg.d << "'" << std::endl;
std::cout << " S1 : Received message " << int(msg.get_message_id()) << " : '" << msg.d << "'" << std::endl;
std::cout.flush();
return STATE1;
}
//***************************************************************************
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message3& msg)
etl::fsm_state_id_t on_event(const Message3& msg)
{
std::cout << " S1 : Received message " << int(msg.message_id) << " : '" << msg.s << "'" << std::endl;
std::cout << " S1 : Received message " << int(msg.get_message_id()) << " : '" << msg.s << "'" << std::endl;
std::cout.flush();
return STATE1;
}
//***************************************************************************
etl::fsm_state_id_t on_event_unknown(etl::imessage_router& sender, const etl::imessage& msg)
etl::fsm_state_id_t on_event_unknown(const etl::imessage& msg)
{
std::cout << " S1 : Received unknown message " << int(msg.message_id) << std::endl;
std::cout << " S1 : Received unknown message " << int(msg.get_message_id()) << std::endl;
std::cout.flush();
return STATE2;
}
@ -233,30 +219,30 @@ public:
}
//***************************************************************************
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message1& msg)
etl::fsm_state_id_t on_event(const Message1& msg)
{
std::cout << " S2 : Received message " << int(msg.message_id) << " : '" << msg.i << "'" << std::endl;
std::cout << " S2 : Received message " << int(msg.get_message_id()) << " : '" << msg.i << "'" << std::endl;
return STATE2;
}
//***************************************************************************
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message2& msg)
etl::fsm_state_id_t on_event(const Message2& msg)
{
std::cout << " S2 : Received message " << int(msg.message_id) << " : '" << msg.d << "'" << std::endl;
std::cout << " S2 : Received message " << int(msg.get_message_id()) << " : '" << msg.d << "'" << std::endl;
return STATE2;
}
//***************************************************************************
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message3& msg)
etl::fsm_state_id_t on_event(const Message3& msg)
{
std::cout << " S2 : Received message " << int(msg.message_id) << " : '" << msg.s << "'" << std::endl;
std::cout << " S2 : Received message " << int(msg.get_message_id()) << " : '" << msg.s << "'" << std::endl;
return STATE2;
}
//***************************************************************************
etl::fsm_state_id_t on_event_unknown(etl::imessage_router& sender, const etl::imessage& msg)
etl::fsm_state_id_t on_event_unknown(const etl::imessage& msg)
{
std::cout << " S2 : Received unknown message " << int(msg.message_id) << std::endl;
std::cout << " S2 : Received unknown message " << int(msg.get_message_id()) << std::endl;
return STATE1;
}
};

View File

@ -23,32 +23,32 @@
<ProjectGuid>{2BB47D48-5EFC-4C38-B2BE-002172F00E3B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>QueuedFSM</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -62,15 +62,12 @@ public:
//***************************************************************************
// Override the base class's receive function.
void receive(etl::imessage_router& sender_, const etl::imessage& msg_)
void receive(const etl::imessage& msg_)
{
if (accepts(msg_))
{
// Place in queue.
Item item(&sender_, msg_);
queue.emplace(&sender_, msg_);
queue.emplace(msg_);
std::cout << "Queueing message " << int(msg_.get_message_id()) << std::endl;
}
@ -85,58 +82,45 @@ public:
{
while (!queue.empty())
{
Item& item = queue.front();
etl::imessage& msg = item.packet.get();
etl::imessage_router& sender = *item.sender;
message_packet& packet = queue.front();
etl::imessage& msg = packet.get();
std::cout << "Processing message " << int(msg.get_message_id()) << std::endl;
// Call the base class's receive function.
// This will route it to the correct on_receive handler.
Base_t::receive(sender, msg);
Base_t::receive(msg);
queue.pop();
}
}
//***************************************************************************
void on_receive(etl::imessage_router& sender, const Message1& msg)
void on_receive(const Message1& msg)
{
std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.i << "'" << std::endl;
}
//***************************************************************************
void on_receive(etl::imessage_router& sender, const Message2& msg)
void on_receive(const Message2& msg)
{
std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.d << "'" << std::endl;
}
//***************************************************************************
void on_receive(etl::imessage_router& sender, const Message3& msg)
void on_receive(const Message3& msg)
{
std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.s << "'" << std::endl;
}
//***************************************************************************
void on_receive_unknown(etl::imessage_router& sender, const etl::imessage& msg)
void on_receive_unknown(const etl::imessage& msg)
{
std::cout << " Received unknown message " << int(msg.get_message_id()) << std::endl;
}
private:
struct Item
{
Item(etl::imessage_router* sender_, const etl::imessage& msg_)
: sender(sender_),
packet(msg_)
{
}
etl::imessage_router* sender;
message_packet packet;
};
etl::queue<Item, 10> queue;
etl::queue<message_packet, 10> queue;
};
//*****************************************************************************

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_t = etl::crc_type<etl::private_crc::crc16_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_a_t = etl::crc_type<etl::private_crc::crc16_a_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_arc_t = etl::crc_type<etl::private_crc::crc16_arc_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_aug_ccitt_t = etl::crc_type<etl::private_crc::crc16_aug_ccitt_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_buypass_t = etl::crc_type<etl::private_crc::crc16_buypass_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_ccitt_t = etl::crc_type<etl::private_crc::crc16_ccitt_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_cdma2000_t = etl::crc_type<etl::private_crc::crc16_cdma2000_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_dds110_t = etl::crc_type<etl::private_crc::crc16_dds110_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_dect_r_t = etl::crc_type<etl::private_crc::crc16_dect_r_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_dect_x_t = etl::crc_type<etl::private_crc::crc16_dect_x_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_dnp_t = etl::crc_type<etl::private_crc::crc16_dnp_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_en13757_t = etl::crc_type<etl::private_crc::crc16_en13757_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_genibus_t = etl::crc_type<etl::private_crc::crc16_genibus_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_kermit_t = etl::crc_type<etl::private_crc::crc16_kermit_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_maxim_t = etl::crc_type<etl::private_crc::crc16_maxim_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_mcrf4xx_t = etl::crc_type<etl::private_crc::crc16_mcrf4xx_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_modbus_t = etl::crc_type<etl::private_crc::crc16_modbus_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_profibus_t = etl::crc_type<etl::private_crc::crc16_profibus_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_riello_t = etl::crc_type<etl::private_crc::crc16_riello_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_t10dif_t = etl::crc_type<etl::private_crc::crc16_t10dif_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_teledisk_t = etl::crc_type<etl::private_crc::crc16_teledisk_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_tms37157_t = etl::crc_type<etl::private_crc::crc16_tms37157_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_usb_t = etl::crc_type<etl::private_crc::crc16_usb_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc16_x25_t = etl::crc_type<etl::private_crc::crc16_x25_parameters, Table_Size>;
#else

View File

@ -36,7 +36,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_ccitt_t = etl::crc_type<etl::private_crc::crc8_ccitt_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_cdma2000_t = etl::crc_type<etl::private_crc::crc8_cdma2000_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_darc_t = etl::crc_type<etl::private_crc::crc8_darc_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_dvbs2_t = etl::crc_type<etl::private_crc::crc8_dvbs2_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_ebu_t = etl::crc_type<etl::private_crc::crc8_ebu_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_icode_t = etl::crc_type<etl::private_crc::crc8_icode_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_itu_t = etl::crc_type<etl::private_crc::crc8_itu_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_maxim_t = etl::crc_type<etl::private_crc::crc8_maxim_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_rohc_t = etl::crc_type<etl::private_crc::crc8_rohc_parameters, Table_Size>;
#else

View File

@ -39,7 +39,7 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !ETL_CRC_FORCE_CPP03
#if ETL_CPP11_SUPPORTED && !defined(ETL_CRC_FORCE_CPP03)
template <size_t Table_Size>
using crc8_wcdma_t = etl::crc_type<etl::private_crc::crc8_wcdma_parameters, Table_Size>;
#else

View File

@ -132,7 +132,7 @@ namespace etl
//*************************************************************************
/// Gets the next state based on the inputs.
//*************************************************************************
void get_next(bool sample, bool condition_set, bool condition_clear, uint_least8_t state_table[][2])
void get_next(bool sample, bool condition_set, bool condition_clear, const uint_least8_t state_table[][2])
{
int index1 = ((flags & STATE) * 2) + (sample ? 1 : 0);
int index2 = (sample ? (condition_set ? 0 : 1) : (condition_clear ? 0 : 1));
@ -182,7 +182,7 @@ namespace etl
//*************************************************************************
void set_state(bool sample, bool condition_set, bool condition_clear)
{
static uint_least8_t state_table[4][2] =
static ETL_CONSTANT uint_least8_t state_table[4][2] =
{
/* OFF 0 */{ debounce_base::OFF, debounce_base::OFF },
/* OFF 1 */{ debounce_base::ON, debounce_base::OFF },
@ -260,7 +260,7 @@ namespace etl
//*************************************************************************
void set_state(bool sample, bool condition_set, bool condition_clear)
{
static uint_least8_t state_table[6][2] =
static ETL_CONSTANT uint_least8_t state_table[6][2] =
{
/* OFF 0 */{ debounce_base::OFF, debounce_base::OFF },
/* OFF 1 */{ debounce_base::ON, debounce_base::OFF },
@ -347,7 +347,7 @@ namespace etl
//*************************************************************************
void set_state(bool sample, bool condition_set, bool condition_clear)
{
static uint_least8_t state_table[8][2] =
static ETL_CONSTANT uint_least8_t state_table[8][2] =
{
/* OFF 0 */{ debounce_base::OFF, debounce_base::OFF },
/* OFF 1 */{ debounce_base::ON, debounce_base::OFF },

View File

@ -269,26 +269,50 @@ namespace etl
//***************************************************************************
#if defined(ETL_NO_CHECKS)
#define ETL_ASSERT(b, e) // Does nothing.
#define ETL_ASSERT_AND_RETURN(b, e) // Does nothing.
#define ETL_ASSERT_AND_RETURN_VALUE(b, e, v) // Does nothing.
#define ETL_ALWAYS_ASSERT(e) // Does nothing.
#define ETL_ALWAYS_ASSERT_AND_RETURN(e) // Does nothing.
#define ETL_ALWAYS_ASSERT_AND_RETURN_VALUE(e, v) // Does nothing.
#elif defined(ETL_THROW_EXCEPTIONS)
#if defined(ETL_LOG_ERRORS)
#define ETL_ASSERT(b, e) {if (!(b)) {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception.
#define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception.
#define ETL_ASSERT(b, e) {if (!(b)) {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception.
#define ETL_ASSERT_AND_RETURN(b, e) {if (!(b)) {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception.
#define ETL_ASSERT_AND_RETURN_VALUE(b, e, v) {if (!(b)) {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception.
#define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception.
#define ETL_ALWAYS_ASSERT_AND_RETURN(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception.
#define ETL_ALWAYS_ASSERT_AND_RETURN_VALUE(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception.
#else
#define ETL_ASSERT(b, e) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
#define ETL_ASSERT_AND_RETURN(b, e) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
#define ETL_ASSERT_AND_RETURN_VALUE(b, e, v) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
#define ETL_ALWAYS_ASSERT(e) {throw((e));} // Throws an exception.
#define ETL_ALWAYS_ASSERT_AND_RETURN(e) {throw((e));} // Throws an exception.
#define ETL_ALWAYS_ASSERT_AND_RETURN_VALUE(e, v) {throw((e));} // Throws an exception.
#endif
#else
#if defined(ETL_LOG_ERRORS)
#define ETL_ASSERT(b, e) {if(!(b)) {etl::error_handler::error((e));}} // If the condition fails, calls the error handler
#define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e));} // Calls the error handler
#define ETL_ASSERT(b, e) {if(!(b)) {etl::error_handler::error((e));}} // If the condition fails, calls the error handler
#define ETL_ASSERT_AND_RETURN(b, e) {if(!(b)) {etl::error_handler::error((e)); return;}} // If the condition fails, calls the error handler and return
#define ETL_ASSERT_AND_RETURN_VALUE(b, e, v) {if(!(b)) {etl::error_handler::error((e)); return (v);}} // If the condition fails, calls the error handler and return a value
#define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e));} // Calls the error handler
#define ETL_ALWAYS_ASSERT_AND_RETURN(e) {etl::error_handler::error((e)); return;} // Calls the error handler and return
#define ETL_ALWAYS_ASSERT_AND_RETURN_VALUE(e, v) {etl::error_handler::error((e)); return (v);} // Calls the error handler and return a value
#else
#if defined(ETL_DEBUG)
#define ETL_ASSERT(b, e) assert((b)) // If the condition fails, asserts.
#define ETL_ASSERT_AND_RETURN(b, e) assert((b)) // If the condition fails, asserts.
#define ETL_ASSERT_AND_RETURN_VALUE(b, e, v) assert((b)) // If the condition fails, asserts.
#define ETL_ALWAYS_ASSERT(e) assert(false) // Asserts.
#define ETL_ALWAYS_ASSERT_AND_RETURN(e) assert(false) // Asserts.
#define ETL_ALWAYS_ASSERT_AND_RETURN_VALUE(e, v) assert(false) // Asserts.
#else
#define ETL_ASSERT(b, e) // Does nothing.
#define ETL_ASSERT_AND_RETURN(b, e) {if (!(b)) return;} // Returns.
#define ETL_ASSERT_AND_RETURN_VALUE(b, e, v) {if (!(b)) return(v);} // Returns a value.
#define ETL_ALWAYS_ASSERT(e) // Does nothing.
#define ETL_ALWAYS_ASSERT_AND_RETURN(e) {return;} // Returns.
#define ETL_ALWAYS_ASSERT_AND_RETURN_VALUE(e, v) {return(v);} // Returns a value.
#endif
#endif
#endif

View File

@ -43,6 +43,7 @@ SOFTWARE.
#include "exception.h"
#include "error_handler.h"
#include "file_error_numbers.h"
#include "binary.h"
namespace etl
{
@ -60,14 +61,14 @@ namespace etl
};
//***************************************************************************
/// The exception thrown when the buffer pointer alignment is not compatible.
/// The exception thrown when the type size is too large.
//***************************************************************************
class mem_cast_alignment_exception : public etl::mem_cast_exception
class mem_cast_size_exception : public etl::mem_cast_exception
{
public:
mem_cast_alignment_exception(string_type file_name_, numeric_type line_number_)
: mem_cast_exception(ETL_ERROR_TEXT("mem_cast:alignment", ETL_MEM_CAST_FILE_ID"A"), file_name_, line_number_)
mem_cast_size_exception(string_type file_name_, numeric_type line_number_)
: mem_cast_exception(ETL_ERROR_TEXT("mem_cast:size", ETL_MEM_CAST_FILE_ID"A"), file_name_, line_number_)
{
}
};
@ -96,10 +97,12 @@ namespace etl
static ETL_CONSTANT size_t Size = Size_;
static ETL_CONSTANT size_t Alignment = Alignment_;
ETL_STATIC_ASSERT((Alignment == 1) || etl::is_power_of_2<Alignment>::value, "Alignment must be a power of 2");
//***********************************
/// Default constructor
//***********************************
ETL_CONSTEXPR mem_cast()
mem_cast()
: buffer()
{
}
@ -108,14 +111,60 @@ namespace etl
/// Copy constructor
//***********************************
template <size_t Other_Size, size_t Other_Alignment>
ETL_CONSTEXPR mem_cast(const mem_cast<Other_Size, Other_Alignment>& other)
: type_size(other.type_size)
mem_cast(const mem_cast<Other_Size, Other_Alignment>& other)
{
ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large");
ETL_STATIC_ASSERT(Alignment >= Other_Alignment, "Other alignment incompatible");
memcpy(buffer, other.buffer, Size_);
}
//***********************************
/// Assignment operator
//***********************************
template <size_t Other_Size, size_t Other_Alignment>
mem_cast& operator =(const mem_cast<Other_Size, Other_Alignment>& rhs)
{
ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large");
memcpy(buffer, rhs.buffer, Size_);
return *this;
}
//***********************************
/// Assign from value
//***********************************
template <typename T>
void assign(const T& value)
{
ETL_STATIC_ASSERT(Size >= sizeof(T), "Type size is too large");
::new (static_cast<void*>(buffer)) T(value);
}
//***********************************
/// Assign from value at offset
//***********************************
template <typename T>
void assign_at_offset(size_t offset, const T& value)
{
char* p = static_cast<char*>(buffer) + offset;
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
::new (p) T(value);
}
//***********************************
/// Assign from value at offset
//***********************************
template <typename T, size_t Offset>
void assign_at_offset(const T& value)
{
char* p = static_cast<char*>(buffer) + Offset;
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Type size is too large");
::new (p) T(value);
}
#if ETL_CPP11_SUPPORTED
//***********************************
@ -124,18 +173,43 @@ namespace etl
template <typename T, typename... TArgs>
void emplace(TArgs... args)
{
ETL_STATIC_ASSERT(Size >= sizeof(T), "Type size is too large");
::new (static_cast<void*>(buffer)) T(etl::forward<TArgs>(args)...);
}
//***********************************
/// Emplace from parameters at offset
//***********************************
template <typename T, typename... TArgs>
void emplace_at_offset(size_t offset, TArgs... args)
{
char* p = static_cast<char*>(buffer) + offset;
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
::new (p) T(etl::forward<TArgs>(args)...);
}
//***********************************
/// Emplace from parameters at offset
//***********************************
template <typename T, size_t Offset, typename... TArgs>
void emplace_at_offset(TArgs... args)
{
char* p = static_cast<char*>(buffer) + Offset;
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Type size is too large");
::new (p) T(etl::forward<TArgs>(args)...);
}
#endif
//***********************************
/// Get a reference to T
//***********************************
template <typename T>
ETL_CONSTEXPR T& ref()
ETL_NODISCARD T& ref()
{
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large");
ETL_STATIC_ASSERT(Alignment >= etl::alignment_of<T>::value, "Alignment of T is incompatible");
return *static_cast<T*>(buffer);
}
@ -144,32 +218,69 @@ namespace etl
/// Get a const reference to T
//***********************************
template <typename T>
ETL_CONSTEXPR const T& ref() const
ETL_NODISCARD const T& ref() const
{
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large");
ETL_STATIC_ASSERT(Alignment >= etl::alignment_of<T>::value, "Alignment of T is incompatible");
return *static_cast<const T*>(buffer);
}
//***********************************
/// Assignment operator
/// Get a reference to T at offset (dynamic)
//***********************************
template <size_t Other_Size, size_t Other_Alignment>
ETL_CONSTEXPR mem_cast& operator =(const mem_cast<Other_Size, Other_Alignment>& rhs)
template <typename T>
ETL_NODISCARD T& ref_at_offset(size_t offset)
{
ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large");
ETL_STATIC_ASSERT(Alignment >= Other_Alignment, "RHS alignment incompatible");
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
memcpy(buffer, rhs.buffer, Size_);
char* p = buffer + offset;
return *this;
return *static_cast<T*>(p);
}
//***********************************
/// Get a const reference to T at offset (dynamic)
//***********************************
template <typename T>
ETL_NODISCARD const T& ref_at_offset(size_t offset) const
{
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
char* p = buffer + offset;
return *static_cast<const T*>(p);
}
//***********************************
/// Get a reference to T at offset (static)
//***********************************
template <typename T, size_t Offset>
ETL_NODISCARD T& ref_at_offset()
{
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Size of T is too large");
char* p = buffer + Offset;
return *static_cast<T*>(p);
}
//***********************************
/// Get a const reference to T at offset (static)
//***********************************
template <typename T, size_t Offset>
ETL_NODISCARD const T& ref_at_offset() const
{
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Size of T is too large");
char* p = buffer + Offset;
return *static_cast<const T*>(p);
}
//***********************************
/// Get the size of the buffer
//***********************************
ETL_CONSTEXPR size_t size() const
ETL_NODISCARD static ETL_CONSTEXPR size_t size()
{
return Size;
}
@ -177,7 +288,7 @@ namespace etl
//***********************************
/// Get the alignment of the buffer
//***********************************
ETL_CONSTEXPR size_t alignment() const
ETL_NODISCARD static ETL_CONSTEXPR size_t alignment()
{
return Alignment;
}
@ -185,7 +296,7 @@ namespace etl
//***********************************
/// Get a pointer to the internal buffer
//***********************************
ETL_CONSTEXPR char* data()
ETL_NODISCARD char* data()
{
return buffer;
}
@ -193,7 +304,7 @@ namespace etl
//***********************************
/// Get a const pointer to the internal buffer
//***********************************
ETL_CONSTEXPR const char* data() const
ETL_NODISCARD const char* data() const
{
return buffer;
}
@ -207,40 +318,86 @@ namespace etl
//*****************************************************************************
/// mem_cast_ptr
//*****************************************************************************
template <size_t Size_>
class mem_cast_ptr
{
public:
static ETL_CONSTANT size_t Size = Size_;
static ETL_CONSTANT size_t Undefined_Size = etl::integral_limits<size_t>::max;
//***********************************
/// Default constructor
//***********************************
ETL_CONSTEXPR mem_cast_ptr()
mem_cast_ptr()
: pbuffer(ETL_NULLPTR)
, buffer_size(Undefined_Size)
{
}
//***********************************
/// Construct with pointer to buffer
/// Construct with pointer to buffer and optional size
//***********************************
ETL_CONSTEXPR mem_cast_ptr(char* pbuffer_)
mem_cast_ptr(char* pbuffer_, size_t buffer_size_ = Undefined_Size)
: pbuffer(pbuffer_)
, buffer_size(buffer_size_)
{
}
//***********************************
/// Copy construct with pointer to buffer
/// Copy construct
//***********************************
template <size_t Other_Size>
ETL_CONSTEXPR mem_cast_ptr(const mem_cast_ptr<Other_Size>& other, char* pbuffer_)
: pbuffer(pbuffer_)
mem_cast_ptr(const mem_cast_ptr& other)
: pbuffer(other.pbuffer)
, buffer_size(other.buffer_size)
{
}
//***********************************
/// Assignment operator
//***********************************
mem_cast_ptr& operator =(const mem_cast_ptr& rhs)
{
pbuffer = rhs.pbuffer;
buffer_size = rhs.buffer_size;
return *this;
}
//***********************************
/// Assign from value
//***********************************
template <typename T>
void assign(const T& value)
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large");
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::mem_cast_size_exception));
memcpy(pbuffer, other.pbuffer, Size_);
::new (pbuffer) T(value);
}
//***********************************
/// Assign from value at offset
//***********************************
template <typename T>
void assign_at_offset(size_t offset, const T& value)
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
char* p = pbuffer + offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - offset), ETL_ERROR(etl::mem_cast_size_exception));
::new (p) T(value);
}
//***********************************
/// Assign from value at offset
//***********************************
template <typename T, size_t Offset>
void assign_at_offset(const T& value)
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
char* p = pbuffer + Offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - Offset), ETL_ERROR(etl::mem_cast_size_exception));
::new (p) T(value);
}
#if ETL_CPP11_SUPPORTED
@ -251,20 +408,46 @@ namespace etl
void emplace(TArgs... args)
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
ETL_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, ETL_ERROR(etl::mem_cast_alignment_exception));
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::mem_cast_size_exception));
::new (pbuffer) T(etl::forward<TArgs>(args)...);
}
//***********************************
/// Emplace from parameters at offset
//***********************************
template <typename T, typename... TArgs>
void emplace_at_offset(size_t offset, TArgs... args)
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
char* p = pbuffer + offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - offset), ETL_ERROR(etl::mem_cast_size_exception));
::new (p) T(etl::forward<TArgs>(args)...);
}
//***********************************
/// Emplace from parameters at offset
//***********************************
template <typename T, size_t Offset, typename... TArgs>
void emplace_at_offset(TArgs... args)
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
char* p = pbuffer + Offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - Offset), ETL_ERROR(etl::mem_cast_size_exception));
::new (p) T(etl::forward<TArgs>(args)...);
}
#endif
//***********************************
/// Get a reference to T
//***********************************
template <typename T>
ETL_CONSTEXPR T& ref()
ETL_NODISCARD T& ref()
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
ETL_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, ETL_ERROR(etl::mem_cast_alignment_exception));
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::mem_cast_size_exception));
return *reinterpret_cast<T*>(pbuffer);
}
@ -273,46 +456,107 @@ namespace etl
/// Get a const reference to T
//***********************************
template <typename T>
ETL_CONSTEXPR const T& ref() const
ETL_NODISCARD const T& ref() const
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
ETL_ASSERT((uintptr_t(pbuffer) % etl::alignment_of<T>::value) == 0, ETL_ERROR(etl::mem_cast_alignment_exception));
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::mem_cast_size_exception));
return *reinterpret_cast<const T*>(pbuffer);
}
//***********************************
template <size_t Other_Size>
mem_cast_ptr& operator =(const mem_cast_ptr<Other_Size>& rhs)
/// Get a reference to T at offset (dynamic)
//***********************************
template <typename T>
ETL_NODISCARD T& ref_at_offset(size_t offset)
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large");
char* p = pbuffer + offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - offset), ETL_ERROR(etl::mem_cast_size_exception));
memcpy(pbuffer, rhs.pbuffer, Size_);
return *this;
return *reinterpret_cast<T*>(p);
}
//***********************************
/// Assignment operator
/// Get a const reference to T at offset (dynamic)
//***********************************
ETL_CONSTEXPR size_t size() const
template <typename T>
ETL_NODISCARD const T& ref_at_offset(size_t offset) const
{
return Size;
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
char* p = pbuffer + offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - offset), ETL_ERROR(etl::mem_cast_size_exception));
return *reinterpret_cast<const T*>(p);
}
//***********************************
/// Get a pointer to the internal buffer
/// Get a reference to T at offset (static)
//***********************************
void data(char* pbuffer_)
template <typename T, size_t Offset>
ETL_NODISCARD T& ref_at_offset()
{
pbuffer = pbuffer_;
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
char* p = pbuffer + Offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - Offset), ETL_ERROR(etl::mem_cast_size_exception));
return *reinterpret_cast<T*>(p);
}
//***********************************
/// Get a const pointer to the internal buffer
/// Get a const reference to T at offset (static)
//***********************************
ETL_CONSTEXPR char* data() const
template <typename T, size_t Offset>
ETL_NODISCARD const T& ref_at_offset() const
{
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
char* p = pbuffer + Offset;
ETL_ASSERT(sizeof(T) <= (buffer_size - Offset), ETL_ERROR(etl::mem_cast_size_exception));
return *reinterpret_cast<const T*>(p);
}
//***********************************
/// Get the size of the buffer
//***********************************
ETL_NODISCARD size_t size() const
{
return buffer_size;
}
//***********************************
/// Get the alignment of the buffer
//***********************************
ETL_NODISCARD size_t alignment() const
{
typedef typename etl::smallest_uint_for_bits<sizeof(uintptr_t)* CHAR_BIT>::type type;
const type p = reinterpret_cast<type>(pbuffer);
return 1U << etl::count_trailing_zeros(p);
}
//***********************************
/// Set the pointer to the external buffer
//***********************************
void data(char* pbuffer_, size_t buffer_size_ = Undefined_Size)
{
pbuffer = pbuffer_;
buffer_size = buffer_size_;
}
//***********************************
/// Get a pointer to the external buffer
//***********************************
ETL_NODISCARD char* data()
{
return pbuffer;
}
//***********************************
/// Get const a pointer to the external buffer
//***********************************
ETL_NODISCARD const char* data() const
{
return pbuffer;
}
@ -320,16 +564,26 @@ namespace etl
private:
/// Pointer to the buffer
char* pbuffer;
char* pbuffer;
size_t buffer_size;
};
#if ETL_CPP11_SUPPORTED
//*****************************************************************************
/// mem_cast_var
/// mem_cast from a variadic list of types
//*****************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_MEM_CAST_FORCE_CPP03)
template <typename... TTypes>
using mem_cast_types = etl::mem_cast<etl::largest<TTypes...>::size, etl::largest<TTypes...>::alignment>;
#else
template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char,
typename T5 = char, typename T6 = char, typename T7 = char, typename T8 = char,
typename T9 = char, typename T10 = char, typename T11 = char, typename T12 = char,
typename T13 = char, typename T14 = char, typename T15 = char, typename T16 = char>
struct mem_cast_types : public etl::mem_cast<etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment>
{
};
#endif
}

View File

@ -38,8 +38,8 @@ SOFTWARE.
///\ingroup utilities
#define ETL_VERSION_MAJOR 20
#define ETL_VERSION_MINOR 10
#define ETL_VERSION_PATCH 5
#define ETL_VERSION_MINOR 11
#define ETL_VERSION_PATCH 1
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) "." ETL_STRINGIFY(ETL_VERSION_MINOR) "." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_STRINGIFY(ETL_VERSION_MAJOR) L"." ETL_STRINGIFY(ETL_VERSION_MINOR) L"." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_U16 ETL_STRINGIFY(ETL_VERSION_MAJOR) u"." ETL_STRINGIFY(ETL_VERSION_MINOR) u"." ETL_STRINGIFY(ETL_VERSION_PATCH)

View File

@ -1,6 +1,6 @@
{
"name": "ETL Embedded Template Library",
"version": "20.10.5",
"version": "20.11.1",
"author s": {
"name": "John Wellbelove",
"email": "john.wellbelove@etlcpp.com"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library ETL
version=20.10.5
version=20.11.1
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

View File

@ -8,7 +8,7 @@ project('PROJECT_NAME',
'cpp_std=c++17', 'build.cpp_std=c++17',
],
meson_version: '>=0.54.0',
version: '20.10.5'
version: '20.11.1'
)
######################

View File

@ -1,3 +1,16 @@
===============================================================================
20.11.1
Fixed ambiguous function call in etl::mem_cast for clang.
===============================================================================
20.11.0
Added etl::mem_cast, etl::mem_cast_ptr & etl::mem_cast_types for reinterpretion of memory blocks.
State tables in etl::debounce are now constexpr in C++11 or above.
===============================================================================
20.10.6
Updated QueuedMessageRouter and QueuedFSM examples to use current message frameworks.
===============================================================================
20.10.5
Added container_type to etl::stack, etl::queue and etl::priority_queue.

View File

@ -145,6 +145,8 @@ set(TEST_SOURCE_FILES
test_map.cpp
test_maths.cpp
test_mean.cpp
test_mem_cast.cpp
test_mem_cast_ptr.cpp
test_memory.cpp
test_message_bus.cpp
test_message_packet.cpp

View File

@ -80,20 +80,23 @@ SOFTWARE.
//#define ETL_NO_STL
//#define ETL_FUNCTION_FORCE_CPP03
//#define ETL_PRIORITY_QUEUE_FORCE_CPP03
//#define ETL_QUEUE_ATOMIC_FORCE_CPP03
//#define ETL_VARIANT_FORCE_CPP03
//#define ETL_VECTOR_FORCE_CPP03
//#define ETL_QUEUE_FORCE_CPP03
//#define ETL_QUEUE_MPMC_MUTEX_FORCE_CPP03
//#define ETL_QUEUE_ISR_FORCE_CPP03
//#define ETL_QUEUE_LOCKED_FORCE_CPP03
//#define ETL_OPTIONAL_FORCE_CPP03
//#define ETL_LARGEST_TYPE_FORCE_CPP03
//#define ETL_TYPE_SELECT_FORCE_CPP03
//#define ETL_UNINITIALIZED_BUFFER_FORCE_CPP03
//#define ETL_CRC_FORCE_CPP03
#if defined(ETL_FORCE_TEST_CPP03)
#define ETL_FUNCTION_FORCE_CPP03
#define ETL_PRIORITY_QUEUE_FORCE_CPP03
#define ETL_QUEUE_ATOMIC_FORCE_CPP03
#define ETL_VARIANT_FORCE_CPP03
#define ETL_VECTOR_FORCE_CPP03
#define ETL_QUEUE_FORCE_CPP03
#define ETL_QUEUE_MPMC_MUTEX_FORCE_CPP03
#define ETL_QUEUE_ISR_FORCE_CPP03
#define ETL_QUEUE_LOCKED_FORCE_CPP03
#define ETL_OPTIONAL_FORCE_CPP03
#define ETL_LARGEST_TYPE_FORCE_CPP03
#define ETL_TYPE_SELECT_FORCE_CPP03
#define ETL_UNINITIALIZED_BUFFER_FORCE_CPP03
#define ETL_CRC_FORCE_CPP03
#define ETL_MEM_CAST_FORCE_CPP03
#endif
#if defined(ETL_NO_STL)
#define ETL_TIMER_SEMAPHORE_TYPE uint32_t

View File

@ -38,6 +38,7 @@ SOFTWARE.
namespace
{
#pragma pack(push,1)
struct Data
{
Data()
@ -58,6 +59,7 @@ namespace
double d;
std::array<int, 3> a;
};
#pragma pack(pop)
constexpr size_t Size = etl::largest<char, double, Data>::size;
constexpr size_t Alignment = etl::largest<char, double, Data>::alignment;
@ -134,6 +136,52 @@ namespace
CHECK(alignof(Data) <= memCastTypes.alignment());
}
//*************************************************************************
TEST(test_mem_cast_assign_type)
{
MemCast memCast;
memCast.assign<char>(123);
CHECK_EQUAL(123, memCast.ref<char>());
memCast.assign<double>(1.23);
CHECK_EQUAL(1.23, memCast.ref<double>());
Data data(123, 1.23, std::array<int, 3>{ 1, 2, 3 });
memCast.assign<Data>(data);
CHECK(123 == memCast.ref<Data>().c);
CHECK(1.23 == memCast.ref<Data>().d);
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_assign_type_at_dynamic_offset)
{
MemCast memCast;
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
size_t offset = offsetof(Data, a);
memCast.assign_at_offset<Array>(offset, a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_assign_type_at_static_offset)
{
MemCast memCast;
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
constexpr size_t Offset = offsetof(Data, a);
memCast.assign_at_offset<Array, Offset>(a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_emplace_type)
{
@ -151,6 +199,34 @@ namespace
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_emplace_type_at_dynamic_offset)
{
MemCast memCast;
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
size_t offset = offsetof(Data, a);
memCast.emplace_at_offset<Array>(offset, a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_emplace_type_at_static_offset)
{
MemCast memCast;
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
constexpr size_t Offset = offsetof(Data, a);
memCast.emplace_at_offset<Array, Offset>(a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_to_type)
{

View File

@ -63,32 +63,175 @@ namespace
constexpr size_t Alignment = etl::largest<char, double, Data>::alignment;
// Test variant types.
using MemCast = etl::mem_cast_ptr<Size>;
using MemCast = etl::mem_cast_ptr;
char c;
double d;
Data data;
char* Ptr(int i)
{
return reinterpret_cast<char*>(i);
}
std::aligned_storage_t<Size, Alignment> buffer;
SUITE(test_mem_cast)
SUITE(test_mem_cast_ptr)
{
//*************************************************************************
TEST(test_size)
TEST(test_alignment)
{
MemCast memCast;
CHECK(sizeof(char) <= MemCast::Size);
CHECK(sizeof(short) <= MemCast::Size);
CHECK(sizeof(Data) <= MemCast::Size);
char* p = nullptr;
CHECK(sizeof(char) <= memCast.Size);
CHECK(sizeof(short) <= memCast.Size);
CHECK(sizeof(Data) <= memCast.Size);
memCast.data(Ptr(1));
CHECK_EQUAL(1U , memCast.alignment());
CHECK(sizeof(char) <= memCast.size());
CHECK(sizeof(short) <= memCast.size());
CHECK(sizeof(Data) <= memCast.size());
memCast.data(Ptr(2));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(3));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(4));
CHECK_EQUAL(4U , memCast.alignment());
memCast.data(Ptr(5));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(6));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(7));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(8));
CHECK_EQUAL(8U , memCast.alignment());
memCast.data(Ptr(9));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(10));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(11));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(12));
CHECK_EQUAL(4U , memCast.alignment());
memCast.data(Ptr(13));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(14));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(15));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(16));
CHECK_EQUAL(16U , memCast.alignment());
memCast.data(Ptr(17));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(18));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(19));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(20));
CHECK_EQUAL(4U , memCast.alignment());
memCast.data(Ptr(21));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(22));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(23));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(24));
CHECK_EQUAL(8U , memCast.alignment());
memCast.data(Ptr(25));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(26));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(27));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(28));
CHECK_EQUAL(4U , memCast.alignment());
memCast.data(Ptr(29));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(30));
CHECK_EQUAL(2U , memCast.alignment());
memCast.data(Ptr(31));
CHECK_EQUAL(1U , memCast.alignment());
memCast.data(Ptr(32));
CHECK_EQUAL(32U , memCast.alignment());
}
//*************************************************************************
TEST(test_mem_cast_assign_type)
{
char* pbuffer = reinterpret_cast<char*>(&buffer);
MemCast memCast(pbuffer);
memCast.assign<char>(123);
CHECK_EQUAL(123, memCast.ref<char>());
memCast.assign<double>(1.23);
CHECK_EQUAL(1.23, memCast.ref<double>());
Data data(123, 1.23, std::array<int, 3>{ 1, 2, 3 });
memCast.assign<Data>(data);
CHECK(123 == memCast.ref<Data>().c);
CHECK(1.23 == memCast.ref<Data>().d);
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_assign_type_at_dynamic_offset)
{
char* pbuffer = reinterpret_cast<char*>(&buffer);
MemCast memCast(pbuffer);
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
size_t offset = offsetof(Data, a);
memCast.assign_at_offset<Array>(offset, a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_assign_type_at_static_offset)
{
char* pbuffer = reinterpret_cast<char*>(&buffer);
MemCast memCast(pbuffer);
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
constexpr size_t Offset = offsetof(Data, a);
memCast.assign_at_offset<Array, Offset>(a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
@ -110,6 +253,38 @@ namespace
CHECK((std::array { 1, 2, 3 }) == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_emplace_type_at_dynamic_offset)
{
char* pbuffer = reinterpret_cast<char*>(&buffer);
MemCast memCast(pbuffer);
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
size_t offset = offsetof(Data, a);
memCast.emplace_at_offset<Array>(offset, a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_emplace_type_at_static_offset)
{
char* pbuffer = reinterpret_cast<char*>(&buffer);
MemCast memCast(pbuffer);
using Array = std::array<int, 3>;
Array a{ 1, 2, 3 };
constexpr size_t Offset = offsetof(Data, a);
memCast.emplace_at_offset<Array, Offset>(a);
CHECK(a == memCast.ref<Data>().a);
}
//*************************************************************************
TEST(test_mem_cast_to_type)
{
@ -137,7 +312,6 @@ namespace
const MemCast memCast(pbuffer);
pbuffer = memCast.data();
*pbuffer = 123;
CHECK_EQUAL(123, memCast.ref<char>());
@ -155,7 +329,7 @@ namespace
{
MemCast memCast;
CHECK_THROW(memCast.ref<char>(), etl::mem_cast_nullptr_exception);
CHECK_THROW(char c = memCast.ref<char>(), etl::mem_cast_nullptr_exception);
}
//*************************************************************************
@ -163,27 +337,7 @@ namespace
{
const MemCast memCast;
CHECK_THROW(memCast.ref<char>(), etl::mem_cast_nullptr_exception);
}
//*************************************************************************
TEST(test_mem_cast_to_type_misaligned_buffer)
{
double d;
char* pbuffer = reinterpret_cast<char*>(&d);
MemCast memCast(pbuffer + 1);
CHECK_THROW(memCast.ref<double>(), etl::mem_cast_alignment_exception);
}
//*************************************************************************
TEST(test_const_mem_cast_to_type_misaligned_buffer)
{
double d;
char* pbuffer = reinterpret_cast<char*>(&d);
const MemCast memCast(pbuffer + 1);
CHECK_THROW(memCast.ref<double>(), etl::mem_cast_alignment_exception);
CHECK_THROW(char c = memCast.ref<char>(), etl::mem_cast_nullptr_exception);
}
};
}

View File

@ -1340,6 +1340,7 @@
<ClInclude Include="..\..\include\etl\macros.h" />
<ClInclude Include="..\..\include\etl\fixed_sized_memory_block_allocator.h" />
<ClInclude Include="..\..\include\etl\mean.h" />
<ClInclude Include="..\..\include\etl\mem_cast.h" />
<ClInclude Include="..\..\include\etl\message_packet.h" />
<ClInclude Include="..\..\include\etl\message_pool.h" />
<ClInclude Include="..\..\include\etl\multi_array.h" />
@ -3232,12 +3233,20 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\mem_cast.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Clang|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugLLVMNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC No Checks|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug No Unit Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugLLVMNoSTL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugMSVCSmallStrings|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugNoSTLForceNoAdvanced|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugStringTruncationIsError|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='LLVM New|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugAppveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVCDebugNoSTLAppveyor|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\message.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@ -5024,4 +5033,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -1110,7 +1110,7 @@
<ClInclude Include="..\..\include\etl\private\variant_new.h">
<Filter>ETL\Private</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\mem_cast.h">
<ClInclude Include="..\..\include\etl\mem_cast.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
</ItemGroup>
@ -2681,4 +2681,4 @@
<Filter>Resource Files</Filter>
</Natvis>
</ItemGroup>
</Project>
</Project>