Safer LazyConstructor - now requires to specify constructor parameter types manually

This commit is contained in:
Pavel Kirienko
2014-03-08 21:50:28 +04:00
parent b6dd1e3a14
commit 5a92b58e3e
2 changed files with 19 additions and 10 deletions
@@ -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);
+1 -1
View File
@@ -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());