Suggestion: Component::begin() ::end()

Component::begin() end() for standard C++ iteration through child-components

2 Likes

It’s tempting, but I’ve resisted it because it seems like that are only a small number of contexts where this’d be useful, and it may lure people into doing silly things, e.g. if you delete, remove or change the z-order of any child components in the middle of the loop, bad things will happen…

…just a note on this: I searched the entire juce codebase with a regex to look for any for loops that iterate a component’s children in the natural oder, and only found about 10 places where this happens.

Edit: @lalala has a much better suggestion for JUCE 5 users

Below is a snippet that will allow you to for (auto c : ChildComponents (component)).
I’d also like for something like this to exist in JUCE (and this snippet can be used freely and added there etc!)

class ChildComponents
{
public:
    class Iterator;

    ChildComponents (Component& c)
        : component_ (c)
    {
    }

    Iterator begin();
    Iterator end();

private:
    Component& component_;
};

class ChildComponents::Iterator
{
    friend class ChildComponents;

public:
    typedef Component value_type;

    Iterator& operator++()
    {
        ++index_;
        return *this;
    }

    value_type* operator->() const
    {
        return component_.getChildComponent (index_);
    }

    value_type& operator*() const
    {
        return *operator->();
    }

    bool operator!= (const Iterator& other)
    {
        return
            &other.component_ != &component_ ||
            other.index_ != index_;
    }

private:
    Iterator (Component& c, int i)
        : component_ (c), index_ (i)
    {
    }

    Component& component_;
    int index_;
};

inline ChildComponents::Iterator ChildComponents::begin()
{
    return Iterator (component_, 0);
}

inline ChildComponents::Iterator ChildComponents::end()
{
    return Iterator (component_, component_.getNumChildComponents());
}
1 Like

note that you can already do the following:

for (auto* child : getChildren())
{
}
8 Likes