Boost logo

Boost :

From: Fernando Cacciola (fcacciola_at_[hidden])
Date: 2001-12-21 12:58:17


----- Original Message -----
From: rogeeff <rogeeff_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, December 21, 2001 2:09 PM
Subject: [boost] Re: BCB5, the pimpl idiom bug and the new Unit Test
Framework

> --- In boost_at_y..., "Fernando Cacciola" <fcacciola_at_g...> wrote:
> >
> > ----- Original Message -----
> > From: Fernando Cacciola <fcacciola_at_g...>
> > To: <boost_at_y...>
> > Sent: Friday, December 21, 2001 12:21 PM
> > Subject: RE: [boost] BCB5, the pimpl idiom bug and the new Unit Test
> > Framework
> >
> >
> > >
> > >
> > > Well, using plain old raw pointers won't be thread safe, but
> safer in any
> > > other respect...
> > > So I think that you are right, by now, better stick to raw
> pointers....
> > >
> >
> > On second thought, this conclusion leads me back to my original
> proposal:
> > use the technique of grin_ptr<> with
> > scoped_ptr<>.
> >
> > It doesn't make sense to change scoped_ptr<> though, but if
> gennadiy adds
> > the following smart ptr to some header (like unit_test_config) as an
> > implementation detail, he doesn't need to use bare pointers and
> this smart
> > ptr being pretty simple shouldn't present any maintenance problems:
> >
> >
> >
> >
> >
> >
> > // ginning_ptr<> is a fusion of boost::scoped_ptr<> and grin_ptr<>
> (*1)
> > //
> > // (*1) Alan Griffith,
> > (http://www.octopull.demon.co.uk/arglib/TheGrin.html)
> > //
> > // ginning_ptr mimics a built-in pointer except that it guarantees
> deletion
> > // of the object pointed to, either on destruction of the
> ginning_ptr or
> > via
> > // an explicit reset(). ginning_ptr is a simple solution for the
> > implementation
> > // of the PIMPL idiom that works with the Borland compiler (unlike
> > scoped_ptr);
> > //
> > // Alan's technique allows the compiler to parse ~ginning_ptr()
> without
> > compiling
> > // delete p ; and therefore without problems if T is an incomplete
> type,
> > // which is the case with the pimpl idiom.
> > // delete p is parsed only when ginning_ptr<> is constructed,
> which in the
> > // case of the pimpl idiom is on the implementation file when T is
> > complete.
> > //
> > // Since ~ginning_ptr() doesn't see (statically) "delete p", this
> smart
> > pointer
> > // allows the pimpl idiom to be safely implemented even for
> Borland C++
> > 5.5.1
> > // (which erroneously parses the pimpl destructor while T is still
> > incomplete)
> > //
> > // NOTE: checked_delete(p) is used instead of delete p to catch the
> > // case where the constructor of the outer handle class is visible
> > // before T is complete
> > // (something that should happen in a pimpl implementation)
> > //
> > template<typename T> class ginning_ptr : noncopyable {
> >
> > T* ptr;
> > typedef void (*do_delete_func) ( T* p ) ;
> > do_delete_func do_delete ;
> > static void do_delete_impl( T* p ) { checked_delete(p) ; }
> >
> > public:
> > typedef T element_type;
> >
> > explicit ginning_ptr( T* p=0 ) : ptr(p) , do_delete
> (do_delete_impl) {} //
> > never throws
> > ~ginning_ptr() { do_delete(ptr); }
> > void reset( T* p=0 ) { if ( ptr != p ) { do_delete(ptr);
> ptr =
> > p; } }
> > T& operator*() const { return *ptr; } // never throws
> > T* operator->() const { return ptr; } // never throws
> > T* get() const { return ptr; } // never throws
> > #ifdef BOOST_SMART_PTR_CONVERSION
> > // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own
> risk!
> > operator T*() const { return ptr; } // never throws
> > #endif
> > }; // ginning_ptr
> >
> >
> > I've received email from Alan Griffith and he said that we have
> permission
> > to use his ideas as long as we don't involve him directly; that is,
> as long
> > as we handle it ourselves.
> > I don't think that the deep copy semantics of grin_ptr<> or
> impl_ptr<> are
> > needed here, only the callback delete, so grinning_ptr<> is very
> simple and
> > easy to maintain.
> >
> > Fernando Cacciola
> > Sierra s.r.l.
> > fcacciola_at_g...
> > www.gosierra.com
>
> How about separate header? I agree te code is pritty simple and I
> should not have a problem to support it. Hopefully after accepting
> loki-style smart_ptr I will be able to exclude it. Could you recheck
> that BCB5 does not have any problems after such change and I
> meanwhile do it.
>
I've put 'grinning_ptr<>' in its own header, in /test/detail.
Changed every occurrence of scoped_ptr<> with it.
Everything compiled OK.
I haven't run the test 'test' though, but my own test suite worked OK.

Note: it should be 'grinning_ptr', not 'ginning_ptr', as I wrote it....

BTW: I uploaded 'grinning_ptr.hpp' to the files section, you can grab it
from there.

Fernando Cacciola
Sierra s.r.l.
fcacciola_at_[hidden]
www.gosierra.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk