lazy_constructor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_UTIL_LAZY_CONSTRUCTOR_HPP_INCLUDED
6 #define UAVCAN_UTIL_LAZY_CONSTRUCTOR_HPP_INCLUDED
7 
8 #include <cstdlib>
9 #include <uavcan/error.hpp>
10 #include <uavcan/build_config.hpp>
12 
13 #ifndef UAVCAN_CPP_VERSION
14 # error UAVCAN_CPP_VERSION
15 #endif
16 
17 namespace uavcan
18 {
26 template <typename T>
28 {
29 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
30  struct
31  {
32  alignas(T) unsigned char pool[sizeof(T)];
33  } data_;
34 #else
35  union
36  {
37  unsigned char pool[sizeof(T)];
38  long double _aligner1;
39  long long _aligner2;
40  } data_;
41 #endif
42 
43  T* ptr_;
44 
45  void ensureConstructed() const
46  {
47  if (!ptr_)
48  {
49  handleFatalError("LazyConstructor<T>");
50  }
51  }
52 
53  void ensureNotConstructed() const
54  {
55  if (ptr_)
56  {
57  handleFatalError("LazyConstructor<T>");
58  }
59  }
60 
61 public:
63  : ptr_(UAVCAN_NULLPTR)
64  {
65  fill(data_.pool, data_.pool + sizeof(T), uint8_t(0));
66  }
67 
68  LazyConstructor(const LazyConstructor<T>& rhs) // Implicit
69  : ptr_(UAVCAN_NULLPTR)
70  {
71  fill(data_.pool, data_.pool + sizeof(T), uint8_t(0));
72  if (rhs)
73  {
74  construct<const T&>(*rhs); // Invoke copy constructor
75  }
76  }
77 
78  ~LazyConstructor() { destroy(); }
79 
81  {
82  destroy();
83  if (rhs)
84  {
85  construct<const T&>(*rhs); // Invoke copy constructor
86  }
87  return *this;
88  }
89 
90  bool isConstructed() const { return ptr_ != UAVCAN_NULLPTR; }
91 
92  operator T*() const { return ptr_; }
93 
94  const T* operator->() const { ensureConstructed(); return ptr_; }
95  T* operator->() { ensureConstructed(); return ptr_; }
96 
97  const T& operator*() const { ensureConstructed(); return *ptr_; }
98  T& operator*() { ensureConstructed(); return *ptr_; }
99 
100  void destroy()
101  {
102  if (ptr_)
103  {
104  ptr_->~T();
105  }
106  ptr_ = UAVCAN_NULLPTR;
107  fill(data_.pool, data_.pool + sizeof(T), uint8_t(0));
108  }
109 
110  void construct()
111  {
112  ensureNotConstructed();
113  ptr_ = new (static_cast<void*>(data_.pool)) T();
114  }
115 
116 // MAX_ARGS = 6
117 // TEMPLATE = '''
118 // template <%s>
119 // void construct(%s)
120 // {
121 // ensureNotConstructed();
122 // ptr_ = new (static_cast<void*>(data_.pool)) T(%s);
123 // }'''
124 // for nargs in range(1, MAX_ARGS + 1):
125 // nums = [(x + 1) for x in range(nargs)]
126 // l1 = ['typename P%d' % x for x in nums]
127 // l2 = ['typename ParameterType<P%d>::Type p%d' % (x, x) for x in nums]
128 // l3 = ['p%d' % x for x in nums]
129 // print(TEMPLATE % (', '.join(l1), ', '.join(l2), ', '.join(l3)))
130 
131  template <typename P1>
133  {
134  ensureNotConstructed();
135  ptr_ = new (static_cast<void*>(data_.pool)) T(p1);
136  }
137 
138  template<typename P1, typename P2>
140  {
141  ensureNotConstructed();
142  ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2);
143  }
144 
145  template<typename P1, typename P2, typename P3>
147  typename ParameterType<P3>::Type p3)
148  {
149  ensureNotConstructed();
150  ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3);
151  }
152 
153  template<typename P1, typename P2, typename P3, typename P4>
155  typename ParameterType<P3>::Type p3, typename ParameterType<P4>::Type p4)
156  {
157  ensureNotConstructed();
158  ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3, p4);
159  }
160 
161  template<typename P1, typename P2, typename P3, typename P4, typename P5>
163  typename ParameterType<P3>::Type p3, typename ParameterType<P4>::Type p4,
164  typename ParameterType<P5>::Type p5)
165  {
166  ensureNotConstructed();
167  ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3, p4, p5);
168  }
169 
170  template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
172  typename ParameterType<P3>::Type p3, typename ParameterType<P4>::Type p4,
173  typename ParameterType<P5>::Type p5, typename ParameterType<P6>::Type p6)
174  {
175  ensureNotConstructed();
176  ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3, p4, p5, p6);
177  }
178 };
179 
180 }
181 
182 #endif // UAVCAN_UTIL_LAZY_CONSTRUCTOR_HPP_INCLUDED
std::uint8_t uint8_t
Definition: std.hpp:24
void construct(typename ParameterType< P1 >::Type p1, typename ParameterType< P2 >::Type p2, typename ParameterType< P3 >::Type p3, typename ParameterType< P4 >::Type p4, typename ParameterType< P5 >::Type p5)
void construct(typename ParameterType< P1 >::Type p1, typename ParameterType< P2 >::Type p2, typename ParameterType< P3 >::Type p3, typename ParameterType< P4 >::Type p4)
UAVCAN_EXPORT void handleFatalError(const char *msg)
Definition: uc_error.cpp:20
const T & operator*() const
UAVCAN_EXPORT void fill(ForwardIt first, ForwardIt last, const T &value)
Definition: templates.hpp:254
LazyConstructor(const LazyConstructor< T > &rhs)
void construct(typename ParameterType< P1 >::Type p1, typename ParameterType< P2 >::Type p2, typename ParameterType< P3 >::Type p3, typename ParameterType< P4 >::Type p4, typename ParameterType< P5 >::Type p5, typename ParameterType< P6 >::Type p6)
void construct(typename ParameterType< P1 >::Type p1, typename ParameterType< P2 >::Type p2, typename ParameterType< P3 >::Type p3)
void construct(typename ParameterType< P1 >::Type p1, typename ParameterType< P2 >::Type p2)
const T * operator->() const
void construct(typename ParameterType< P1 >::Type p1)
LazyConstructor< T > & operator=(const LazyConstructor< T > &rhs)


uavcan_communicator
Author(s):
autogenerated on Wed Jan 11 2023 03:59:39