Boost logo

Boost :

From: David B. Held (dheld_at_[hidden])
Date: 2002-07-17 17:56:19


"Philippe A. Bouchard" <philippeb_at_[hidden]> wrote in message
news:ah4p6i$nba$1_at_main.gmane.org...
> Heu... it's right.
>
> Here are C++ versions using 2 statements.

Hmm...I obviously don't understand exactly how placement new works,
but that's no suprise. ;) Nonetheless, I doubt you will get a loyal
following
of people willing to write two lines to initialize a smart pointer in return
for the minor benefit of having a count wrapper, especially considering
how obscure the lines are. You can reduce it to one line by providing
constructor overloads, like I meant to suggest before, but that is
what takes a lot of work. Maybe Paul Mensonides or someone will help
you write a preprocessor hack to generate the cases.

Also, you should consider instead extracting element_type, calling it
something like count_wrapper<T>, and making it work with
boost::intrusive_ptr instead. Like I've said a few times, squad_ptr is too
similar to intrusive_ptr to justify YASM (yet another smart pointer).

Dave

P.S. Here is more or less what I mean:

template <typename T>
class count_wrapper
{
public:
    typedef T value_type;

    count_wrapper() : m_counter(1)
    { new (m_buffer) value_type(); }

    template <typename P1>
    count_wrapper(P1 const& p1)
    { new (m_buffer) value_type(p1); }

    template <typename P1, typename P2>
    count_wrapper(P1 const& p1, P2 const& p2)
    { new (m_buffer) value_type(p1, p2); }

    // etc., etc.

    ~count_wrapper()
    { reinterpret_cast<value_type*>(m_buffer)->~value_type(); }

    operator value_type&()
    { return *reinterpret_cast<value_type*>(m_buffer); }

    void add_ref(void) { ++m_counter; }

    bool release(void)
    {
        return !--m_counter;
    }

private:
   char m_buffer[sizeof(value_type)];
   long m_counter;
};

template <typename T>
inline void intrusive_ptr_add_ref(count_wrapper<T>* p)
{
    p->add_ref();
}

template <typename T>
inline void intrusive_ptr_release(count_wrapper<T>* p)
{
    if (p->release()) delete p;
}

Of course, you have the ol' problem of combinatorial explosion if you
provide both const& and non-const& forms for each c'tor parameter.
But then you can do:

boost::instrusive_ptr<A> p(new count_wrapper<A>(1, 2, 3));

which is functionally equivalent to:

squad_ptr<A> p(new squad_ptr<A>::element_type);
new (p.get()) A(1, 2, 3);

not to mention much easier to read.


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