mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-20 03:43:34 +08:00
Safer LazyConstructor - now requires to specify constructor parameter types manually
This commit is contained in:
@@ -39,6 +39,12 @@ class LazyConstructor
|
||||
failure();
|
||||
}
|
||||
|
||||
template <typename U> struct ParamType { typedef const U& Type; };
|
||||
template <typename U> struct ParamType<U&> { typedef U& Type; };
|
||||
#if __cplusplus > 201100
|
||||
template <typename U> struct ParamType<U&&> { typedef U&& Type; };
|
||||
#endif
|
||||
|
||||
public:
|
||||
LazyConstructor()
|
||||
: ptr_(NULL)
|
||||
@@ -51,7 +57,7 @@ public:
|
||||
{
|
||||
std::fill(data_, data_ + sizeof(T), 0);
|
||||
if (rhs)
|
||||
construct(*rhs); // Invoke copy constructor
|
||||
construct<const T&>(*rhs); // Invoke copy constructor
|
||||
}
|
||||
|
||||
~LazyConstructor() { destroy(); }
|
||||
@@ -60,7 +66,7 @@ public:
|
||||
{
|
||||
destroy();
|
||||
if (rhs)
|
||||
construct(*rhs); // Invoke copy constructor
|
||||
construct<const T&>(*rhs); // Invoke copy constructor
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -98,47 +104,50 @@ public:
|
||||
// for nargs in range(1, MAX_ARGS + 1):
|
||||
// nums = [(x + 1) for x in range(nargs)]
|
||||
// l1 = ['typename P%d' % x for x in nums]
|
||||
// l2 = ['P%d p%d' % (x, x) for x in nums]
|
||||
// l2 = ['typename ParamType<P%d>::Type p%d' % (x, x) for x in nums]
|
||||
// l3 = ['p%d' % x for x in nums]
|
||||
// print(TEMPLATE % (', '.join(l1), ', '.join(l2), ', '.join(l3)))
|
||||
|
||||
template <typename P1>
|
||||
void construct(P1 p1)
|
||||
void construct(typename ParamType<P1>::Type p1)
|
||||
{
|
||||
ensureNotConstructed();
|
||||
ptr_ = new (static_cast<void*>(data_)) T(p1);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2>
|
||||
void construct(P1 p1, P2 p2)
|
||||
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2)
|
||||
{
|
||||
ensureNotConstructed();
|
||||
ptr_ = new (static_cast<void*>(data_)) T(p1, p2);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2, typename P3>
|
||||
void construct(P1 p1, P2 p2, P3 p3)
|
||||
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3)
|
||||
{
|
||||
ensureNotConstructed();
|
||||
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2, typename P3, typename P4>
|
||||
void construct(P1 p1, P2 p2, P3 p3, P4 p4)
|
||||
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3,
|
||||
typename ParamType<P4>::Type p4)
|
||||
{
|
||||
ensureNotConstructed();
|
||||
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||
void construct(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
|
||||
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3,
|
||||
typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5)
|
||||
{
|
||||
ensureNotConstructed();
|
||||
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4, p5);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
|
||||
void construct(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
|
||||
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3,
|
||||
typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5, typename ParamType<P6>::Type p6)
|
||||
{
|
||||
ensureNotConstructed();
|
||||
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4, p5, p6);
|
||||
|
||||
@@ -21,7 +21,7 @@ TEST(LazyConstructor, Basic)
|
||||
*/
|
||||
a.destroy(); // no-op
|
||||
a.construct();
|
||||
b.construct("Hello world");
|
||||
b.construct<const char*>("Hello world");
|
||||
|
||||
ASSERT_TRUE(a);
|
||||
ASSERT_TRUE(b.isConstructed());
|
||||
|
||||
Reference in New Issue
Block a user