|
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