eRPC API Reference  Rev. 1.12.0
NXP Semiconductors
erpc_manually_constructed.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Freescale Semiconductor, Inc.
3  * Copyright 2016 NXP
4  * Copyright 2021 ACRIOS Systems s.r.o.
5  * All rights reserved.
6  *
7  *
8  * SPDX-License-Identifier: BSD-3-Clause
9  */
10 
11 #ifndef _EMBEDDED_RPC__MANUALLY_CONSTRUCTED_H_
12 #define _EMBEDDED_RPC__MANUALLY_CONSTRUCTED_H_
13 
14 #include "erpc_config_internal.h"
15 
16 #include <new>
17 #include <stdint.h>
18 
25 // Classes
28 
29 namespace erpc {
50 template <class T>
52 {
53 public:
55 
56  T *get(void) { return (m_isConstructed) ? reinterpret_cast<T *>(&m_storage) : nullptr; }
57  const T *get(void) const { return (m_isConstructed) ? reinterpret_cast<const T *>(&m_storage) : nullptr; }
58  T *operator->(void) { return get(); }
59  const T *operator->(void) const { return get(); }
60  T &operator*(void)
61  {
62  if (m_isConstructed)
63  {
64  return *get();
65  }
66  else
67  {
68  memset(&m_storage, 0, sizeof(m_storage) * 8);
69  return reinterpret_cast<T &>(m_storage);
70  };
71  }
72  const T &operator*(void) const
73  {
74  if (m_isConstructed)
75  {
76  return *get();
77  }
78  else
79  {
80  memset(&m_storage, 0, sizeof(m_storage) * 8);
81  return reinterpret_cast<const T &>(m_storage);
82  };
83  }
84  operator T *(void) { return get(); }
85  operator const T *(void) const { return get(); }
87 
89 
90  void construct(void)
91  {
92  destroy();
93  new (m_storage) T;
94  m_isConstructed = true;
95  }
96 
97  template <typename A1>
98  void construct(const A1 &a1)
99  {
100  destroy();
101  new (m_storage) T(a1);
102  m_isConstructed = true;
103  }
104 
105  template <typename A1, typename A2>
106  void construct(const A1 &a1, const A2 &a2)
107  {
108  destroy();
109  new (m_storage) T(a1, a2);
110  m_isConstructed = true;
111  }
112 
113  template <typename A1, typename A2, typename A3>
114  void construct(const A1 &a1, const A2 &a2, const A3 &a3)
115  {
116  destroy();
117  new (m_storage) T(a1, a2, a3);
118  m_isConstructed = true;
119  }
120 
121  template <typename A1, typename A2, typename A3, typename A4>
122  void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
123  {
124  destroy();
125  new (m_storage) T(a1, a2, a3, a4);
126  m_isConstructed = true;
127  }
128 
129  template <typename A1, typename A2, typename A3, typename A4, typename A5>
130  void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
131  {
132  destroy();
133  new (m_storage) T(a1, a2, a3, a4, a5);
134  m_isConstructed = true;
135  }
136 
137  template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
138  void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6)
139  {
140  destroy();
141  new (m_storage) T(a1, a2, a3, a4, a5, a6);
142  m_isConstructed = true;
143  }
145 
151  void destroy(void)
152  {
153  if (m_isConstructed)
154  {
155  get()->~T();
156  m_isConstructed = false;
157  }
158  }
159 
166  bool isUsed(void) { return m_isConstructed; }
167 
168 protected:
174  uint64_t m_storage[(sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t)];
175 
181  bool m_isConstructed = false;
182 };
183 
184 #define ERPC_MANUALLY_CONSTRUCTED(class, variableName) static ManuallyConstructed<class> variableName
185 #define ERPC_MANUALLY_CONSTRUCTED_ARRAY(class, variableName, dimension) \
186  ERPC_MANUALLY_CONSTRUCTED(class, variableName)[dimension]
187 
188 #if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
189 #define ERPC_MANUALLY_CONSTRUCTED_STATIC(class, variableName) ERPC_MANUALLY_CONSTRUCTED(class, variableName)
190 #else
191 #define ERPC_MANUALLY_CONSTRUCTED_STATIC(class, variableName)
192 #endif
193 
194 #if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
195 #define ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(class, variableName, dimension) \
196  ERPC_MANUALLY_CONSTRUCTED_ARRAY(class, variableName, dimension)
197 #else
198 #define ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(class, variableName, dimension)
199 #endif
200 
201 #if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
202 #define ERPC_CREATE_NEW_OBJECT(class, arrayOfObjects, numberOfObjects, ...) \
203  return new (std::nothrow) class(__VA_ARGS__);
204 
205 #define ERPC_DESTROY_OBJECT(object, ...) delete object;
206 
207 #elif ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
208 #define ERPC_CREATE_NEW_OBJECT(class, arrayOfObjects, numberOfObjects, ...) \
209  uint8_t objectsIterator; \
210  class *ret = NULL; \
211  for (objectsIterator = 0; objectsIterator < numberOfObjects; objectsIterator++) \
212  { \
213  if (!arrayOfObjects[objectsIterator].isUsed()) \
214  { \
215  arrayOfObjects[objectsIterator].construct(__VA_ARGS__); \
216  ret = arrayOfObjects[objectsIterator].get(); \
217  break; \
218  } \
219  } \
220  return ret;
221 
222 #define ERPC_DESTROY_OBJECT(object, arrayOfObjects, numberOfObjects) \
223  uint8_t objectsIterator; \
224  for (objectsIterator = 0; objectsIterator < numberOfObjects; objectsIterator++) \
225  { \
226  if (object == arrayOfObjects[objectsIterator].get()) \
227  { \
228  arrayOfObjects[objectsIterator].destroy(); \
229  break; \
230  } \
231  }
232 #endif
233 
234 } // namespace erpc
235 
238 #endif // _EMBEDDED_RPC__MANUALLY_CONSTRUCTED_H_
uint64_t m_storage[(sizeof(T)+sizeof(uint64_t)-1)/sizeof(uint64_t)]
Storage for the object.
Definition: erpc_manually_constructed.hpp:174
bool m_isConstructed
Track construct/destruct calls.
Definition: erpc_manually_constructed.hpp:181
bool isUsed(void)
Returns information if object is free or is used.
Definition: erpc_manually_constructed.hpp:166
Definition: erpc_arbitrated_client_manager.hpp:25
void destroy(void)
Invoke the object&#39;s destructor.
Definition: erpc_manually_constructed.hpp:151
Allocates static storage for an object.
Definition: erpc_manually_constructed.hpp:51