diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 35b012c1..ea07e377 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -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 ./ diff --git a/examples/QueuedFSM/QueuedFSM.cpp b/examples/QueuedFSM/QueuedFSM.cpp index 9d99142e..a0cbd029 100644 --- a/examples/QueuedFSM/QueuedFSM.cpp +++ b/examples/QueuedFSM/QueuedFSM.cpp @@ -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 queue; + etl::queue 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; } }; diff --git a/examples/QueuedFSM/vs2017/QueuedFSM.sln b/examples/QueuedFSM/vs2019/QueuedFSM.sln similarity index 100% rename from examples/QueuedFSM/vs2017/QueuedFSM.sln rename to examples/QueuedFSM/vs2019/QueuedFSM.sln diff --git a/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj b/examples/QueuedFSM/vs2019/QueuedFSM.vcxproj similarity index 96% rename from examples/QueuedFSM/vs2017/QueuedFSM.vcxproj rename to examples/QueuedFSM/vs2019/QueuedFSM.vcxproj index 6e9c8762..5e461eab 100644 --- a/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj +++ b/examples/QueuedFSM/vs2019/QueuedFSM.vcxproj @@ -23,32 +23,32 @@ {2BB47D48-5EFC-4C38-B2BE-002172F00E3B} Win32Proj QueuedFSM - 10.0.18362.0 + 10.0 Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode diff --git a/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj.filters b/examples/QueuedFSM/vs2019/QueuedFSM.vcxproj.filters similarity index 100% rename from examples/QueuedFSM/vs2017/QueuedFSM.vcxproj.filters rename to examples/QueuedFSM/vs2019/QueuedFSM.vcxproj.filters diff --git a/examples/QueuedMessageRouter/QueuedMessageRouter.cpp b/examples/QueuedMessageRouter/QueuedMessageRouter.cpp index a392db95..d4f78f77 100644 --- a/examples/QueuedMessageRouter/QueuedMessageRouter.cpp +++ b/examples/QueuedMessageRouter/QueuedMessageRouter.cpp @@ -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 queue; + etl::queue queue; }; //***************************************************************************** diff --git a/include/etl/crc16.h b/include/etl/crc16.h index f9c8cb2e..bbb5b5b4 100644 --- a/include/etl/crc16.h +++ b/include/etl/crc16.h @@ -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 using crc16_t = etl::crc_type; #else diff --git a/include/etl/crc16_a.h b/include/etl/crc16_a.h index 2430c9f4..be98d3ef 100644 --- a/include/etl/crc16_a.h +++ b/include/etl/crc16_a.h @@ -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 using crc16_a_t = etl::crc_type; #else diff --git a/include/etl/crc16_arc.h b/include/etl/crc16_arc.h index b60b667c..80799617 100644 --- a/include/etl/crc16_arc.h +++ b/include/etl/crc16_arc.h @@ -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 using crc16_arc_t = etl::crc_type; #else diff --git a/include/etl/crc16_aug_ccitt.h b/include/etl/crc16_aug_ccitt.h index 4cd66e10..807d432f 100644 --- a/include/etl/crc16_aug_ccitt.h +++ b/include/etl/crc16_aug_ccitt.h @@ -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 using crc16_aug_ccitt_t = etl::crc_type; #else diff --git a/include/etl/crc16_buypass.h b/include/etl/crc16_buypass.h index a8315e21..462a17ce 100644 --- a/include/etl/crc16_buypass.h +++ b/include/etl/crc16_buypass.h @@ -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 using crc16_buypass_t = etl::crc_type; #else diff --git a/include/etl/crc16_ccitt.h b/include/etl/crc16_ccitt.h index eefd8255..9a444345 100644 --- a/include/etl/crc16_ccitt.h +++ b/include/etl/crc16_ccitt.h @@ -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 using crc16_ccitt_t = etl::crc_type; #else diff --git a/include/etl/crc16_cdma2000.h b/include/etl/crc16_cdma2000.h index 3a5b2b77..7784c9ae 100644 --- a/include/etl/crc16_cdma2000.h +++ b/include/etl/crc16_cdma2000.h @@ -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 using crc16_cdma2000_t = etl::crc_type; #else diff --git a/include/etl/crc16_dds110.h b/include/etl/crc16_dds110.h index e3dbbf8e..7a998e66 100644 --- a/include/etl/crc16_dds110.h +++ b/include/etl/crc16_dds110.h @@ -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 using crc16_dds110_t = etl::crc_type; #else diff --git a/include/etl/crc16_dectr.h b/include/etl/crc16_dectr.h index 172ebbbb..327dfc51 100644 --- a/include/etl/crc16_dectr.h +++ b/include/etl/crc16_dectr.h @@ -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 using crc16_dect_r_t = etl::crc_type; #else diff --git a/include/etl/crc16_dectx.h b/include/etl/crc16_dectx.h index d018d6cf..a8497d8d 100644 --- a/include/etl/crc16_dectx.h +++ b/include/etl/crc16_dectx.h @@ -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 using crc16_dect_x_t = etl::crc_type; #else diff --git a/include/etl/crc16_dnp.h b/include/etl/crc16_dnp.h index a347ccd3..02c67c4f 100644 --- a/include/etl/crc16_dnp.h +++ b/include/etl/crc16_dnp.h @@ -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 using crc16_dnp_t = etl::crc_type; #else diff --git a/include/etl/crc16_en13757.h b/include/etl/crc16_en13757.h index 1cb217fc..d5ec5fed 100644 --- a/include/etl/crc16_en13757.h +++ b/include/etl/crc16_en13757.h @@ -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 using crc16_en13757_t = etl::crc_type; #else diff --git a/include/etl/crc16_genibus.h b/include/etl/crc16_genibus.h index 378eebc1..a7cbb382 100644 --- a/include/etl/crc16_genibus.h +++ b/include/etl/crc16_genibus.h @@ -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 using crc16_genibus_t = etl::crc_type; #else diff --git a/include/etl/crc16_kermit.h b/include/etl/crc16_kermit.h index fa7db6b1..66dedb5b 100644 --- a/include/etl/crc16_kermit.h +++ b/include/etl/crc16_kermit.h @@ -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 using crc16_kermit_t = etl::crc_type; #else diff --git a/include/etl/crc16_maxim.h b/include/etl/crc16_maxim.h index ef3a2bca..896ab11d 100644 --- a/include/etl/crc16_maxim.h +++ b/include/etl/crc16_maxim.h @@ -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 using crc16_maxim_t = etl::crc_type; #else diff --git a/include/etl/crc16_mcrf4xx.h b/include/etl/crc16_mcrf4xx.h index 24012377..06a3f890 100644 --- a/include/etl/crc16_mcrf4xx.h +++ b/include/etl/crc16_mcrf4xx.h @@ -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 using crc16_mcrf4xx_t = etl::crc_type; #else diff --git a/include/etl/crc16_modbus.h b/include/etl/crc16_modbus.h index aa536027..5743ef41 100644 --- a/include/etl/crc16_modbus.h +++ b/include/etl/crc16_modbus.h @@ -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 using crc16_modbus_t = etl::crc_type; #else diff --git a/include/etl/crc16_profibus.h b/include/etl/crc16_profibus.h index 275f5bb6..9b6951c1 100644 --- a/include/etl/crc16_profibus.h +++ b/include/etl/crc16_profibus.h @@ -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 using crc16_profibus_t = etl::crc_type; #else diff --git a/include/etl/crc16_riello.h b/include/etl/crc16_riello.h index 65f99583..ed1332e5 100644 --- a/include/etl/crc16_riello.h +++ b/include/etl/crc16_riello.h @@ -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 using crc16_riello_t = etl::crc_type; #else diff --git a/include/etl/crc16_t10dif.h b/include/etl/crc16_t10dif.h index 1087c8cd..44e767a8 100644 --- a/include/etl/crc16_t10dif.h +++ b/include/etl/crc16_t10dif.h @@ -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 using crc16_t10dif_t = etl::crc_type; #else diff --git a/include/etl/crc16_teledisk.h b/include/etl/crc16_teledisk.h index 29e78eca..f90d8964 100644 --- a/include/etl/crc16_teledisk.h +++ b/include/etl/crc16_teledisk.h @@ -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 using crc16_teledisk_t = etl::crc_type; #else diff --git a/include/etl/crc16_tms37157.h b/include/etl/crc16_tms37157.h index 4af39380..31de01c5 100644 --- a/include/etl/crc16_tms37157.h +++ b/include/etl/crc16_tms37157.h @@ -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 using crc16_tms37157_t = etl::crc_type; #else diff --git a/include/etl/crc16_usb.h b/include/etl/crc16_usb.h index 2a2528f6..bb67e42c 100644 --- a/include/etl/crc16_usb.h +++ b/include/etl/crc16_usb.h @@ -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 using crc16_usb_t = etl::crc_type; #else diff --git a/include/etl/crc16_x25.h b/include/etl/crc16_x25.h index afb705c0..9120a7c2 100644 --- a/include/etl/crc16_x25.h +++ b/include/etl/crc16_x25.h @@ -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 using crc16_x25_t = etl::crc_type; #else diff --git a/include/etl/crc8_ccitt.h b/include/etl/crc8_ccitt.h index 80c7ec8e..d95b85c2 100644 --- a/include/etl/crc8_ccitt.h +++ b/include/etl/crc8_ccitt.h @@ -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 using crc8_ccitt_t = etl::crc_type; #else diff --git a/include/etl/crc8_cdma2000.h b/include/etl/crc8_cdma2000.h index d7a83108..f1607e56 100644 --- a/include/etl/crc8_cdma2000.h +++ b/include/etl/crc8_cdma2000.h @@ -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 using crc8_cdma2000_t = etl::crc_type; #else diff --git a/include/etl/crc8_darc.h b/include/etl/crc8_darc.h index 29a6a167..f419a706 100644 --- a/include/etl/crc8_darc.h +++ b/include/etl/crc8_darc.h @@ -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 using crc8_darc_t = etl::crc_type; #else diff --git a/include/etl/crc8_dvbs2.h b/include/etl/crc8_dvbs2.h index 02fe9f03..bd55a255 100644 --- a/include/etl/crc8_dvbs2.h +++ b/include/etl/crc8_dvbs2.h @@ -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 using crc8_dvbs2_t = etl::crc_type; #else diff --git a/include/etl/crc8_ebu.h b/include/etl/crc8_ebu.h index 3c4c7f2e..47b4613b 100644 --- a/include/etl/crc8_ebu.h +++ b/include/etl/crc8_ebu.h @@ -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 using crc8_ebu_t = etl::crc_type; #else diff --git a/include/etl/crc8_icode.h b/include/etl/crc8_icode.h index e421cc46..e51c6dfb 100644 --- a/include/etl/crc8_icode.h +++ b/include/etl/crc8_icode.h @@ -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 using crc8_icode_t = etl::crc_type; #else diff --git a/include/etl/crc8_itu.h b/include/etl/crc8_itu.h index a4a7fc0c..f84aa025 100644 --- a/include/etl/crc8_itu.h +++ b/include/etl/crc8_itu.h @@ -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 using crc8_itu_t = etl::crc_type; #else diff --git a/include/etl/crc8_maxim.h b/include/etl/crc8_maxim.h index bf39cd32..a138657f 100644 --- a/include/etl/crc8_maxim.h +++ b/include/etl/crc8_maxim.h @@ -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 using crc8_maxim_t = etl::crc_type; #else diff --git a/include/etl/crc8_rohc.h b/include/etl/crc8_rohc.h index dcade461..34e61dbe 100644 --- a/include/etl/crc8_rohc.h +++ b/include/etl/crc8_rohc.h @@ -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 using crc8_rohc_t = etl::crc_type; #else diff --git a/include/etl/crc8_wcdma.h b/include/etl/crc8_wcdma.h index a947e09a..f30d3529 100644 --- a/include/etl/crc8_wcdma.h +++ b/include/etl/crc8_wcdma.h @@ -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 using crc8_wcdma_t = etl::crc_type; #else diff --git a/include/etl/debounce.h b/include/etl/debounce.h index 21981236..b3787ce5 100644 --- a/include/etl/debounce.h +++ b/include/etl/debounce.h @@ -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 }, diff --git a/include/etl/error_handler.h b/include/etl/error_handler.h index 065f2480..fe62da42 100644 --- a/include/etl/error_handler.h +++ b/include/etl/error_handler.h @@ -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 diff --git a/include/etl/mem_cast.h b/include/etl/mem_cast.h index cc73cd66..3388d4ac 100644 --- a/include/etl/mem_cast.h +++ b/include/etl/mem_cast.h @@ -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::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 - ETL_CONSTEXPR mem_cast(const mem_cast& other) - : type_size(other.type_size) + mem_cast(const mem_cast& 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 + mem_cast& operator =(const mem_cast& rhs) + { + ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large"); + + memcpy(buffer, rhs.buffer, Size_); + + return *this; + } + + //*********************************** + /// Assign from value + //*********************************** + template + void assign(const T& value) + { + ETL_STATIC_ASSERT(Size >= sizeof(T), "Type size is too large"); + + ::new (static_cast(buffer)) T(value); + } + + //*********************************** + /// Assign from value at offset + //*********************************** + template + void assign_at_offset(size_t offset, const T& value) + { + char* p = static_cast(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 + void assign_at_offset(const T& value) + { + char* p = static_cast(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 void emplace(TArgs... args) { + ETL_STATIC_ASSERT(Size >= sizeof(T), "Type size is too large"); + ::new (static_cast(buffer)) T(etl::forward(args)...); } + + //*********************************** + /// Emplace from parameters at offset + //*********************************** + template + void emplace_at_offset(size_t offset, TArgs... args) + { + char* p = static_cast(buffer) + offset; + ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception)); + + ::new (p) T(etl::forward(args)...); + } + + //*********************************** + /// Emplace from parameters at offset + //*********************************** + template + void emplace_at_offset(TArgs... args) + { + char* p = static_cast(buffer) + Offset; + ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Type size is too large"); + + ::new (p) T(etl::forward(args)...); + } #endif //*********************************** /// Get a reference to T //*********************************** template - 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::value, "Alignment of T is incompatible"); return *static_cast(buffer); } @@ -144,32 +218,69 @@ namespace etl /// Get a const reference to T //*********************************** template - 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::value, "Alignment of T is incompatible"); return *static_cast(buffer); } //*********************************** - /// Assignment operator + /// Get a reference to T at offset (dynamic) //*********************************** - template - ETL_CONSTEXPR mem_cast& operator =(const mem_cast& rhs) + template + 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(p); + } + + //*********************************** + /// Get a const reference to T at offset (dynamic) + //*********************************** + template + 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(p); + } + + //*********************************** + /// Get a reference to T at offset (static) + //*********************************** + template + 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(p); + } + + //*********************************** + /// Get a const reference to T at offset (static) + //*********************************** + template + 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(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 class mem_cast_ptr { public: - static ETL_CONSTANT size_t Size = Size_; + static ETL_CONSTANT size_t Undefined_Size = etl::integral_limits::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 - ETL_CONSTEXPR mem_cast_ptr(const mem_cast_ptr& 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 + 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 + 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 + 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::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(args)...); } + + //*********************************** + /// Emplace from parameters at offset + //*********************************** + template + 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(args)...); + } + + //*********************************** + /// Emplace from parameters at offset + //*********************************** + template + 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(args)...); + } #endif //*********************************** /// Get a reference to T //*********************************** template - 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::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(pbuffer); } @@ -273,46 +456,107 @@ namespace etl /// Get a const reference to T //*********************************** template - 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::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(pbuffer); } //*********************************** - template - mem_cast_ptr& operator =(const mem_cast_ptr& rhs) + /// Get a reference to T at offset (dynamic) + //*********************************** + template + 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(p); } //*********************************** - /// Assignment operator + /// Get a const reference to T at offset (dynamic) //*********************************** - ETL_CONSTEXPR size_t size() const + template + 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(p); } //*********************************** - /// Get a pointer to the internal buffer + /// Get a reference to T at offset (static) //*********************************** - void data(char* pbuffer_) + template + 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(p); } //*********************************** - /// Get a const pointer to the internal buffer + /// Get a const reference to T at offset (static) //*********************************** - ETL_CONSTEXPR char* data() const + template + 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(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::type type; + + const type p = reinterpret_cast(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 using mem_cast_types = etl::mem_cast::size, etl::largest::alignment>; +#else + template + struct mem_cast_types : public etl::mem_cast::size, + etl::largest::alignment> + { + }; #endif } diff --git a/include/etl/version.h b/include/etl/version.h index cce3d1f9..61d898fe 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -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) diff --git a/library.json b/library.json index b72d881c..11db9207 100644 --- a/library.json +++ b/library.json @@ -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" diff --git a/library.properties b/library.properties index 7fdf7a9e..aeaf6fa4 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library ETL -version=20.10.5 +version=20.11.1 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/meson.build b/meson.build index 77d55aa3..f870b9bc 100644 --- a/meson.build +++ b/meson.build @@ -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' ) ###################### diff --git a/support/Release notes.txt b/support/Release notes.txt index 6f5ef35c..4e457139 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -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. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e91d9b3c..8664063e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 diff --git a/test/etl_profile.h b/test/etl_profile.h index 1c24412d..c1652ae3 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -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 diff --git a/test/test_mem_cast.cpp b/test/test_mem_cast.cpp index cb9105ee..304be224 100644 --- a/test/test_mem_cast.cpp +++ b/test/test_mem_cast.cpp @@ -38,6 +38,7 @@ SOFTWARE. namespace { + #pragma pack(push,1) struct Data { Data() @@ -58,6 +59,7 @@ namespace double d; std::array a; }; + #pragma pack(pop) constexpr size_t Size = etl::largest::size; constexpr size_t Alignment = etl::largest::alignment; @@ -134,6 +136,52 @@ namespace CHECK(alignof(Data) <= memCastTypes.alignment()); } + //************************************************************************* + TEST(test_mem_cast_assign_type) + { + MemCast memCast; + + memCast.assign(123); + CHECK_EQUAL(123, memCast.ref()); + + memCast.assign(1.23); + CHECK_EQUAL(1.23, memCast.ref()); + + Data data(123, 1.23, std::array{ 1, 2, 3 }); + memCast.assign(data); + CHECK(123 == memCast.ref().c); + CHECK(1.23 == memCast.ref().d); + CHECK((std::array { 1, 2, 3 }) == memCast.ref().a); + } + + //************************************************************************* + TEST(test_mem_cast_assign_type_at_dynamic_offset) + { + MemCast memCast; + + using Array = std::array; + Array a{ 1, 2, 3 }; + + size_t offset = offsetof(Data, a); + + memCast.assign_at_offset(offset, a); + CHECK(a == memCast.ref().a); + } + + //************************************************************************* + TEST(test_mem_cast_assign_type_at_static_offset) + { + MemCast memCast; + + using Array = std::array; + Array a{ 1, 2, 3 }; + + constexpr size_t Offset = offsetof(Data, a); + + memCast.assign_at_offset(a); + CHECK(a == memCast.ref().a); + } + //************************************************************************* TEST(test_mem_cast_emplace_type) { @@ -151,6 +199,34 @@ namespace CHECK((std::array { 1, 2, 3 }) == memCast.ref().a); } + //************************************************************************* + TEST(test_mem_cast_emplace_type_at_dynamic_offset) + { + MemCast memCast; + + using Array = std::array; + Array a{ 1, 2, 3 }; + + size_t offset = offsetof(Data, a); + + memCast.emplace_at_offset(offset, a); + CHECK(a == memCast.ref().a); + } + + //************************************************************************* + TEST(test_mem_cast_emplace_type_at_static_offset) + { + MemCast memCast; + + using Array = std::array; + Array a{ 1, 2, 3 }; + + constexpr size_t Offset = offsetof(Data, a); + + memCast.emplace_at_offset(a); + CHECK(a == memCast.ref().a); + } + //************************************************************************* TEST(test_mem_cast_to_type) { diff --git a/test/test_mem_cast_ptr.cpp b/test/test_mem_cast_ptr.cpp index 4bbebfac..582d9c7a 100644 --- a/test/test_mem_cast_ptr.cpp +++ b/test/test_mem_cast_ptr.cpp @@ -63,32 +63,175 @@ namespace constexpr size_t Alignment = etl::largest::alignment; // Test variant types. - using MemCast = etl::mem_cast_ptr; + using MemCast = etl::mem_cast_ptr; char c; double d; Data data; + char* Ptr(int i) + { + return reinterpret_cast(i); + } + std::aligned_storage_t 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(&buffer); + + MemCast memCast(pbuffer); + + memCast.assign(123); + CHECK_EQUAL(123, memCast.ref()); + + memCast.assign(1.23); + CHECK_EQUAL(1.23, memCast.ref()); + + Data data(123, 1.23, std::array{ 1, 2, 3 }); + memCast.assign(data); + CHECK(123 == memCast.ref().c); + CHECK(1.23 == memCast.ref().d); + CHECK((std::array { 1, 2, 3 }) == memCast.ref().a); + } + + //************************************************************************* + TEST(test_mem_cast_assign_type_at_dynamic_offset) + { + char* pbuffer = reinterpret_cast(&buffer); + + MemCast memCast(pbuffer); + + using Array = std::array; + Array a{ 1, 2, 3 }; + + size_t offset = offsetof(Data, a); + + memCast.assign_at_offset(offset, a); + CHECK(a == memCast.ref().a); + } + + //************************************************************************* + TEST(test_mem_cast_assign_type_at_static_offset) + { + char* pbuffer = reinterpret_cast(&buffer); + + MemCast memCast(pbuffer); + + using Array = std::array; + Array a{ 1, 2, 3 }; + + constexpr size_t Offset = offsetof(Data, a); + + memCast.assign_at_offset(a); + CHECK(a == memCast.ref().a); } //************************************************************************* @@ -110,6 +253,38 @@ namespace CHECK((std::array { 1, 2, 3 }) == memCast.ref().a); } + //************************************************************************* + TEST(test_mem_cast_emplace_type_at_dynamic_offset) + { + char* pbuffer = reinterpret_cast(&buffer); + + MemCast memCast(pbuffer); + + using Array = std::array; + Array a{ 1, 2, 3 }; + + size_t offset = offsetof(Data, a); + + memCast.emplace_at_offset(offset, a); + CHECK(a == memCast.ref().a); + } + + //************************************************************************* + TEST(test_mem_cast_emplace_type_at_static_offset) + { + char* pbuffer = reinterpret_cast(&buffer); + + MemCast memCast(pbuffer); + + using Array = std::array; + Array a{ 1, 2, 3 }; + + constexpr size_t Offset = offsetof(Data, a); + + memCast.emplace_at_offset(a); + CHECK(a == memCast.ref().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()); @@ -155,7 +329,7 @@ namespace { MemCast memCast; - CHECK_THROW(memCast.ref(), etl::mem_cast_nullptr_exception); + CHECK_THROW(char c = memCast.ref(), etl::mem_cast_nullptr_exception); } //************************************************************************* @@ -163,27 +337,7 @@ namespace { const MemCast memCast; - CHECK_THROW(memCast.ref(), etl::mem_cast_nullptr_exception); - } - - //************************************************************************* - TEST(test_mem_cast_to_type_misaligned_buffer) - { - double d; - char* pbuffer = reinterpret_cast(&d); - MemCast memCast(pbuffer + 1); - - CHECK_THROW(memCast.ref(), etl::mem_cast_alignment_exception); - } - - //************************************************************************* - TEST(test_const_mem_cast_to_type_misaligned_buffer) - { - double d; - char* pbuffer = reinterpret_cast(&d); - const MemCast memCast(pbuffer + 1); - - CHECK_THROW(memCast.ref(), etl::mem_cast_alignment_exception); + CHECK_THROW(char c = memCast.ref(), etl::mem_cast_nullptr_exception); } }; } diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 430c64ab..3b3a491b 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -1340,6 +1340,7 @@ + @@ -3232,12 +3233,20 @@ true - true true + true + true true - true - true true + true + true + true + true + true + true + true + true + true true @@ -5024,4 +5033,4 @@ - \ No newline at end of file + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index 2a763f13..747b9512 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -1110,7 +1110,7 @@ ETL\Private - + ETL\Utilities @@ -2681,4 +2681,4 @@ Resource Files - \ No newline at end of file +