Skip to content

Commit

Permalink
libdeng2: Trying out a DENG2_PRIVATE compatible with old compilers
Browse files Browse the repository at this point in the history
std::auto_ptr<> with an undefined struct is not tolerated by some
compilers. Now DENG2_PRIVATE uses a custom PrivateAutoPtr class that
reinterprets the unknown instance type as an IPrivate when deleting.
  • Loading branch information
skyjake committed Mar 6, 2013
1 parent 356cdc9 commit 9d7aac3
Showing 1 changed file with 38 additions and 9 deletions.
47 changes: 38 additions & 9 deletions doomsday/libdeng2/include/de/libdeng2.h
Expand Up @@ -234,23 +234,52 @@
*/
#define DENG2_PRIVATE(Var) \
struct Instance; \
std::auto_ptr<Instance> Var;
de::PrivateAutoPtr<Instance> Var;

#if defined(__cplusplus)
namespace de {

struct IPrivate {
virtual ~IPrivate() {}
};

template <typename InstType>
class PrivateAutoPtr
{
public:
PrivateAutoPtr(InstType *p = 0) : ptr(p) {}
~PrivateAutoPtr() { reset(); }

InstType &operator * () const { return *ptr; }
InstType *operator -> () const { return ptr; }
void reset(InstType *p = 0) {
delete reinterpret_cast<IPrivate *>(ptr);
ptr = p;
}
InstType *get() const {
return ptr;
}
InstType *release() {
InstType *p = ptr;
ptr = 0;
return p;
}
private:
InstType *ptr;
};

/**
* Utility template for defining private implementation data (pimpl idiom). Use
* this in source files, not in headers.
*/
template <typename Type>
struct Private {
Type &self;
Type *thisPublic;
typedef Private<Type> Base;

Private(Type &i) : self(i), thisPublic(&i) {}
Private(Type *i) : self(*i), thisPublic(i) {}
template <typename PublicType>
struct Private : public IPrivate {
PublicType &self;
PublicType *thisPublic;
typedef Private<PublicType> Base;

Private(PublicType &i) : self(i), thisPublic(&i) {}
Private(PublicType *i) : self(*i), thisPublic(i) {}
};

template <typename FromType, typename ToType>
Expand Down

0 comments on commit 9d7aac3

Please sign in to comment.