typename std::enable_if< std::is_base_of<BaseSet, TSet>::value, Object>::type BaseSet::php_takeWhile(const Variant& fn) { CallCtx ctx; vm_decode_function(fn, nullptr, false, ctx); if (!ctx.func) { SystemLib::throwInvalidArgumentExceptionObject( "Parameter must be a valid callback"); } auto set = req::make<TSet>(); if (!m_size) return Object(std::move(set)); set->mutate(); int32_t version UNUSED; if (std::is_same<c_Set, TSet>::value) { version = m_version; } uint32_t used = posLimit(); for (uint32_t i = 0; i < used; ++i) { if (isTombstone(i)) continue; Elm* e = &data()[i]; bool b = invokeAndCastToBool(ctx, 1, &e->data); if (std::is_same<c_Set, TSet>::value) { if (UNLIKELY(version != m_version)) { throw_collection_modified(); } } if (!b) break; e = &data()[i]; if (e->hasIntKey()) { set->addRaw(e->data.m_data.num); } else { assert(e->hasStrKey()); set->addRaw(e->data.m_data.pstr); } } return Object(std::move(set)); }
/** * postSort() runs after the sort has been performed. For HphpArray, postSort() * handles rebuilding the hash. Also, if resetKeys is true, postSort() will * renumber the keys 0 thru n-1. */ void HphpArray::postSort(bool resetKeys) { ASSERT(m_size > 0); size_t tableSize = computeTableSize(m_tableMask); initHash(m_hash, tableSize); m_hLoad = 0; if (resetKeys) { for (ElmInd pos = 0; pos <= m_lastE; ++pos) { Elm* e = &m_data[pos]; if (e->hasStrKey() && e->key->decRefCount() == 0) { e->key->release(); } e->setIntKey(pos); m_hash[pos] = pos; } m_nextKI = m_size; } else { for (ElmInd pos = 0; pos <= m_lastE; ++pos) { Elm* e = &m_data[pos]; ElmInd* ei = findForNewInsert(e->hasIntKey() ? e->ikey : e->hash); *ei = pos; } } m_hLoad = m_size; }
/** * postSort() runs after the sort has been performed. For HphpArray, postSort() * handles rebuilding the hash. Also, if resetKeys is true, postSort() will * renumber the keys 0 thru n-1. */ void HphpArray::postSort(bool resetKeys) { assert(m_size > 0); size_t tableSize = computeTableSize(m_tableMask); initHash(m_hash, tableSize); m_hLoad = 0; if (resetKeys) { for (uint32_t pos = 0; pos < m_used; ++pos) { Elm* e = &m_data[pos]; if (e->hasStrKey()) decRefStr(e->key); e->setIntKey(pos); m_hash[pos] = pos; } m_nextKI = m_size; } else { for (uint32_t pos = 0; pos < m_used; ++pos) { Elm* e = &m_data[pos]; ElmInd* ei = findForNewInsert(e->hasIntKey() ? e->ikey : e->hash()); *ei = pos; } } m_hLoad = m_size; }