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); } }
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); } }