Boost logo

Boost :

From: Miki Jovanovic (miki_at_[hidden])
Date: 2000-03-15 16:02:05


Hi all, hi Mark,

I've been spending some serious time in the linked_ptr and I basically
have two small suggestions:

1) dynamic_cast_from might behave little better is written as below.
What I did not like with the previous version was that if the contained
object destructor threw an exception, the value of the smart pointer
would have beed NULL. Version below would actually do the assignment
correctly, even if the exception was thrown. Also, I there should be a
small performance improvement.

template <class T2>
element_type * dynamic_cast_from(const linked_ptr<T2> & other) {
   if (ptr != other.get()) {// also checks for assignment to self
      element_type *pToDelete = ptr;
      ptr = dynamic_cast<element_type*>(other.get());
      if (ptr) {
         if (leave_list(&other))
            delete pToDelete;
      }
      else if (leave_list(this))
         delete pToDelete;
   }
   return get();
}

2) This second suggestion is way more contraversial. The idea is to
improve slightly the performance of linked_ptr. How slightly? Very
slightly. What I like in the shared_ptr is that the contained object is
actually at the same address as the shared_ptr:

(void*)&ptr == (void*)&ptr.px

This means that accessing the pointer is as cheap as a dumb pointer.

In the linked_ptr, linked base has two members left and right which in
the current setup are physically located before the actual contained
pointer. So the idea would be something like this:

class linked_base {
  protected:
    void *pVoid;
    mutable const linked_base *left;
    mutable const linked_base *right;
};

class linked_ptr : public linked_base {
  protected:
    T* ptr() const { return reinterpret_cast<T*const>( pVoid ); }
    T*& ptr() { return *reinterpret_cast<T**>( &pVoid ); }
};

And from here use ptr() to read and write the pointer. Optimisation
should inline these, and effectively the two accessors would not
execute any instructions. Type checking is kept, because of the return
types of ptr(). And now the actual pointer is at the beginning of the
structure.

As all of you will notice, the performance benefit is quite small.
Method is to say the least 'little confusing'. But if we are pushing
for every millisecond... On the up side, the method is quite contained,
so it will not pollute the rest of the code (much).

Cheers,

Miki.


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