Boost logo

Boost :

From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2002-07-28 20:17:33


> Don't you have an idea of what is going on in the backstage here?!?
Again,
> my main goal is to add 1 integer length when the object is allocated; one
> malloc call not two (for counters); copying is faster when
> sizeof(shared_ptr<type>) == sizeof(type *); no need for policy based
> functions in your class to handle reference counts; works with typenames
> like: int, float, char *, char (*)(), char (* volatile const)(int, float,
> double (*)(int, long, double), char (*) [10][20][30], ...); the integer
> (counter) can be replaced by a virtual table, size_t, etc.; thus is more
> extensible for memory management or dynamic information. It is impossible
> to do so with the current standards or policies easily in an efficient way
> because I _have_ to modify the operator new when objects are allocated,
not
> after. It will be too late for performance gains.

This could be done without modification of operator new (Here I will be
operating terms from my implementation of PBSP).
General idea is to keep counter with the object. Here we have 2 cases:
1. It's your own class. Then you could inherit from something like
counted_base from current shared_ptr. AFAIU it not what you are interested
in, so I skip the solution.
2. You could not modify the class (like in your examples). But you still
could write wrapper class with counter: something like this:

template<typename T>
struct value_container
{
    T value;
};

template<typename T>
struct counted : if_true<T is intrinsic type>::template
then<value_container<T>, T>::type
{
     // you probably need couple templated constructors

      int counter;
};

now we could specialize intrusive_ref_traits like this
template<typename T>
struct intrusive_ref_traits<counted<T> >
{
    BOOST_STATIC_CONSTANT( bool, has_intrusive_reference = true );

    static void first_reference( counted<T>*& p ) { if( p != NULL )
p->counter = 1; }
    static void add_reference( counted<T>*& p ) { if( p != NULL )
++p->counter; }
    static bool release_reference( counted<T>*& p ) { if( p !=
NULL ) --p->counter; return p->counter == 0; }
};

That's it. You could start using shared_ptr like this

typedef counted<YourFancyClass> YourFancyClassEx;
shared_ptr<YourFancyClassEx> = new YourFancyClassEx;
...

For inrisic types you probably would want to specialize plain_pointer
storage policy so you will not need to type .value every time.

Gennadiy.

P.S. It's only a sketch. But I hope you got the idea.


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