bool MutableArrayIter::advance() {
    ArrayData *data = m_var ? getData() : m_data;
    if (!data) return false;
    // If the foreach loop's array changed since the previous iteration,
    // we recover by creating a new strong iterator for the new array,
    // starting with at the position indicated by the new array's internal
    // pointer.
    if (m_fp.container != data) {
        // Free the current strong iterator if its valid
        if (m_fp.container != NULL) {
            m_fp.container->freeFullPos(m_fp);
        }
        assert(m_fp.container == NULL);
        // If needed, escalate the array to an array type that can support
        // foreach by reference
        escalateCheck();
        // Trigger COW if needed, copying over strong iterators
        data = cowCheck();
        // Create a new strong iterator for the new array
        data->newFullPos(m_fp);
    } else {
        // Trigger COW if needed, copying over strong iterators
        data = cowCheck();
    }
    assert(m_fp.container == data);
    if (!data->setFullPos(m_fp)) return false;
    CVarRef curr = data->currentRef();
    m_valp->assignRef(curr);
    if (m_key) m_key->assignVal(data->key());
    data->next();
    data->getFullPos(m_fp);
    return true;
}
MutableArrayIter::MutableArrayIter(ArrayData *data, Variant *key,
                                   Variant &val)
    : m_var(NULL), m_data(data), m_key(key), m_valp(&val), m_fp() {
    if (data) {
        escalateCheck();
        data = cowCheck();
        data->reset();
        data->newFullPos(m_fp);
        assert(m_fp.container == data);
    }
}
Beispiel #3
0
MutableArrayIter::MutableArrayIter(const Variant *var, Variant *key,
                                   Variant &val)
  : m_var(var), m_data(NULL), m_key(key), m_val(val), m_fp() {
  ASSERT(m_var);
  escalateCheck();
  ArrayData* data = cowCheck();
  if (data) {
    data->reset();
    data->newFullPos(m_fp);
    ASSERT(m_fp.container == data);
  }
}