$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: David B. Held (dheld_at_[hidden])
Date: 2002-05-01 23:42:15
"David Abrahams" <david.abrahams_at_[hidden]> wrote in message
news:07a601c1f0c9$09d3c210$6401a8c0_at_boostconsulting.com...
>
> From: "David B. Held" <dheld_at_[hidden]>
>
> > "David Abrahams" <david.abrahams_at_[hidden]> wrote in message
> > > From: "David B. Held" <dheld_at_[hidden]>
> > > > 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.
> > >
> > > It doesn't have to. You /can/ leave the ordering up to the user. I
> > > have in mind a "construction kit" where you configure new smart
> > > pointers like this:
> >
> > I must be dense, because I don't see how this is at all similar to
> > Beman's design
>
> Don't see why that makes you dense. I never claimed it was like
> Beman's design.
I misread you as saying that with Beman's design, you can leave the
ordering up to the user. I see that you were simply saying that with
full vertical policy chaining, you can have any order. I assumed that
was one of the reasons one would choose vertical chaining.
> > [...]
> > It looks pretty interesting. I still have a hard time getting my head
> > around the idea of something inheriting from itself.
>
> Nothing can do that in C++.
Well, not directly. ;)
> This is just the straightforward "curiously recursive template" pattern,
> as employed (for example) by the operators library.
Whenever I see people mention it, they seem to call it the "curiously
recurring template pattern", from which I gathered that it pops up in
unusual circumstances. But I can see that "recurrent" is also a
mathematical term for "recursive", and so the term is a bit
ambiguous. When you pointed out that it's a *recursive* pattern,
it all made sense. I don't even want to think about what a compiler
has to do to make that work. :(
> [...]
> If there were base policies which didn't need access to the pointer,
> they could have a default constructor. Maybe the policies don't hold
> the pointer at all, but get passed the entire smart_ptr<> object for
> each operation and extract the pointer explicitly.
Ok. But when you delegate storage to a policy (a la Loki::SmartPtr),
it seems that you have to have extra c'tors in every policy, right?
> > In mine as well, unless smart_ptr were made to work with, say,
> > shared_ptr, and you started adding all these conversion c'tors
> > that started cluttering up the policies considerably.
>
> You don't put those in the policies. They just live in the outer class.
I see. I was confused by the fact that you pass a raw pointer to
policy classes. But with a conversion c'tor, you could just take out
the raw pointer, and pass that down.
> [...]
> > It seems to me that a policy adaptor is a fairly generic idea.
> > Have you considered generalizing it, and making it standalone,
> > so other policy-based designs can take advantage of it?
>
> It's already as general as it can get: it's a design pattern. Anything
> can take advantage of it. Trying to write a generalized policy adaptor
> in code could only make it less general.
True. But writing anything in code makes it less general. ;) However,
it seems to me that MPL lets us write something fairly cool. I.e.:
namespace detail
{
class no_policy_tag;
template <typename T>
class no_policy
{
typedef no_policy_tag policy_tag;
};
class no_defaults
{
typedef no_policy_tag default_tag_1;
typedef no_policy_tag default_tag_2;
typedef no_policy_tag default_tag_3;
typedef no_policy_tag default_tag_4;
template <class>
class default_policy_1;
template <class>
class default_policy_2;
template <class>
class default_policy_3;
template <class>
class default_policy_4;
};
} // namespace detail
template
<
template <class> class Policy1 = detail::no_policy,
template <class> class Policy2 = detail::no_policy,
template <class> class Policy3 = detail::no_policy,
template <class> class Policy4 = detail::no_policy,
template <class> class Defaults = detail::no_defaults
>
class policy_adaptor
{
// MPL pseudo-code
mpl::typelist policies<Policy1, Policy2, Policy3, Policy4>;
typedef typename mpl::find_if<policies,
is_same<
typename _1::policy_tag,
typename Defaults::default_tag_1
>::type
>::type iter1;
typedef typename ct_if<
is_same<iter1, mpl::end<policies>::type>,
typename Defaults::default_policy_1, Policy1
>::type policy_1;
typedef typename mpl::find_if<policies,
is_same<
typename _1::policy_tag,
typename Defaults::default_tag_2
>::type
>::type iter2;
typedef typename ct_if<
is_same<iter2, mpl::end<policies>::type>,
typename Defaults::default_policy_2, Policy2
>::type policy_2;
typedef typename mpl::find_if<policies,
is_same<
typename _1::policy_tag,
typename Defaults::default_tag_3
>::type
>::type iter3;
typedef typename ct_if<
is_same<iter3, mpl::end<policies>::type>,
typename Defaults::default_policy_3, Policy3
>::type policy_3;
typedef typename mpl::find_if<policies,
is_same<
typename _1::policy_tag,
typename Defaults::default_tag_4
>::type
>::type iter4;
typedef typename ct_if<
is_same<iter4, mpl::end<policies>::type>,
typename Defaults::default_policy_4, Policy4
>::type policy_4;
public:
template <typename T>
class vertical
: public policy_4<policy_3<policy_2<policy_1<T> > > > >
{ };
template <typename T>
class lateral
: public policy_1<T>
, public policy_2<T>
, public policy_3<T>
, public policy_4<T>
{ };
template <typename T>
class opt_lateral
: public OptionalInherit<
OptionalInherit<policy_1<T>, policy_2<T> >,
OptionalInherit<policy_3<T>, policy_4<T> >,
>
{ };
}
Usage:
So this doesn't preserve the order of policy specification, but I'm
sure that could be accomodated if necessary. And clearly, boost::
preprocessor could be used to scale it. Surely it's not as general
as the Policy Adaptor concept; but if it fits a wide range of uses,
then it has to be as useful as any other library, no?