Boost logo

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
> [...]
> 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
> 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 <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;

        template <typename T>
        class impl : public
            at<3, policies>::type<
            at<2, policies>::type<
            at<1, policies>::type<
            at<0, policies>::type<
> > > >

    template <typename T, class Policy = policy_builder<>::impl<T> >
    class smart_ptr : public Policy


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.


P.S. I guess I did need a little MI after all, huh? :(

Boost list run by bdawes at, gregod at, cpdaniel at, john at