OwnedArray::add() and co. should return the object


#1

Any method for inserting into a container that currently returns void, should instead return a reference to the object:

ObjectClass& OwnedArray<>::add (const ObjectClass* const newObject) noexcept

This way you can do something with the object at the call site for example:

ownedArray.add (new TxFormat) << TxField ("type") << TxField ("account") << TxField ("balance");

#2

For example:

    ObjectClass const& add (ObjectClass const* const newObject) noexcept
    {
        const ScopedLockType lock (getLock());
        data.ensureAllocatedSize (numUsed + 1);
        bassert (data.elements != nullptr);
        data.elements [numUsed++] = const_cast <ObjectClass*> (newObject);
        return *newObject;
    }

    ObjectClass& add (ObjectClass* const newObject) noexcept
    {
        add (const_cast <ObjectClass const*> (newObject));
        return *newObject;
    }

#3

Good request. It’d need to return a pointer though, as you’re allowed to add nullptrs to the array.


#4

Hi Jules,

I see you added this to OwnedArray, could you also add it to ReferenceCountedArray ?

Thanks,

Rail


#5

Can we get this for [i]insert[/i] as well please?

Thanks,

Rail


#6

No problem.


#7

Thanks Jules…

Just one thing… OwnedArray::addIfNotAlreadyThere() should return nullptr if the object isn’t added

    ObjectClass* addIfNotAlreadyThere (ObjectClass* newObject) noexcept
    {
        const ScopedLockType lock (getLock());

        if (! contains (newObject))
            {
            add (newObject);
            return newObject;
            }
    
        return nullptr;
    }

and should we also have an OwnedArray::insertIfNotAlreadyThere()

    ObjectClass* insertIfNotAlreadyThere (int indexToInsertAt, ObjectClass* newObject) noexcept
    {
        const ScopedLockType lock (getLock());
        
        if (! contains (newObject))
            {
            insert (indexToInsertAt, newObject);
            return newObject;
            }
        
        return nullptr;
    }

For completeness, can we have these changes to ReferenceCountedArray as well.

Much appreciated.

Rail


#8

I can't change the behaviour of addIfNotAlreadyThere - if I did, it could break people who wrote stuff that relies on the return value. And I'm not sure if returning null would be the correct thing to do anyway.

Will take a look at ReferenceCountedArray when I get a moment.


#9

Before today we had:

    void addIfNotAlreadyThere (ObjectClass* const newObject) noexcept

so returning a nullptr won’t break any old code…

I do agree though that the return value could go either way… since the returned object pointer would be valid if the object were already in the array…

Thanks,

Rail


#10

The relentless drum of progress beats... std::vector is the standard now and trying to substitute it with a home-brew that doesn't work with <algorithm> and friends is really pointless.

OwnedArray is an anachronism, it makes no sense. Preferable is to simply declare std::vector <std::unique_ptr <T> > or Array <ScopedPointer <T> >

Conflating ownership semantics and container semantics in one class goes against good C++ design.