[FR] Monadic operators on ValueTree

[promising code to begin with, but bad news ahead]

I built another simple class without the lambdas, which in theory can address all three feature requests at once (daisy-chaining, default undoManager, and or_else).

class SpeedyVT
{
public:
    SpeedyVT(const juce::ValueTree& vt_) : vt(vt_) {}

    SpeedyVT setProp(const juce::Identifier& id, const juce::var& v, juce::UndoManager* um = nullptr)
    {
        if (vt.isValid())
            vt.setProperty(id, v, um);

        return vt;
    }

    SpeedyVT addAndReturnChild(const juce::ValueTree& child, int i = -1, juce::UndoManager* um = nullptr)
    {
        if (vt.isValid())
            vt.addChild(child, i, um);

        return child;
    }

    SpeedyVT or_else(const juce::ValueTree& other) const
    {
        if (vt.isValid())
            return vt;

        else return other;
    }
    // add other methods as desired: getOrCreateChild(), getParent(), etc.

    juce::ValueTree vt;
};

void doSomeSpeedyVT()
{
    auto invalidVT = juce::ValueTree();
        
    auto svt = SpeedyVT(invalidVT)
        .or_else(juce::ValueTree("replacement"))
        .setProp("p", 1)
        .addAndReturnChild(juce::ValueTree("child"))
        .setProp("x", 2);

    DBG(svt.vt.getRoot().toXmlString());
    // <child x="2"/>  !?
}

But then I ran into a problem that I hadn’t anticipated. I expected the above code to print:

<replacement p="1">
    <child x="2"/>
</replacement>

But instead “replacement” is gone and you get:

<child x="2"/>

The problem is that the “replacement” ValueTree goes out of scope when the daisy-chained code ends, and this wipes the parent pointer inside child. This behavior was new to me, but it kind of makes sense that I’d never seen it before, since the existing API doesn’t really allow for a parent ValueTree to go out of scope before a child does. (Maybe that’s why daisy-chaining is disallowed in the first place!)

Note that while I’m working with a wrapper class here, you’d face the same issue if you added these methods to the ValueTree class itself, as far as I can tell.

I’m afraid that this problem puts the breaks on both of @ImJimmi 's ideas (or_else and daisy-chaining). It’s definitely a solvable problem, but not in a simple way.