From 0f487fa12673a6aab406c1ed0bc23d5602eb406d Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 16 Dec 2024 14:58:16 +0000 Subject: [PATCH] Make 'packed' have better cross platform functionality --- include/etl/platform.h | 13 +++++++++++-- include/etl/unaligned_type.h | 6 +++--- test/test_etl_traits.cpp | 1 + test/test_utility.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/etl/platform.h b/include/etl/platform.h index 6ea92d362..0583d17ae 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -462,10 +462,18 @@ SOFTWARE. //************************************* // Determine if the ETL should use __attribute__((packed). -#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) - #define ETL_PACKED __attribute__((packed)) +#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) || defined(ETL_COMPILER_ARM6) + #define ETL_PACKED __attribute__((packed)) + #define ETL_END_PACKED + #define ETL_HAS_PACKED 1 +#elif defined(ETL_COMPILER_MICROSOFT) + #define ETL_PACKED __pragma(pack(push, 1)) + #define ETL_END_PACKED __pragma(pack(pop)) + #define ETL_HAS_PACKED 1 #else #define ETL_PACKED + #define ETL_END_PACKED + #define ETL_HAS_PACKED 0 #endif //************************************* @@ -526,6 +534,7 @@ namespace etl static ETL_CONSTANT bool has_mutable_array_view = (ETL_HAS_MUTABLE_ARRAY_VIEW == 1); static ETL_CONSTANT bool has_ideque_repair = (ETL_HAS_IDEQUE_REPAIR == 1); static ETL_CONSTANT bool has_virtual_messages = (ETL_HAS_VIRTUAL_MESSAGES == 1); + static ETL_CONSTANT bool has_packed = (ETL_HAS_PACKED == 1); // Is... static ETL_CONSTANT bool is_debug_build = (ETL_IS_DEBUG_BUILD == 1); diff --git a/include/etl/unaligned_type.h b/include/etl/unaligned_type.h index 77e38ce12..1c406ba3c 100644 --- a/include/etl/unaligned_type.h +++ b/include/etl/unaligned_type.h @@ -53,7 +53,7 @@ namespace etl /// Contains all functionality that doesn't require the type. //************************************************************************* template - class unaligned_type_common + class ETL_PACKED unaligned_type_common { public: @@ -214,7 +214,7 @@ namespace etl protected: unsigned char storage[Size]; - }; + }; ETL_END_PACKED template ETL_CONSTANT size_t unaligned_type_common::Size; @@ -729,7 +729,7 @@ namespace etl } } }; - }; + }; ETL_END_PACKED template ETL_CONSTANT int unaligned_type::Endian; diff --git a/test/test_etl_traits.cpp b/test/test_etl_traits.cpp index a071960e4..24123ad3a 100644 --- a/test/test_etl_traits.cpp +++ b/test/test_etl_traits.cpp @@ -77,6 +77,7 @@ namespace CHECK_EQUAL((ETL_HAS_IDEQUE_REPAIR == 1), etl::traits::has_ideque_repair); CHECK_EQUAL((ETL_HAS_MUTABLE_ARRAY_VIEW == 1), etl::traits::has_mutable_array_view); CHECK_EQUAL((ETL_HAS_VIRTUAL_MESSAGES == 1), etl::traits::has_virtual_messages); + CHECK_EQUAL((ETL_HAS_PACKED == 1), etl::traits::has_packed); CHECK_EQUAL((ETL_IS_DEBUG_BUILD == 1), etl::traits::is_debug_build); CHECK_EQUAL(__cplusplus, etl::traits::cplusplus); diff --git a/test/test_utility.cpp b/test/test_utility.cpp index 223058547..5d7e28091 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -718,5 +718,31 @@ namespace CHECK_EQUAL(forward_like_call_type::ConstRValue, template_function_fl(etl::move(u4))); CHECK_EQUAL(forward_like_call_type::ConstRValue, template_function_fl(etl::move(u4))); } + +#if ETL_HAS_PACKED + //********************************* + TEST(test_packed) + { + struct Unpacked + { + uint32_t a = 0x12345678; + uint8_t b = 0x9A; + uint32_t c = 0x87654321; + }; + + struct ETL_PACKED Packed + { + uint32_t a = 0x12345678; + uint8_t b = 0x9A; + uint32_t c = 0x87654321; + }; ETL_END_PACKED + + Unpacked unpacked; + Packed packed; + + CHECK_TRUE(sizeof(unpacked) > sizeof(packed)); + CHECK_EQUAL(9U, sizeof(packed)); + } +#endif }; }