From 8cccb4aa669855f7954860c66e10dea3ee66c670 Mon Sep 17 00:00:00 2001 From: Cervenka Dusan Date: Fri, 4 Dec 2020 10:51:32 +0100 Subject: [PATCH 1/4] Improving template usage --- erpc_c/infra/erpc_manually_constructed.h | 90 ++++++++++++++++++++---- 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/erpc_c/infra/erpc_manually_constructed.h b/erpc_c/infra/erpc_manually_constructed.h index feed514a..48a8767f 100644 --- a/erpc_c/infra/erpc_manually_constructed.h +++ b/erpc_c/infra/erpc_manually_constructed.h @@ -49,47 +49,97 @@ class ManuallyConstructed public: //! @name Object access //@{ - T *get(void) { return reinterpret_cast(&m_storage); } - const T *get(void) const { return reinterpret_cast(&m_storage); } + T *get(void) { return (isConstructed) ? reinterpret_cast(&m_storage) : nullptr; } + const T *get(void) const { return (isConstructed) ? reinterpret_cast(&m_storage) : nullptr; } T *operator->(void) { return get(); } - const T *operator->(void)const { return get(); } - T &operator*(void) { return *get(); } - const T &operator*(void)const { return *get(); } + const T *operator->(void) const { return get(); } + T &operator*(void) + { + if (isConstructed) + { + return *get(); + } + else + { + memset(&m_storage, 0, sizeof(m_storage) * 8); + return reinterpret_cast(m_storage); + }; + } + const T &operator*(void) const + { + if (isConstructed) + { + return *get(); + } + else + { + memset(&m_storage, 0, sizeof(m_storage) * 8); + return reinterpret_cast(m_storage); + }; + } operator T *(void) { return get(); } - operator const T *(void)const { return get(); } + operator const T *(void) const { return get(); } //@} //! @name Explicit construction methods //@{ - void construct(void) { new (m_storage) T; } + void construct(void) + { + if (!isConstructed) + { + new (m_storage) T; + isConstructed = true; + } + } + template void construct(const A1 &a1) { - new (m_storage) T(a1); + if (!isConstructed) + { + new (m_storage) T(a1); + isConstructed = true; + } } template void construct(const A1 &a1, const A2 &a2) { - new (m_storage) T(a1, a2); + if (!isConstructed) + { + new (m_storage) T(a1, a2); + isConstructed = true; + } } template void construct(const A1 &a1, const A2 &a2, const A3 &a3) { - new (m_storage) T(a1, a2, a3); + if (!isConstructed) + { + new (m_storage) T(a1, a2, a3); + isConstructed = true; + } } template void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) { - new (m_storage) T(a1, a2, a3, a4); + if (!isConstructed) + { + new (m_storage) T(a1, a2, a3, a4); + isConstructed = true; + } } template void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) { - new (m_storage) T(a1, a2, a3, a4, a5); + if (!isConstructed) + { + new (m_storage) T(a1, a2, a3, a4, a5); + isConstructed = true; + } } //@} @@ -98,7 +148,14 @@ class ManuallyConstructed * * Behavior is undefined if the objected was not previously initialized. */ - void destroy(void) { get()->~T(); } + void destroy(void) + { + if (isConstructed) + { + get()->~T(); + isConstructed = false; + } + } protected: /*! @@ -107,6 +164,13 @@ class ManuallyConstructed * An array of uint64 is used to get 8-byte alignment. */ uint64_t m_storage[(sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t)]; + + /*! + * @brief Track construct/destruct calls. + * + * Based on this variable we can allow or forbid construct/destruct calls. + */ + bool isConstructed = false; }; } // namespace erpc From bd56df64b29e89f0b841fff583eb9562be75f3b8 Mon Sep 17 00:00:00 2001 From: Cervenka Dusan Date: Fri, 4 Dec 2020 11:42:34 +0100 Subject: [PATCH 2/4] Add prefix m_ to variable name isConstructed --- erpc_c/infra/erpc_manually_constructed.h | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/erpc_c/infra/erpc_manually_constructed.h b/erpc_c/infra/erpc_manually_constructed.h index 48a8767f..78d77874 100644 --- a/erpc_c/infra/erpc_manually_constructed.h +++ b/erpc_c/infra/erpc_manually_constructed.h @@ -49,13 +49,13 @@ class ManuallyConstructed public: //! @name Object access //@{ - T *get(void) { return (isConstructed) ? reinterpret_cast(&m_storage) : nullptr; } - const T *get(void) const { return (isConstructed) ? reinterpret_cast(&m_storage) : nullptr; } + T *get(void) { return (m_isConstructed) ? reinterpret_cast(&m_storage) : nullptr; } + const T *get(void) const { return (m_isConstructed) ? reinterpret_cast(&m_storage) : nullptr; } T *operator->(void) { return get(); } const T *operator->(void) const { return get(); } T &operator*(void) { - if (isConstructed) + if (m_isConstructed) { return *get(); } @@ -67,7 +67,7 @@ class ManuallyConstructed } const T &operator*(void) const { - if (isConstructed) + if (m_isConstructed) { return *get(); } @@ -85,60 +85,60 @@ class ManuallyConstructed //@{ void construct(void) { - if (!isConstructed) + if (!m_isConstructed) { new (m_storage) T; - isConstructed = true; + m_isConstructed = true; } } template void construct(const A1 &a1) { - if (!isConstructed) + if (!m_isConstructed) { new (m_storage) T(a1); - isConstructed = true; + m_isConstructed = true; } } template void construct(const A1 &a1, const A2 &a2) { - if (!isConstructed) + if (!m_isConstructed) { new (m_storage) T(a1, a2); - isConstructed = true; + m_isConstructed = true; } } template void construct(const A1 &a1, const A2 &a2, const A3 &a3) { - if (!isConstructed) + if (!m_isConstructed) { new (m_storage) T(a1, a2, a3); - isConstructed = true; + m_isConstructed = true; } } template void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) { - if (!isConstructed) + if (!m_isConstructed) { new (m_storage) T(a1, a2, a3, a4); - isConstructed = true; + m_isConstructed = true; } } template void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) { - if (!isConstructed) + if (!m_isConstructed) { new (m_storage) T(a1, a2, a3, a4, a5); - isConstructed = true; + m_isConstructed = true; } } //@} @@ -150,10 +150,10 @@ class ManuallyConstructed */ void destroy(void) { - if (isConstructed) + if (m_isConstructed) { get()->~T(); - isConstructed = false; + m_isConstructed = false; } } @@ -170,7 +170,7 @@ class ManuallyConstructed * * Based on this variable we can allow or forbid construct/destruct calls. */ - bool isConstructed = false; + bool m_isConstructed = false; }; } // namespace erpc From 62cc99556c819f7e0875df9176b6d1682f50a43f Mon Sep 17 00:00:00 2001 From: Cervenka Dusan Date: Wed, 9 Dec 2020 15:43:03 +0100 Subject: [PATCH 3/4] Destroy before construct. --- erpc_c/infra/erpc_manually_constructed.h | 48 +++++++++--------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/erpc_c/infra/erpc_manually_constructed.h b/erpc_c/infra/erpc_manually_constructed.h index 78d77874..397d402b 100644 --- a/erpc_c/infra/erpc_manually_constructed.h +++ b/erpc_c/infra/erpc_manually_constructed.h @@ -85,61 +85,49 @@ class ManuallyConstructed //@{ void construct(void) { - if (!m_isConstructed) - { - new (m_storage) T; - m_isConstructed = true; - } + destroy(); + new (m_storage) T; + m_isConstructed = true; } template void construct(const A1 &a1) { - if (!m_isConstructed) - { - new (m_storage) T(a1); - m_isConstructed = true; - } + destroy(); + new (m_storage) T(a1); + m_isConstructed = true; } template void construct(const A1 &a1, const A2 &a2) { - if (!m_isConstructed) - { - new (m_storage) T(a1, a2); - m_isConstructed = true; - } + destroy(); + new (m_storage) T(a1, a2); + m_isConstructed = true; } template void construct(const A1 &a1, const A2 &a2, const A3 &a3) { - if (!m_isConstructed) - { - new (m_storage) T(a1, a2, a3); - m_isConstructed = true; - } + destroy(); + new (m_storage) T(a1, a2, a3); + m_isConstructed = true; } template void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) { - if (!m_isConstructed) - { - new (m_storage) T(a1, a2, a3, a4); - m_isConstructed = true; - } + destroy(); + new (m_storage) T(a1, a2, a3, a4); + m_isConstructed = true; } template void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) { - if (!m_isConstructed) - { - new (m_storage) T(a1, a2, a3, a4, a5); - m_isConstructed = true; - } + destroy(); + new (m_storage) T(a1, a2, a3, a4, a5); + m_isConstructed = true; } //@} From e913b99aa208dcce1a1a4ecb40da0e82699d12f3 Mon Sep 17 00:00:00 2001 From: Dusan Cervenka Date: Thu, 21 Jan 2021 11:01:32 +0100 Subject: [PATCH 4/4] Update (C) --- erpc_c/infra/erpc_manually_constructed.h | 1 + 1 file changed, 1 insertion(+) diff --git a/erpc_c/infra/erpc_manually_constructed.h b/erpc_c/infra/erpc_manually_constructed.h index 397d402b..77c98d71 100644 --- a/erpc_c/infra/erpc_manually_constructed.h +++ b/erpc_c/infra/erpc_manually_constructed.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2014, Freescale Semiconductor, Inc. * Copyright 2016 NXP + * Copyright 2021 ACRIOS Systems s.r.o. * All rights reserved. * *