Skip to content

Commit b94a617

Browse files
Merge pull request #153 from Hadatko/improve_manual_construct.h
Improving template usage
2 parents b90fee2 + 152b5ad commit b94a617

1 file changed

Lines changed: 61 additions & 6 deletions

File tree

erpc_c/infra/erpc_manually_constructed.h

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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
4950
public:
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

109157
protected:
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

Comments
 (0)