|
Boost : |
From: David B. Held (dheld_at_[hidden])
Date: 2002-04-29 21:57:46
"Phil Nash" <phil.nash.lists_at_[hidden]> wrote in message
news:007801c1efe5$20b9c7c0$10b387d9_at_TimeMachine...
> [...]
> I think we all are (including Andrea,
Umm...I hope you didn't just misspell "Andrei". ;) I wasn't aware of an
"Andrea" in this thread. ;)
> > > Could the decision as to whether we use a linear inheritance
> > > hierarchy or MI be deferred to yet another policy? (YAP?).
> >
> > Heh, heh. Sure it could. But I think that would defeat the purpose
> > of using MI in the first place.
>
> I'm not so sure it would. It might water it down a little, but whether
that
> is too much is perhaps a matter of interpretation. I am not going to
> defend this suggestion as staunchly as my case with smart_resources,
> but I think there is some merit in it.
In working on the chained policy version, I have decided that a policy
mixer is indeed a good thing, although I'm not convinced that it needs
MI. However, your statement later on about using Typelist is right on,
and I hope that Alexsey or Dave A. will help me understand enough
MPL to implement this mixer idea. I didn't want to let it out of the bag
until I had gotten something working, but at this point, it's clear that I'm
not going to get anything working. ;)
Ok, my idea for a linear chained policy mixer looks like this:
namespace detail
{
template <class Policy>
struct policy_forwarder : public Policy
{
typename false_type storage_policy;
typename false_type ownership_policy;
typename false_type conversion_policy;
typename false_type checking_policy;
virtual ~policy_forwarder() { }
};
struct storage_policy { };
struct ownership_policy { };
struct conversion_policy { };
struct checking_policy { };
}
template <class Policy>
class default_storage : public Policy, storage_policy
{ ... };
template <class Policy>
class assert_check : public Policy, checking_policy
{ ... };
...
template
<
template <typename> class StorageTraits = default_storage_traits
template <class> class Policy1 = detail::policy_forwarder,
template <class> class Policy2 = detail::policy_forwarder,
template <class> class Policy3 = detail::policy_forwarder,
template <class> class Policy4 = detail::policy_forwarder
>
class policy_builder
{
// MPL pseudo-code
typelist p1<Policy1, Policy2, Policy3, Policy4>;
typedef ct_if<
is_same<find<p1, storage_policy>::type, end<p1>::type>,
push_back<p1, default_storage>::type, p1
>::type p2;
typedef ct_if<
is_same<find<p2, ownership_policy>::type, end<p2>::type>,
push_back<p2, ref_counted>::type, p2
>::type p3;
typedef ct_if<
is_same<find<p3, conversion_policy>::type, end<p3>::type>,
push_back<p3, disallow_conversion>::type, p3
>::type p4;
typedef ct_if<
is_same<find<p4, checking_policy>::type, end<p4>::type>,
push_back<p4, assert_check>::type, p4
>::type p5;
typedef erase_if<p5, _1 == detail::policy_forwarder>::type policies;
public:
template <typename T>
class impl : public
at<3, policies>::type<
at<2, policies>::type<
at<1, policies>::type<
at<0, policies>::type<
StorageTraits<T>
> > > >
{
};
}
template <typename T, class Policy = policy_builder<>::impl<T> >
class smart_ptr : public Policy
{
...
};
Usage:
typedef smart_ptr<int,
policy_builder<ref_counted_mt, no_checking>::impl<int>
> my_ptr;
The nice thing is that this works with any class that has a simple
Policy template parameter. You could make it even nicer by
making the Policy parameter a template template param, and
then you wouldn't have to specify T twice. It's also nice because
it works with a traditional hand-built policy chain as well.
Dave
P.S. I guess I did need a little MI after all, huh? :(
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk