Boost logo

Boost :

From: Stephen C. Gilardi (squeegee_at_[hidden])
Date: 2000-01-28 16:16:11


> > > - I set the "unique" pointer values to point to self to avoid null
> > > tests
>>
>> I'm not sure I understand this. Can you elaborate?
>> Would there need to be additional code to check for circular
>> references?
>
>I can't remember the exact reasoning - I'll have to dig out the code on
>Monday - but I think that the overall I found it more efficient to
>initialise the left / right pointers to "this" rather than 0. You're
>right though, certain tests do equate to "if ( left == this )".

I had heard of this before. In the past, it's been represented to me
as a "circular linked list". I was curious about it, so I tried it.

In testing with CodeWarrior, on a PowerMac with full optimizations on
for speed, I found the speed of the "this" version and of the "0"
version to be very comparable.

Here are the timings for 10.0E6 iterations of the loop with boost's
default timer.cpp:

        "this" version: 3.75 sec
        "0" version: 3.78 sec
        shared_ptr: 23.95 sec

The "this" version is a little more compact in source code, but I
think a little harder for someone to understand on first read. The
timing comparisons may well be different with a different mix of
copying, assigning and destroying of the smart pointers.

For what it's worth, I think linked_ptr would be a cool addition to boost.

--Steve

I've enclosed the modified file based on the second version of
linked_ptr.hpp posted recently. Here's the portion of the code that
is changed:

class linked_ptr_base
{
protected:
    linked_ptr_base(void * p) throw() :ptr(p),left(this),right(this) {
}// easy as pie

    void copy(const linked_ptr_base & other) throw () {
       const linked_ptr_base * pNewLeft = &other;
       // we place *this between other and *other.right
       ptr = pNewLeft->ptr;
       sync_lock sl;
       left = pNewLeft;
       right = left->right;
       left->right = this;
       right->left = this;
       //debugcheck();
    }

    linked_ptr_base(const linked_ptr_base & other) throw ()
:ptr(0),left(this),right(this) {
       copy(other);
    }

    void leave_list() throw () {
       if (left != this || right != this)
       {
          sync_lock sl;
          // Take ourselves out of the list
          // and join the left and right neighbors.
          left->right = right;
          right->left = left;
          right = left = this;
       }
       //debugcheck();
    }

// void debugcheck() {
// ASSERT(left && left->right == this); }
// ASSERT(right && right->left == this); }
// }

    bool isunique() const throw () { return left == this && right == this; }
[...]
}


-- 


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