Embedded Template Library  1.0
factory.h
1 /******************************************************************************
2 The MIT License(MIT)
3 
4 Embedded Template Library.
5 https://github.com/ETLCPP/etl
6 https://www.etlcpp.com
7 
8 Copyright(c) 2017 jwellbelove
9 
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files(the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions :
16 
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 ******************************************************************************/
28 
29 #ifndef __ETL_FACTORY__
30 #define __ETL_FACTORY__
31 
32 #include <stdint.h>
33 #include <utility>
34 
35 #include "platform.h"
36 #include "error_handler.h"
37 #include "exception.h"
38 #include "largest.h"
39 #include "type_traits.h"
40 #include "alignment.h"
41 #include "static_assert.h"
42 #include "type_lookup.h"
43 #include "pool.h"
44 
45 #if defined(ETL_COMPILER_GCC)
46  #warning THIS CLASS IS DEPRECATED!USE VARIANT_POOL INSTEAD.
47 #elif defined(ETL_COMPILER_MICROSOFT)
48  #pragma message ("THIS CLASS IS DEPRECATED! USE VARIANT_POOL INSTEAD.")
49 #endif
50 
51 #undef ETL_FILE
52 #define ETL_FILE "40"
53 
54 namespace etl
55 {
56  //***************************************************************************
58  {
59  public:
60 
61  factory_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
62  : exception(reason_, file_name_, line_number_)
63  {
64  }
65  };
66 
67  //***************************************************************************
69  {
70  public:
71 
72  factory_cannot_create(string_type file_name_, numeric_type line_number_)
73  : factory_exception(ETL_ERROR_TEXT("factory:cannot create", ETL_FILE"A"), file_name_, line_number_)
74  {
75  }
76  };
77 
78  //***************************************************************************
80  {
81  public:
82 
83  factory_did_not_create(string_type file_name_, numeric_type line_number_)
84  : factory_exception(ETL_ERROR_TEXT("factory:did not create", ETL_FILE"B"), file_name_, line_number_)
85  {
86  }
87  };
88 
89  //***************************************************************************
90  template <const size_t MAX_SIZE_,
91  typename T1,
92  typename T2 = etl::type_id_pair<etl::null_type, -2>,
93  typename T3 = etl::type_id_pair<etl::null_type, -3>,
94  typename T4 = etl::type_id_pair<etl::null_type, -4>,
95  typename T5 = etl::type_id_pair<etl::null_type, -5>,
96  typename T6 = etl::type_id_pair<etl::null_type, -6>,
97  typename T7 = etl::type_id_pair<etl::null_type, -7>,
98  typename T8 = etl::type_id_pair<etl::null_type, -8>,
99  typename T9 = etl::type_id_pair<etl::null_type, -9>,
100  typename T10 = etl::type_id_pair<etl::null_type, -10>,
101  typename T11 = etl::type_id_pair<etl::null_type, -11>,
102  typename T12 = etl::type_id_pair<etl::null_type, -12>,
103  typename T13 = etl::type_id_pair<etl::null_type, -13>,
104  typename T14 = etl::type_id_pair<etl::null_type, -14>,
105  typename T15 = etl::type_id_pair<etl::null_type, -15>,
106  typename T16 = etl::type_id_pair<etl::null_type, -16> >
107  class factory
108  {
109  private:
110 
111  typedef typename T1::type TT1;
112  typedef typename T2::type TT2;
113  typedef typename T3::type TT3;
114  typedef typename T4::type TT4;
115  typedef typename T5::type TT5;
116  typedef typename T6::type TT6;
117  typedef typename T7::type TT7;
118  typedef typename T8::type TT8;
119  typedef typename T9::type TT9;
120  typedef typename T10::type TT10;
121  typedef typename T11::type TT11;
122  typedef typename T12::type TT12;
123  typedef typename T13::type TT13;
124  typedef typename T14::type TT14;
125  typedef typename T15::type TT15;
126  typedef typename T16::type TT16;
127 
128  typedef etl::type_id_lookup<T1, T2, T3, T4, T5, T6, T7, T8,
129  T9, T10, T11, T12, T13, T14, T15, T16> lookup_t;
130 
131  public:
132 
133  static const size_t MAX_SIZE = MAX_SIZE_;
134 
135  //*************************************************************************
137  //*************************************************************************
139  {
140  }
141 
142 #if !ETL_CPP11_SUPPORTED
143  //*************************************************************************
145  //*************************************************************************
146  template <typename T>
148  {
150 
151  T* p = nullptr;
152 
153  if (pool.full())
154  {
155  ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
156  }
157  else
158  {
159  p = pool.template allocate<T>();
160 
161  if (p != nullptr)
162  {
163  new (p) T();
164  }
165  }
166 
167  return p;
168  }
169 
170  //*************************************************************************
172  //*************************************************************************
173  template <typename T, typename TP1>
174  T* create_from_type(const TP1& p1)
175  {
177 
178  T* p = nullptr;
179 
180  if (pool.full())
181  {
182  ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
183  }
184  else
185  {
186  p = pool.template allocate<T>();
187 
188  if (p != nullptr)
189  {
190  new (p) T(p1);
191  }
192  }
193 
194  return p;
195  }
196 
197  //*************************************************************************
199  //*************************************************************************
200  template <typename T, typename TP1, typename TP2>
201  T* create_from_type(const TP1& p1, const TP2& p2)
202  {
204 
205  T* p = nullptr;
206 
207  if (pool.full())
208  {
209  ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
210  }
211  else
212  {
213  p = pool.template allocate<T>();
214 
215  if (p != nullptr)
216  {
217  new (p) T(p1, p2);
218  }
219  }
220 
221  return p;
222  }
223 
224  //*************************************************************************
226  //*************************************************************************
227  template <typename T, typename TP1, typename TP2, typename TP3>
228  T* create_from_type(const TP1& p1, const TP2& p2, const TP3& p3)
229  {
231 
232  T* p = nullptr;
233 
234  if (pool.full())
235  {
236  ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
237  }
238  else
239  {
240  p = pool.template allocate<T>();
241 
242  if (p != nullptr)
243  {
244  new (p) T(p1, p2, p3);
245  }
246  }
247 
248  return p;
249  }
250 
251  //*************************************************************************
253  //*************************************************************************
254  template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
255  T* create_from_type(const TP1& p1, const TP2& p2, const TP3& p3, const TP4& p4)
256  {
258 
259  T* p = nullptr;
260 
261  if (pool.full())
262  {
263  ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
264  }
265  else
266  {
267  p = pool.template allocate<T>();
268 
269  if (p != nullptr)
270  {
271  new (p) T(p1, p2, p3, p4);
272  }
273  }
274 
275  return p;
276  }
277 
278  //*************************************************************************
280  //*************************************************************************
281  template <size_t ID>
282  typename lookup_t::template type_from_id<ID>::type* create_from_id()
283  {
284  typedef typename lookup_t::template type_from_id<ID>::type type;
285  STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
286  return create_from_type<type>();
287  }
288 
289  //*************************************************************************
291  //*************************************************************************
292  template <size_t ID, typename TP1>
293  typename lookup_t::template type_from_id<ID>::type* create_from_id(const TP1& p1)
294  {
295  typedef typename lookup_t::template type_from_id<ID>::type type;
296  STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
297  return create_from_type<type>(p1);
298  }
299 
300  //*************************************************************************
302  //*************************************************************************
303  template <size_t ID, typename TP1, typename TP2>
304  typename lookup_t::template type_from_id<ID>::type* create_from_id(const TP1& p1, const TP2& p2)
305  {
306  typedef typename lookup_t::template type_from_id<ID>::type type;
307  STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
308  return create_from_type<type>(p1, p2);
309  }
310 
311  //*************************************************************************
313  //*************************************************************************
314  template <size_t ID, typename TP1, typename TP2, typename TP3>
315  typename lookup_t::template type_from_id<ID>::type* create_from_id(const TP1& p1, const TP2& p2, const TP3& p3)
316  {
317  typedef typename lookup_t::template type_from_id<ID>::type type;
318  STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
319  return create_from_type<type>(p1, p2, p3);
320  }
321 
322  //*************************************************************************
324  //*************************************************************************
325  template <size_t ID, typename TP1, typename TP2, typename TP3, typename TP4>
326  typename lookup_t::template type_from_id<ID>::type* create_from_id(const TP1& p1, const TP2& p2, const TP3& p3, const TP4& p4)
327  {
328  typedef typename lookup_t::template type_from_id<ID>::type type;
329  STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
330  return create_from_type<type>(p1, p2, p3, p4);
331  }
332 #else
333  //*************************************************************************
335  //*************************************************************************
336  template <typename T, typename... Args>
337  T* create_from_type(Args&&... args)
338  {
340 
341  T* p = nullptr;
342 
343  if (pool.full())
344  {
345  ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
346  }
347  else
348  {
349  p = pool.template allocate<T>();
350 
351  if (p != nullptr)
352  {
353  new (p) T(std::forward<Args>(args)...);
354  }
355  }
356 
357  return p;
358  }
359 
360  //*************************************************************************
362  //*************************************************************************
363  template <size_t ID, typename... Args>
364  typename lookup_t::template type_from_id<ID>::type* create_from_id(Args&&... args)
365  {
366  typedef typename lookup_t::template type_from_id<ID>::type type;
367  STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
368  return create_from_type<type>(std::forward<Args>(args)...);
369  }
370 #endif
371 
372  //*************************************************************************
374  //*************************************************************************
375  template <typename T>
376  bool destroy(const T* const p)
377  {
394  etl::is_base_of<T, TT16>::value), "Invalid type");
395 
396  p->~T();
397 
398  void* vp = reinterpret_cast<char*>(const_cast<T*>(p));
399 
400  if (pool.is_in_pool(vp))
401  {
402  pool.release(vp);
403  return true;
404  }
405  else
406  {
407  ETL_ASSERT(false, ETL_ERROR(factory_did_not_create));
408  return false;
409  }
410  }
411 
412  //*************************************************************************
414  //*************************************************************************
415  size_t max_size() const
416  {
417  return MAX_SIZE;
418  }
419 
420  //*************************************************************************
422  //*************************************************************************
423  size_t available() const
424  {
425  return pool.available();
426  }
427 
428  //*************************************************************************
430  //*************************************************************************
431  size_t size() const
432  {
433  return pool.size();
434  }
435 
436  //*************************************************************************
439  //*************************************************************************
440  bool empty() const
441  {
442  return pool.empty();
443  }
444 
445  //*************************************************************************
448  //*************************************************************************
449  bool full() const
450  {
451  return pool.full();
452  }
453 
454  private:
455 
456  factory(const factory&);
457  factory& operator =(const factory&);
458 
459  // The pool.
462  MAX_SIZE> pool;
463  };
464 }
465 
466 #undef ETL_FILE
467 
468 #endif
Definition: factory.h:69
Definition: factory.h:80
Definition: factory.h:58
Definition: factory.h:108
T * create_from_type()
Creates the object. Default constructor.
Definition: factory.h:147
factory()
Default constructor.
Definition: factory.h:138
bool empty() const
Definition: factory.h:440
bool full() const
Definition: factory.h:449
T * create_from_type(const TP1 &p1, const TP2 &p2, const TP3 &p3, const TP4 &p4)
Creates the object. Four parameter constructor.
Definition: factory.h:255
T * create_from_type(const TP1 &p1)
Creates the object. One parameter constructor.
Definition: factory.h:174
size_t available() const
Returns the number of free items in the factory.
Definition: factory.h:423
bool destroy(const T *const p)
Destroys the object.
Definition: factory.h:376
T * create_from_type(const TP1 &p1, const TP2 &p2, const TP3 &p3)
Creates the object. Three parameter constructor.
Definition: factory.h:228
T * create_from_type(const TP1 &p1, const TP2 &p2)
Creates the object. Two parameter constructor.
Definition: factory.h:201
size_t size() const
Returns the number of allocated items in the factory.
Definition: factory.h:431
lookup_t::template type_from_id< ID >::type * create_from_id()
Creates the object from an index. Default constructor.
Definition: factory.h:282
size_t max_size() const
Returns the maximum number of items in the factory.
Definition: factory.h:415
Definition: null_type.h:39
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
Definition: largest.h:362
size_t size() const
Returns the number of allocated items in the pool.
Definition: pool.h:309
bool empty() const
Definition: pool.h:318
bool is_in_pool(const void *p_object) const
Definition: pool.h:276
bool full() const
Definition: pool.h:327
void release(const void *const p_object)
Definition: pool.h:255
size_t available() const
Returns the number of free items in the pool.
Definition: pool.h:301
Definition: pool.h:470
Definition: pool.h:617
is_base_of
Definition: type_traits_generator.h:1289
is_same
Definition: type_traits_generator.h:981
Definition: absolute.h:37
Definition: type_traits.h:1397
Definition: type_lookup.h:245
The type/id pair type to use for type/id lookup template parameters.
Definition: type_lookup_generator.h:70