Repository: nlohmann/json
File: include/nlohmann/json.hpp (C++)

Code before:

    @since version 1.0.0
    */
    void push_back(basic_json&& val)
    {
        // push_back only works for null objects or arrays
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
        {
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
        }

        // transform null object into an array
        if (is_null())
        {
            m_type = value_t::array;
            m_value = value_t::array;
            assert_invariant();
        }

        // add element to array (move semantics)
        const auto capacity = m_value.array->capacity();
        m_value.array->push_back(std::move(val));
        if (capacity == m_value.array->capacity())
        {
            // capacity has not changed: updating parent of last element is sufficient
            set_parent(m_value.array->back());
        }
        else
        {
            // capacity has changed: update all elements' parents
            set_parents();
        }
        // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
    }

    /*!
    @brief add an object to an array
    @copydoc push_back(basic_json&&)
    */
    reference operator+=(basic_json&& val)
    {
        push_back(std::move(val));
        return *this;
    }

    /*!
    @brief add an object to an array
    @copydoc push_back(basic_json&&)
    */
    void push_back(const basic_json& val)
    {

Review comment (refactor):
Is this code in enough places that it makes sense to have a helper here?
One thought I had was adding an `old_capacity` parameter with a `-1` default to `set_parent` and have it fall back to `set_parents()` if the capacity was specified and changed.  That would allow you to continue using the return value of `set_parent`.
Not sure if that is cleaner or not.

Code after:
    function is called on a JSON null value, an empty array is created before
    appending @a val.

    @param[in] val the value to add to the JSON array

    @throw type_error.308 when called on a type other than JSON array or
    null; example: `"cannot use push_back() with number"`

    @complexity Amortized constant.

    @liveexample{The example shows how `push_back()` and `+=` can be used to
    add elements to a JSON array. Note how the `null` value was silently
    converted to a JSON array.,push_back}

    @since version 1.0.0
    */
    void push_back(basic_json&& val)
    {
        // push_back only works for null objects or arrays
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
        {
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
        }

        // transform null object into an array
        if (is_null())
        {
            m_type = value_t::array;
            m_value = value_t::array;
            assert_invariant();
        }

        // add element to array (move semantics)
        const auto old_capacity = m_value.array->capacity();
        m_value.array->push_back(std::move(val));
        set_parent(m_value.array->back(), old_capacity);
        // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
    }

    /*!
    @brief add an object to an array
    @copydoc push_back(basic_json&&)
    */
    reference operator+=(basic_json&& val)
    {
        push_back(std::move(val));
        return *this;
    }

    /*!
    @brief add an object to an array