|
Boost : |
From: David B. Held (dheld_at_[hidden])
Date: 2002-04-30 18:48:56
By "vertical" I mean linear chained policies, whilst "lateral" means MI, of
course. I see strengths and weaknesses for both, and I just wanted to
mention some of them, to help people decide whether there is a clear
advantage to one or the other.
Obviously, lateral policies prevent direct inter-policy communication
("IPC", not to be confused with inter-process communication ;). A
place where I noticed this in particular was the fact that the Storage
policy of loki::smart_ptr could not access the Checking policy to perform
additional checking. So, to provide this type of checking, the method
would have to moved to the main smart_ptr.
Vertical policies facilitate IPC, but at a cost, depending on the
architecture. For instance, Beman made a tradeoff between straight
vertical and straight horizontal policy design (diagonal policies?). On the
one hand, it simplified the design. On the other hand, it fixed which
policies could see each other. If you know what potential policy
interactions are most likely, this could be a good thing. Otherwise,
it might only provide marginal benefit over full horizontal policy chaining.
The cost I noticed in vertical chaining is the presence of constructors.
All policies in the chain must provide the same set of c'tor signatures.
This is a bit annoying, as many of them don't use, say, the T* c'tor,
but they must provide it anyway.
Another issue with vertical policies is that of default policies. I chose
the full vertical route both to provide a wider range of implementations
for people to look at, and also to help test the idea of complete
control over policy implementations by not limiting policy order.
This, of course, makes it impossible to specify partial policy defaults.
Specifying individual defaults relies on template parameter position,
but if any policy could end up in any position, you can't specify a
position-dependent default. So you are left with an all-or-nothing
policy parameter. The only alternative I see to this is a policy mixer
that detects missing policies, and provides defaults. This is hardly
a five-minute library design job. But I do believe it is entirely possible,
and I sketched an outline of how I think one could work in a different
thread. The nice thing about a policy mixer is that not only can you
specify an incomplete policy list, you can do so in any order. So you
are not limited to specifying an incomplete list only when the specific
policies are at the front. This would address a concern in another
thread that a smart_resource might often specify the Storage policy
without touching the rest.
Another consideration is that of "component-wise addressing".
When Andrei described a fix for a main smart_ptr method, it involved
reinitializing the Ownership policy directly, like so:
Ownership& op = *this;
op = Ownership();
This was possible because you knew which policy *was* the
ownership policy. In a random-order vertical policy, it is highly
non-trivial to detect *where* the ownership policy is. Even if one
could find it, the vertical chaining would likely prevent the type of
solution suggested. One does not know just what policies the
Ownership policy has inherited from, and it may be undesirable to
initialize those polices as well. To this extent, vertical design still
allows you to build objects out of policy components, but those
components more or less lose their identity once they reach their
final destination (as is accented by the fact that all policy references
are changed from ownership::foo(), checking::bar() to policy::foo(),
policy::bar()). Whether that is a serious concern remains to be
seen.
A minor detail is that the vertical policy imlementation looks a lot
cleaner in the actual smart_ptr code, but looks messier in the policy
code. I'm sure this is to be expected. Also, the vertical policy has
the expected minimal size due to EBO.
While I still prefer the lateral approach, it is mainly because you
can at least specify a partial policy list *some* of the time. If a
policy mixer could be designed, I might prefer the vertical approach.
They both have tradeoffs that probably need some more investigation.
Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk