[prev in list] [next in list] [prev in thread] [next in thread] 

List:       boost
Subject:    Re: [boost] [pimpl] Proposal. Determining interest.
From:       Marc Mutz <marc () kdab ! net>
Date:       2007-11-06 17:18:52
Message-ID: 200711061818.54220.marc () kdab ! net
[Download RAW message or body]

On Saturday November 3 2007 07:55, Vladimir Batov wrote:
> Marc,
>
> Just uploaded v0.6 which supports building of two separate class
> hierarchies -- separately for interfaces and for implementations as
> described in GoF Pattern Bible for the Bridge pattern.
>
> The interface hierarchy is built as
>
> struct Base : public pimpl<Base>::pointer_semantics {...};
>
> struct Derived : public Base {...}
>
>  etc.
>
> The implementation hierarchy is still hidden and is built as
>
> template<> struct pimpl<Base>::implementation {...};
>
> template<> struct pimpl<Derived>::implementation : public
> pimpl<Base>::implementation {...};
>
> etc.
>
> Marc, let me know if that looks right for your purpose as I myself have no
> use for deep inheritance trees to test them out.
<snip>

I've been more thinking about the attached scenario. I'm not sure it's worth 
it, since the savings don't seem to be large compared to hand-written code, 
and the need to spell out the forwarding Base(implementation*) is a bit ugly 
(maybe that can be solved in C++0x?), but that should give you the idea. 
Maybe someone better at template magic than I am can coerce this into a 
workable thing. The need for verboseness in referring to 
pimpl<Class>::implementation strikes me as a likely candidate for 
improvement, e.g.

Thanks,
Marc

-- 
Marc Mutz - marc@kdab.com, mutz@kde.org - Klarälvdalens Datakonsult AB
Platform-independent software solutions - www.kdab.com info@kdab.com

["pimpl.cpp" (text/x-c++src)]

#include <boost/shared_ptr.hpp>

template <typename T_Class>
struct pimpl {

    class implementation;

    struct polymorphic_base {

    protected:
        explicit polymorphic_base( typename pimpl::implementation * i ) : _impl( i ) \
{}

        typename pimpl::implementation * impl() { return _impl.get(); }
        const typename pimpl::implementation * impl() const { return _impl.get(); }
    private:
        boost::shared_ptr<typename pimpl::implementation> _impl; 
    };

    template <typename T_Base>
    struct derived_from : T_Base {
        typedef T_Base base;
    protected:
        explicit derived_from( typename pimpl::implementation * i )
            : base( (typename pimpl<base>::implementation*)i ) {}
        typename pimpl::implementation * impl() {
            return (typename pimpl::implementation*)T_Base::impl();
        }
        const typename pimpl::implementation * impl() const {
            return (const typename pimpl::implementation*)T_Base::impl();
        }
    };

};

class Base : protected pimpl<Base>::polymorphic_base {
    typedef pimpl<Base>::polymorphic_base base;
public:
    Base();

    void f();
    void f() const;

protected:
    explicit Base( pimpl<Base>::implementation * i ) : base( i ) {}
};

class Derived : public pimpl<Derived>::derived_from<Base> {
    typedef pimpl<Derived>::derived_from<Base> base;
public:
    Derived();

    void g();
    void g() const;
};

template <>
class pimpl<Base>::implementation {

};

Base::Base() : base( new pimpl<Base>::implementation ) {}

void Base::f() {
    pimpl<Base>::implementation * i = impl();
    //implementation * ii = impl(); // Error: 'implementation' undefined???
}

void Base::f() const {
    const pimpl<Base>::implementation * ci = impl();
    //pimpl<Base>::implementation * i = impl(); // Error: can't convert 'const \
implementation*' -> 'implementation*': Good. }

template <>
class pimpl<Derived>::implementation : pimpl<Base>::implementation {

};

Derived::Derived() : base( new pimpl<Derived>::implementation ) {}

void Derived::g() {
    pimpl<Derived>::implementation * i = impl();
    //implementation * ii = impl(); // Error: 'implementation' undefined??
}

void Derived::g() const {
    const pimpl<Derived>::implementation * ci = impl();
    //pimpl<Derived>::implementation * i = impl(); // Error: can't convert 'const \
implementation*' -> 'implementation*': Good. }

int main() {

    Base b;
    Derived d;

    const Base cb;
    const Derived cd;

    b.f();
    cb.f();

    d.f();
    cd.f();

    d.g();
    cd.g();

    return 0;
}



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic