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
}
# endif
2006-01-16 19:05:09 +00:00
// $Log$
2006-07-17 11:05:44 +00:00
// Revision 1.22 2006/07/17 11:05:44 syntheticpp
// ImplT/PimplT/RimplT renamed to the more readable version: T->Of
//
2006-06-19 12:39:09 +00:00
// Revision 1.21 2006/06/19 12:39:08 syntheticpp
// replace tabs with 4 spaces
//
2006-03-27 15:33:24 +00:00
// Revision 1.20 2006/03/27 15:33:24 syntheticpp
// fix spelling
//
2006-03-08 17:07:20 +00:00
// Revision 1.19 2006/03/08 17:07:11 syntheticpp
// replace tabs with 4 spaces in all files
//
2006-03-08 16:39:27 +00:00
// Revision 1.18 2006/03/08 16:39:27 syntheticpp
// add documenation
//
2006-03-02 09:55:37 +00:00
// Revision 1.17 2006/03/02 09:55:37 syntheticpp
// don't compile with incomplete types
//
2006-03-01 15:20:19 +00:00
// Revision 1.16 2006/03/01 15:20:19 syntheticpp
// add documenation how to avoid the -deletion of pointer to incomplete type- error
//
2006-01-28 20:13:57 +00:00
// Revision 1.15 2006/01/28 20:12:56 syntheticpp
// replace implementation with a auto-create and propagating-const wrapper for smart pointers which auto delete the holded pointer on destruction
//
2006-01-26 14:28:59 +00:00
// Revision 1.14 2006/01/26 14:28:59 syntheticpp
// remove wrong 'typename'
//
2006-01-23 17:23:46 +00:00
// Revision 1.13 2006/01/23 17:22:49 syntheticpp
// add support of deep constness, only supported by (future) Loki::SmartPtr, not supported by boost::shared_ptr and plain pointer. Maybe deep constness forces a redesign of Pimpl. Is there a way to support deep constness by a rimpl?
//
2006-01-19 18:16:39 +00:00
// Revision 1.12 2006/01/19 18:16:39 syntheticpp
// disable usage with auto_ptr: don't compile with std::auto_ptr
//
2006-01-18 19:03:25 +00:00
// Revision 1.11 2006/01/18 19:03:06 syntheticpp
// make rimpl type really a reference
//
2006-01-18 16:49:32 +00:00
// Revision 1.10 2006/01/18 16:49:06 syntheticpp
// move definition of the destructor to extra file, because msvc tries to use the incomplete type; not inlining does not help; maybe this is a compiler bug.
//
2006-01-17 12:03:36 +00:00
// Revision 1.9 2006/01/17 12:03:36 syntheticpp
// add comment about auto_ptr
//
2006-01-17 11:07:34 +00:00
// Revision 1.8 2006/01/17 11:07:34 syntheticpp
// AutoPtrHolderChecked inherits from AutoPtrHolder
//
2006-01-16 19:48:23 +00:00
// Revision 1.7 2006/01/16 19:48:23 syntheticpp
// add error policy
//
2006-01-16 19:05:09 +00:00
// Revision 1.6 2006/01/16 19:05:09 rich_sposato
// Added cvs keywords.
//