2006-01-15 22:03:10 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// The Loki Library
|
|
|
|
|
// Copyright (c) 2006 Peter K<>mmel
|
|
|
|
|
// Permission to use, copy, modify, distribute and sell this software for any
|
|
|
|
|
// purpose is hereby granted without fee, provided that the above copyright
|
|
|
|
|
// notice appear in all copies and that both that copyright notice and this
|
|
|
|
|
// permission notice appear in supporting documentation.
|
|
|
|
|
// The author makes no representations about the
|
|
|
|
|
// suitability of this software for any purpose. It is provided "as is"
|
|
|
|
|
// without express or implied warranty.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
#ifndef LOKI_PIMPL_H
|
|
|
|
|
#define LOKI_PIMPL_H
|
|
|
|
|
|
2006-03-08 16:39:27 +00:00
|
|
|
|
// $Header$
|
|
|
|
|
|
|
|
|
|
/// \defgroup PimplGroup Pimpl
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
|
|
|
|
#ifndef LOKI_INHERITED_PIMPL_NAME
|
2006-01-16 13:27:49 +00:00
|
|
|
|
#define LOKI_INHERITED_PIMPL_NAME d
|
2006-01-15 22:03:10 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef LOKI_INHERITED_RIMPL_NAME
|
2006-01-16 13:27:49 +00:00
|
|
|
|
#define LOKI_INHERITED_RIMPL_NAME d
|
2006-01-15 22:03:10 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace Loki
|
|
|
|
|
{
|
2006-01-16 13:27:49 +00:00
|
|
|
|
|
2006-03-08 17:07:20 +00:00
|
|
|
|
//////////////////////////////////////////
|
|
|
|
|
/// \class ConstPropPtr
|
|
|
|
|
///
|
|
|
|
|
/// \ingroup PimplGroup
|
2006-03-08 16:39:27 +00:00
|
|
|
|
/// Simple const propagating smart pointer
|
2006-03-08 17:07:20 +00:00
|
|
|
|
/// Is the default smart pointer of Pimpl.
|
2006-01-28 20:13:57 +00:00
|
|
|
|
//////////////////////////////////////////
|
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
template<class T>
|
|
|
|
|
struct ConstPropPtr
|
2006-03-08 17:07:20 +00:00
|
|
|
|
{
|
2006-06-19 12:39:09 +00:00
|
|
|
|
explicit ConstPropPtr(T* p) : ptr_(p) {}
|
2006-03-08 17:07:20 +00:00
|
|
|
|
~ConstPropPtr() { delete ptr_; ptr_ = 0; }
|
2006-06-19 12:39:09 +00:00
|
|
|
|
T* operator->() { return ptr_; }
|
|
|
|
|
T& operator*() { return *ptr_; }
|
|
|
|
|
const T* operator->() const { return ptr_; }
|
|
|
|
|
const T& operator*() const { return *ptr_; }
|
2006-03-08 17:07:20 +00:00
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
private:
|
|
|
|
|
ConstPropPtr();
|
|
|
|
|
ConstPropPtr(const ConstPropPtr&);
|
|
|
|
|
ConstPropPtr& operator=(const ConstPropPtr&);
|
|
|
|
|
T* ptr_;
|
2006-03-08 17:07:20 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// \class Pimpl
|
|
|
|
|
///
|
|
|
|
|
/// \ingroup PimplGroup
|
|
|
|
|
///
|
|
|
|
|
/// Implements the Pimpl idiom. It's a wrapper for a smart pointer which
|
|
|
|
|
/// automatically creates and deletes the implementation object and adds
|
|
|
|
|
/// const propagation to the smart pointer.
|
|
|
|
|
///
|
|
|
|
|
/// \par Usage
|
|
|
|
|
/// see test/Pimpl
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2006-01-28 20:13:57 +00:00
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
template
|
2006-03-08 17:07:20 +00:00
|
|
|
|
<
|
2006-06-19 12:39:09 +00:00
|
|
|
|
class T,
|
|
|
|
|
typename Pointer = ConstPropPtr<T>
|
2006-03-08 17:07:20 +00:00
|
|
|
|
>
|
2006-01-28 20:13:57 +00:00
|
|
|
|
class Pimpl
|
2006-03-08 17:07:20 +00:00
|
|
|
|
{
|
2006-01-16 13:27:49 +00:00
|
|
|
|
public:
|
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
typedef T Impl;
|
2006-01-16 13:27:49 +00:00
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
Pimpl() : ptr_(new T)
|
2006-01-28 20:13:57 +00:00
|
|
|
|
{}
|
2006-01-23 17:23:46 +00:00
|
|
|
|
|
2006-03-08 17:07:20 +00:00
|
|
|
|
~Pimpl()
|
2006-03-02 09:55:37 +00:00
|
|
|
|
{
|
2006-03-08 17:07:20 +00:00
|
|
|
|
// Don't compile with incomplete type
|
|
|
|
|
//
|
2006-03-27 15:33:24 +00:00
|
|
|
|
// If compilation breaks here make sure
|
2006-03-08 17:07:20 +00:00
|
|
|
|
// the compiler does not auto-generate the
|
|
|
|
|
// destructor of the class hosting the pimpl:
|
|
|
|
|
// - implement the destructor of the class
|
|
|
|
|
// - don't inline the destructor
|
2006-06-19 12:39:09 +00:00
|
|
|
|
typedef char T_must_be_defined[sizeof(T) ? 1 : -1 ];
|
2006-03-08 17:07:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
T* operator->()
|
2006-01-23 17:23:46 +00:00
|
|
|
|
{
|
2006-01-28 20:13:57 +00:00
|
|
|
|
return ptr_.operator->();
|
2006-01-23 17:23:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-01-28 20:13:57 +00:00
|
|
|
|
T& operator*()
|
2006-01-23 17:23:46 +00:00
|
|
|
|
{
|
2006-01-28 20:13:57 +00:00
|
|
|
|
return ptr_.operator*();
|
2006-01-23 17:23:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-01-28 20:13:57 +00:00
|
|
|
|
const T* operator->() const
|
2006-01-15 22:03:10 +00:00
|
|
|
|
{
|
2006-01-28 20:13:57 +00:00
|
|
|
|
return ptr_.operator->();
|
2006-01-15 22:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-01-28 20:13:57 +00:00
|
|
|
|
const T& operator*() const
|
2006-01-15 22:03:10 +00:00
|
|
|
|
{
|
2006-01-28 20:13:57 +00:00
|
|
|
|
return ptr_.operator*();
|
2006-01-15 22:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
Pointer& wrapped()
|
2006-03-08 17:07:20 +00:00
|
|
|
|
{
|
2006-06-19 12:39:09 +00:00
|
|
|
|
return ptr_;
|
2006-03-08 17:07:20 +00:00
|
|
|
|
}
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
const Pointer& wrapped() const
|
2006-03-08 17:07:20 +00:00
|
|
|
|
{
|
2006-06-19 12:39:09 +00:00
|
|
|
|
return ptr_;
|
2006-03-08 17:07:20 +00:00
|
|
|
|
}
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
2006-06-19 12:39:09 +00:00
|
|
|
|
Pimpl(const Pimpl&);
|
2006-01-28 20:13:57 +00:00
|
|
|
|
Pimpl& operator=(const Pimpl&);
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
Pointer ptr_;
|
2006-01-16 13:27:49 +00:00
|
|
|
|
};
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
template<class T, typename Pointer = ConstPropPtr<T> >
|
2006-01-28 20:13:57 +00:00
|
|
|
|
struct PimplOwner
|
|
|
|
|
{
|
|
|
|
|
Pimpl<T,Pointer> LOKI_INHERITED_PIMPL_NAME;
|
|
|
|
|
};
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
|
|
|
|
|
2006-03-08 17:07:20 +00:00
|
|
|
|
//////////////////////////////////////////
|
2006-07-17 11:05:44 +00:00
|
|
|
|
/// \class ImplOf
|
2006-03-08 17:07:20 +00:00
|
|
|
|
///
|
2006-07-17 11:05:44 +00:00
|
|
|
|
/// \ingroup PimplGroup
|
2006-03-08 17:07:20 +00:00
|
|
|
|
/// Convenience template for the
|
2006-07-17 11:05:44 +00:00
|
|
|
|
/// implementations which Pimpl points to.
|
2006-01-28 20:13:57 +00:00
|
|
|
|
//////////////////////////////////////////
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-01-28 20:13:57 +00:00
|
|
|
|
template<class T>
|
2006-07-17 11:05:44 +00:00
|
|
|
|
struct ImplOf;
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
|
|
|
|
|
2006-03-08 17:07:20 +00:00
|
|
|
|
//////////////////////////////////////////
|
2006-07-17 11:05:44 +00:00
|
|
|
|
/// \class PImplOf
|
2006-03-08 17:07:20 +00:00
|
|
|
|
///
|
2006-07-17 11:05:44 +00:00
|
|
|
|
/// \ingroup PimplGroup
|
|
|
|
|
/// Convenience template which uses ImplOf
|
2006-03-08 17:07:20 +00:00
|
|
|
|
/// as implementation structure
|
2006-03-08 16:39:27 +00:00
|
|
|
|
//////////////////////////////////////////
|
|
|
|
|
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-01-28 20:13:57 +00:00
|
|
|
|
template<class T, template<class> class Ptr = ConstPropPtr>
|
2006-07-17 11:05:44 +00:00
|
|
|
|
struct PimplOf
|
2006-01-15 22:03:10 +00:00
|
|
|
|
{
|
2006-06-19 12:39:09 +00:00
|
|
|
|
typedef T Impl;
|
2006-01-28 20:13:57 +00:00
|
|
|
|
|
2006-01-16 13:30:26 +00:00
|
|
|
|
// declare pimpl
|
2006-07-17 11:05:44 +00:00
|
|
|
|
typedef Pimpl<ImplOf<T>, Ptr<ImplOf<T> > > Type;
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-01-16 13:30:26 +00:00
|
|
|
|
// inherit pimpl
|
2006-07-17 11:05:44 +00:00
|
|
|
|
typedef PimplOwner<ImplOf<T>, Ptr<ImplOf<T> > > Owner;
|
2006-03-08 17:07:20 +00:00
|
|
|
|
};
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
|
|
|
|
|
2006-07-17 11:05:44 +00:00
|
|
|
|
template<class T, class UsedPimpl = typename PimplOf<T>::Type >
|
|
|
|
|
struct RimplOf
|
2006-01-15 22:03:10 +00:00
|
|
|
|
{
|
2006-06-19 12:39:09 +00:00
|
|
|
|
typedef typename UsedPimpl::Impl & Type;
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-01-28 20:13:57 +00:00
|
|
|
|
class Owner
|
2006-03-08 17:07:20 +00:00
|
|
|
|
{
|
2006-06-19 12:39:09 +00:00
|
|
|
|
UsedPimpl pimpl;
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
public:
|
|
|
|
|
Owner() : LOKI_INHERITED_RIMPL_NAME(*pimpl)
|
2006-03-08 17:07:20 +00:00
|
|
|
|
{}
|
2006-01-15 22:03:10 +00:00
|
|
|
|
|
2006-06-19 12:39:09 +00:00
|
|
|
|
Type LOKI_INHERITED_RIMPL_NAME;
|
2006-03-08 17:07:20 +00:00
|
|
|
|
};
|
2006-01-28 20:13:57 +00:00
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2006-01-15 22:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-17 19:31:51 +00:00
|
|
|
|
#endif // end file guardian
|
2006-01-16 19:05:09 +00:00
|
|
|
|
|