$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Beman Dawes (bdawes_at_[hidden])
Date: 2002-01-13 16:54:48
At 05:39 AM 1/13/2002, Andrei Alexandrescu wrote:
 >I think a good solution would be the following.
 >
 >The policies might take two template arguments, the last one being the
 >SmartPtr class itself. In turn, SmartPtr exposes all of its policies
 >through
 >typedefs. Here's a trimmed-down example.
 >
 >template <
 >    class T,
 >    template <class, class> class Checking>
 >    template <class, class> class Storage>
 >class SmartPtr
 >    : public Checking< T, SmartPtr<T, Checking, Storage> >
 >    : public Storage< T, SmartPtr<T, Checking, Storage> >
 >{
 >public:
 >    typedef Checking checking_policy;
 >    typedef Storage storage_policy;
 >    ...
 >};
 >
 >So now the policies that don't care of each other simply ignore their
 >second
 >template parameter. Policies that do need to communicate with 
neighbouring
 >policies can access them by using the parent class and their named
 >typedefs.
 >This is cool as long as we're working with static functions. If needed, a
 >static_cast could access the parent object as well. (I'd prefer something
 >better than that.)
Yes, agreed.  This is the approach Peter Dimov has been advocating.  But I 
can't get it to compile with either GCC 3.0.1 or VC++7.0b2. See code below.
GCC says:
policy_ptr.cpp: In instantiation of `default_checking<int, policy_ptr<int, 
default_checking, default_storage> >':
policy_ptr.cpp:37:   instantiated from `policy_ptr<int, default_checking, 
default_storage>'
policy_ptr.cpp:37:   instantiated from here
policy_ptr.cpp:34: no type named `storage_policy' in `class policy_ptr<int, 
    default_checking, default_storage>'
line 34 is the line that reads:   void check( 
typename   SmartPtr::storage_policy::pointer_type p ) const
Any ideas?
--Beman
// try Andrei's and Peter's ideas
#include <cassert>
template < class T,
            template < class, class > class Checking,
            template < class, class > class Storage
          >
class policy_ptr
   : public Checking< T, policy_ptr< T, Checking, Storage > >,
     public Storage< T, policy_ptr< T, Checking, Storage > >
{
public:
   typedef Checking< T, policy_ptr<T, Checking, Storage> > checking_policy;
   typedef Storage< T, policy_ptr<T, Checking, Storage> > storage_policy;
};
template < class T, class SmartPtr >
class default_storage
{
public:
   typedef T* pointer_type;
   T* get()
     { static_cast<SmartPtr const *>(this)->check( pointee_ ); return 
pointee_; }
private:
   T* pointee_;
};
template < class T, class SmartPtr >
class default_checking
{
public:
   void check( typename SmartPtr::storage_policy::pointer_type p ) const
     { assert( p ); }
};
policy_ptr< int, default_checking, default_storage > my_ptr;