Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2002-01-04 14:10:42


At 08:20 AM 1/4/2002, Peter Dimov wrote:

>> Czarnecki and Eisenecker in Generative Programming
>> (http://www.generative-programming.org/) deal with the issue by using a
>> nested inheritance hierarchy (see page 612 for example). So the form
>might
>> be something like this:
>>
>> template <
>> typename T,
>> template <class> class OwnershipPolicy,
>> template <class> class ConversionPolicy,
>> template <class> class CheckingPolicy,
>> template <class> class StoragePolicy >
>> class SmartPtr
>> : public ConversionPolicy <
>> typename OwnershipPolicy <
>> typename CheckingPolicy <
>> typename StoragePolicy<T> > > >
>> { ...
>
>This kind of hierarchy has its benefits. On MSVC 7b2, this E:
>
>struct A {};
>struct B {};
>struct C {};
>struct D { void * p; };
>struct E: A, B, C, D {};
>
>has a size of 8, whereas this E:
>
>struct A {};
>struct B: A {};
>struct C: B {};
>struct D: C { void * p; };
>struct E: D {};
>
>has a size of 4.
>
>But it's not a general solution to the policy communication problem.

Agreed.

>I don't see how StoragePolicy<T> can access ConversionPolicy<> in the
>above example.

I don't think it can, either. Thus ConversionPolicy<> has to handle
anything that needs access to both policies. That limits flexibility.

>An alternative is to use the Coplien/Barton-Nackman idiom and pass the
>SmartPtr to each policy:

Yes. C&E do that (or a variation on the theme) a lot too. It provides
maximum inter-policy communications flexibility.

Regardless of the exact technique used, I don't see how we can use the Loki
SmartPtr as the base (or typedef template when that becomes available) for
the Boost smart pointers without doing something to increase inter-policy
communication. Trying to do so via the derived framework class can't cope
with the interface variations AFAICS.

>The other fundamental problem - that some policy combinations are
>nonsensical (array_access with intrusive_storage) - has three major
>solutions:
>
>1. Do nothing.

I don't think that's acceptable.

>2. Compile-time assertions in the parent class.

I was assuming the first class (policy or otherwise) in the hierarchy that
has enough information should make the compile-time assertion.

>3. A generator class that makes it impossible to get at the nonsensical
>combinations.

I've though about that too. Perhaps something like this:

template<
  class T,
  template<class, class> class StoragePolicy,
  template<class, class> class CheckingPolicy,
  template<class, class> class AccessPolicy,
  template<class, class> class ConfigurationPolicy
// ^^^^^^^^^^^^^^^^^^^
>
class smart_ptr:

  public StoragePolicy<T, smart_ptr<T, StoragePolicy, CheckingPolicy,
AccessPolicy> >,
  public CheckingPolicy<T, smart_ptr<T, StoragePolicy, CheckingPolicy,
AccessPolicy> >,
  public AccessPolicy<T, smart_ptr<T, StoragePolicy, CheckingPolicy,
AccessPolicy> >
  public ConfigurationPolicy<T, smart_ptr<T, StoragePolicy, CheckingPolicy,
AccessPolicy> >::type
// ^^^^^^
{
};

Notice that ConfigurationPolicy supplies a generator, rather than directly
supplying the finished type. That would make it easy to apply full
compile_time generator techniques to the configuration analysis.

The same generator indirection could be applied to the other policies
too. That yields even more flexibility. I don't know if it is needed,
however.

--Beman


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk