11/*
22 * Copyright (c) 2014, Freescale Semiconductor, Inc.
33 * Copyright 2016 NXP
4+ * Copyright 2021 ACRIOS Systems s.r.o.
45 * All rights reserved.
56 *
67 *
@@ -49,53 +50,93 @@ class ManuallyConstructed
4950public:
5051 // ! @name Object access
5152 // @{
52- T *get (void ) { return reinterpret_cast <T *>(&m_storage); }
53- const T *get (void ) const { return reinterpret_cast <const T *>(&m_storage); }
53+ T *get (void ) { return (m_isConstructed) ? reinterpret_cast <T *>(&m_storage) : nullptr ; }
54+ const T *get (void ) const { return (m_isConstructed) ? reinterpret_cast <const T *>(&m_storage) : nullptr ; }
5455 T *operator ->(void ) { return get (); }
5556 const T *operator ->(void ) const { return get (); }
56- T &operator *(void ) { return *get (); }
57- const T &operator *(void ) const { return *get (); }
57+ T &operator *(void )
58+ {
59+ if (m_isConstructed)
60+ {
61+ return *get ();
62+ }
63+ else
64+ {
65+ memset (&m_storage, 0 , sizeof (m_storage) * 8 );
66+ return reinterpret_cast <T &>(m_storage);
67+ };
68+ }
69+ const T &operator *(void ) const
70+ {
71+ if (m_isConstructed)
72+ {
73+ return *get ();
74+ }
75+ else
76+ {
77+ memset (&m_storage, 0 , sizeof (m_storage) * 8 );
78+ return reinterpret_cast <const T &>(m_storage);
79+ };
80+ }
5881 operator T *(void ) { return get (); }
5982 operator const T *(void ) const { return get (); }
6083 // @}
6184
6285 // ! @name Explicit construction methods
6386 // @{
64- void construct (void ) { new (m_storage) T; }
87+ void construct (void )
88+ {
89+ destroy ();
90+ new (m_storage) T;
91+ m_isConstructed = true ;
92+ }
93+
6594 template <typename A1>
6695 void construct (const A1 &a1)
6796 {
97+ destroy ();
6898 new (m_storage) T (a1);
99+ m_isConstructed = true ;
69100 }
70101
71102 template <typename A1, typename A2>
72103 void construct (const A1 &a1, const A2 &a2)
73104 {
105+ destroy ();
74106 new (m_storage) T (a1, a2);
107+ m_isConstructed = true ;
75108 }
76109
77110 template <typename A1, typename A2, typename A3>
78111 void construct (const A1 &a1, const A2 &a2, const A3 &a3)
79112 {
113+ destroy ();
80114 new (m_storage) T (a1, a2, a3);
115+ m_isConstructed = true ;
81116 }
82117
83118 template <typename A1, typename A2, typename A3, typename A4>
84119 void construct (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
85120 {
121+ destroy ();
86122 new (m_storage) T (a1, a2, a3, a4);
123+ m_isConstructed = true ;
87124 }
88125
89126 template <typename A1, typename A2, typename A3, typename A4, typename A5>
90127 void construct (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
91128 {
129+ destroy ();
92130 new (m_storage) T (a1, a2, a3, a4, a5);
131+ m_isConstructed = true ;
93132 }
94133
95134 template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
96135 void construct (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6)
97136 {
137+ destroy ();
98138 new (m_storage) T (a1, a2, a3, a4, a5, a6);
139+ m_isConstructed = true ;
99140 }
100141 // @}
101142
@@ -104,7 +145,14 @@ class ManuallyConstructed
104145 *
105146 * Behavior is undefined if the objected was not previously initialized.
106147 */
107- void destroy (void ) { get ()->~T (); }
148+ void destroy (void )
149+ {
150+ if (m_isConstructed)
151+ {
152+ get ()->~T ();
153+ m_isConstructed = false ;
154+ }
155+ }
108156
109157protected:
110158 /* !
@@ -113,6 +161,13 @@ class ManuallyConstructed
113161 * An array of uint64 is used to get 8-byte alignment.
114162 */
115163 uint64_t m_storage[(sizeof (T) + sizeof (uint64_t ) - 1 ) / sizeof (uint64_t )];
164+
165+ /* !
166+ * @brief Track construct/destruct calls.
167+ *
168+ * Based on this variable we can allow or forbid construct/destruct calls.
169+ */
170+ bool m_isConstructed = false ;
116171};
117172
118173} // namespace erpc
0 commit comments