auto_ptr-like class for R classes

A long time ago in a galaxy far far away^W^W^W^W^W^W^W^W^W
In the Epoc R5 times Sander van der Wal wrote an auto_ptr implementation
for Epoc/Symbian, updated it later for R6 and wrote a whitepaper
(http://www.symbian.com/developer/techlib/papers/auto_ptr/auto_ptr.pdf).

Sander's auto_ptr transparently uses the cleanup stack to provide STL
auto_ptr semantics (except that you can't really return them from
functions), but has a shortcoming: it's not very easy to use
together with manual use of the cleanup stack, which is necessary
for (locally allocated) R classes. E.g.:

void FooL()
{
    RBar r;
    r.Connect();
    CleanupClosePushL(r);
    auto_ptr<CBaz> b(CBaz::NewL(r));
    ???
}

In '???' we should Pop(AndDestroy) the r from the cleanupstack, but
doing a Pop will pop the auto_ptr. We can enclose the auto_ptr
in another block to get it popped off first, but that means having
to pay a lot more attention to how they are used.  Especially with
several sequentially allocated C and R classes this becomes painful
and adds nestings that have nothing to do with the code flow (although
they of course do relate to resource allocation flow).

To alleviate this, I propose to use a similar construct for R classes
as well. It cannot, however, be a separate class like auto_ptr, since
R classes cannot be copied around like pointers can. Instead we need
to make a derived class for each R class which handles the cleanupstack.
The use looks like

void FooL()
{
    // note the 'A' for automatic
    RABar r; r.ConnectLA();
    auto_ptr<CBaz> b(CBaz::NewL(r));
    ...
}

We have been using something like this for half a year now,
with good results. You still need two statements for initialization,
but once the idiom becomes frequent, they will always come together.

The actual derived classes cannot be templatized, since different R
classes have different Open methods (Connect, Replace etc.), but
they can easily be generated with a script. The implementation
looks like (complete code with the generation script can
be found at http://db.cs.helsinki.fi/~mraento/lxr/source/ContextCommon/
(raii*, inc/raii*, src/raii*):

class RABase {
protected:
        RABase() : iOpen(EFalse), iOnStack(EFalse) { }
        virtual ~RABase() {
                if (iOnStack)
                        CleanupStack::Pop();
        }
        TBool iOpen, iOnStack;
    /*
     * use a static function that is called
     * from the CloseRABase, so that only
     * one close function is needed, not one
     * per derived class
     */
        static void CloseRABase(TAny* p) {
                RABase* b=(RABase*) p;
                b->CloseRA();
        }
        void PutOnStackL() {
                if (!iOnStack) {
                        iOnStack=ETrue;
                        CleanupStack::PushL(TCleanupItem(&CloseRABase,
                (TAny*)this));
                }
        }
        virtual void CloseInner() = 0;
        friend void CloseRABase(TAny* p);

public:
        void CloseRA() {
                if (iOpen) {
                        CloseInner(); iOpen=EFalse;
                }
        }
        TBool IsOpen() const { return iOpen; }
};

class RAWsSession : public RWsSession, public RABase {
public:
        inline void ConnectLA() {
                RABase::CloseRA();
                User::LeaveIfError(Connect());
                iOpen=ETrue;
                PutOnStackL();
        }
        ~RAWsSession() { RABase::CloseRA(); }
        void CloseInner() { RWsSession::Close(); }
private:
    // private override so that this cannot
    // be closed through other means than CloseRA()
        void Close() { }
};

You are free to use the technique in your own programs, I'll have
to make a separate release of the actual code under a suitable
license to allow you to use it in non-GPL code, but that can be
done. Any comments are welcome,