void ArrayUtil::Walk(VRefParam input, PFUNC_WALK walk_function, const void *data, bool recursive /* = false */, PointerSet *seen /* = NULL */, CVarRef userdata /* = null_variant */) { assert(walk_function); Variant k; Variant v; for (MutableArrayIter iter = input->begin(&k, v); iter.advance(); ) { if (recursive && v.is(KindOfArray)) { assert(seen); ArrayData *arr = v.getArrayData(); if (v.isReferenced()) { if (seen->find((void*)arr) != seen->end()) { raise_warning("array_walk_recursive(): recursion detected"); return; } seen->insert((void*)arr); } Walk(directRef(v), walk_function, data, recursive, seen, userdata); if (v.isReferenced()) { seen->erase((void*)arr); } } else { walk_function(directRef(v), k, userdata, data); } } }
void ArrayUtil::Walk(VRefParam input, PFUNC_WALK walk_function, const void *data, bool recursive /* = false */, PointerSet *seen /* = NULL */, const Variant& userdata /* = null_variant */) { assert(walk_function); // The Optional is just to avoid copy constructing MArrayIter. folly::Optional<MArrayIter> miter; create_miter_for_walk(miter, input); assert(miter.hasValue()); Variant k; Variant v; while (miter->advance()) { k = miter->key(); v.assignRef(miter->val()); if (recursive && v.is(KindOfArray)) { assert(seen); ArrayData *arr = v.getArrayData(); if (v.isReferenced()) { if (seen->find((void*)arr) != seen->end()) { raise_warning("array_walk_recursive(): recursion detected"); return; } seen->insert((void*)arr); } Walk(directRef(v), walk_function, data, recursive, seen, userdata); if (v.isReferenced()) { seen->erase((void*)arr); } } else { walk_function(directRef(v), k, userdata, data); } } }
Variant f_hphp_get_iterator(CVarRef iterable) { return f_hphp_get_iterator(directRef(iterable), false); }