ScopedPointer<>, SharedObjectPtr<> needs a DeletePolicy template argument


#1

I'm creating wrapped completion handlers using custom memory allocators ([url=http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/asio_handler_allocate.html]boost::asio::asio_handler_allocate[/url] for example)

 

I want to keep them in a ScopedPointer or ReferenceCountedObjectPt type of container, but there's no way to specify the deletion policy of the underlying object. I'm going to add it to Beast of course. But how would you do it Jules?

Does it go in the [b]ReferenceCountedObject[/b] class itself? Or what?

 

Or do I just override operator delete for my class?

 


#2

I got this working, but it didn’t make sense as a template parameter in SharedObjectPtr. Instead, I made a global class:

/** The DefaultDeletePolicy simply calls operator delete.
*/
template <typename T>
struct ContainerDeletePolicy
{
    static inline void destroy (T* t)
    {
        delete t;
    }
};

Then I went through all the JUCE containers and made them go through ContainerDeletePolicy<>::destroy. The only trick part was ReferenceCountedObject::decReferenceCount, since it doesn’t know the underlying type. So I changed it to this:

    /** Decreases the object's reference count.

        If doDelete is true the object will be deleted when the reference
        count drops to zero. The delete is performed using the regular
        operator and does NOT go through the ContainerDeletePolicy.

        The return value indicates if the reference count dropped to zero,
        so callers who know the derived type can use the ContainerDeletePolicy.
    */
    inline bool decReferenceCount (bool doDelete = true) noexcept
    {
        bassert (getReferenceCount() > 0);
        if (--refCount == 0)
        {
            if (doDelete)
                delete this;
            return true;
        }
        return false;
    }

Then I made ReferenceCountedObjectPtr check the return value and call ContainerDeletePolicy<>::delete when the count drops to zero.


#3

Good idea, and I'd been meaning to add something like this.


#4

I’m a little confused why it was necessary to add all the friend declarations, like:

friend struct ContainerDeletePolicy<ThreadPoolThread>;

What was the point of that? Mine compiles fine without it…did I miss something?


#5

Jules WTF!! You made everything use the ContainerDeletePolicy except ReferenceCountedObjectPtr which was the whole point!!!


#6

This was my solution:

beast::SharedObject

Note return value and parameters to SharedObject::decReferenceCount


#7

For old MS compilers, unfortunately.


#8

FYI I've added something similar to this now. I thought it was best to use two separate decrement methods to avoid that bool parameter, because this is a very performance-sensitive method, and I don't quite trust the compiler to optimise-away the 'if' statement in all cases.


#9

Excellent point, and great looking, clean, well written code as usual. Thanks.


#10

Jules check out this GREAT article:

http://www.boost.org/community/counted_body.html


#11

Jules if you have templated copy construction and copy assignment in RefCountedObjectPtr then do you still need the non-templated copy constructor and copy assignments? Seems to be redundant.