Boost logo

Boost :

From: Philippe A. Bouchard (philippeb_at_[hidden])
Date: 2002-08-07 12:32:04


"David B. Held" <dheld_at_[hidden]> wrote in message
news:airh9q$ecb$1_at_main.gmane.org...
> "Philippe A. Bouchard" <philippeb_at_[hidden]> wrote in message
> news:air9pa$j6j$1_at_main.gmane.org...
> > I've cleaned up the polymorphic ptr<> class:
> > http://groups.yahoo.com/group/boost/files/ptr/
> >
> > - The syntax is similar to SGI's for temporary readability issues.
> > - Lookup tables could be optimized more but are already reasonnable
> > in ressources.
>
> Pardon my ignorance, but where are you using lookup tables?

There is one vector per ptr<T> called s_rectify;

> > - Template friend classes are not well supported under gcc 2.95.4;
> > some internal classes are simply public.
>
> An interesting trick that I've seen in Andrei's code is to do a
> reinterpret_cast to the local type. You don't mind a few extra
> reinterpret_casts, do you? ;) Here's an example of what I mean:
>
> template <typename _U>
> __ptr_base(__ptr_base<_U, __false_type> const & a_p)
> : m_ptr(reinterpret_cast<_T *>(a_p.share()))
> {
> s_rectify.reserve(reinterpret_cast<__ptr_base const&>(a_p).s_id + 1);
> s_rectify[reinterpret_cast<__ptr_base const&>(a_p).s_id] =
> int(static_cast<_T *>((_U *) 1) - offset(1));
> }

Is it faster? I got the habit of not casting to reference types because of
implicit exceptions sometimes.

> > - You can trick ptr<> with has_trivial_destructor for single parent
> > hierarchies; it will optimize speed even if you have virtual destructors
> > but this __true_type hack won't be portable; although some other trait
> > could be officially used instead.
> > [...]
>
> It looks like you're not using the Boost type traits. Is there a reason?

Because I don't know the official trait related to virtual tables yet :) I
wasn't sure.

> Other comments:
>
> Like Dave A. mentioned before, names with a leading underscore
> followed by a capital letter are reserved for the implementation (namely,
> _T). It would probably be best to lose all leading underscores in your
> code.

Noted.

> It seems silly to reuse the struct id for rc and gc. Why not just give
the
> tags and the functions different names? Why do you need the functions
> at all?? You overloaded placement new, but did not write corresponding
> placement delete.

Done. They were renamed rc_type and rc(). Placement delete? This is
already handled by explicit destructor calls.

> I'm wondering if there is a problem with having static data in the header
> when it is included in multiple translation units? For instance, if I use
> ptr<MyPolymorphicType> followed by ptr<MyPolymorphicType2> in
> Translation Unit 1, and I just use ptr<MyPolymorphicType2> in Translation
> Unit 2, what will happen? Can you guarantee that it will work correctly?

It will still work, you just live with redundant lookup tables. But this
problem is the main one with template usages.

> In the copy c'tor, you make a call to vector::reserve and then do an
> assignment into the vector every time. While I realize that
vector::reserve
> will only be expensive when it actually needs to reserve new data, it will
> still involve a conditional branch that doesn't exist in most other
pointer
> implementations. This is noteworthy, because copies could occur quite
> often, especially in something like vector<ptr<T> >. Are you sure your
> pointer is really faster than what's out there? I'm beginning to wonder.

Yes I know, this was my drawback but still can be optimized. Those resizes
can be made globally before main() is called or fragmented into blocks of
10, 50 or 100 enlargments... like pool.

> Finally, you call your pointer "Extensible". In what way is it
extensible?
> With boost::shared_ptr, you can pass a custom deleter, which allows
> you to use it as a type of generic RAII wrapper. That's extensible. With
> the policy-based pointers, you can extend them in all kinds of ways with
> custom policies. In what way can you extend your pointer?

It is more extensible for speed & memory of large containers because the
pointer is of sizeof(int), allocations & deallocations are not done twice
for each object pointed to, less overhead on memory maps and we all know the
that the custom deleter can also be integrated eventually. I'm not a 100%
familiar with the main policies this is why I haven't done it yet.

Philippe A. Bouchard


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