bool equals(const ObjectData* obj1, const ObjectData* obj2) { assertx(isValidCollection(obj1->collectionType())); if (!obj2->isCollection()) return false; auto ct1 = obj1->collectionType(); auto ct2 = obj2->collectionType(); // we intentionally allow mutable/immutable versions of the same collection // type to compare equal if (isMapCollection(ct1)) { return isMapCollection(ct2) && BaseMap::Equals(obj1, obj2); } else if (isVectorCollection(ct1)) { return isVectorCollection(ct2) && BaseVector::Equals(obj1, obj2); } else if (isSetCollection(ct1)) { return isSetCollection(ct2) && BaseSet::Equals(obj1, obj2); } else { assertx(ct1 == CollectionType::Pair); return (ct2 == CollectionType::Pair) && c_Pair::Equals(obj1, obj2); } }
Object c_AwaitAllWaitHandle::ti_frommap(const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isMapCollection(obj->collectionType()))) { assertx(collections::isType(obj->getVMClass(), CollectionType::Map, CollectionType::ImmMap)); return FromMap(static_cast<BaseMap*>(obj)); } } failMap(); }
Object c_AwaitAllWaitHandle::ti_frommap(const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isMapCollection(obj->collectionType()))) { assert(obj->instanceof(c_Map::classof()) || obj->instanceof(c_ImmMap::classof())); return FromMap(static_cast<BaseMap*>(obj)); } } failMap(); }
Object HHVM_STATIC_METHOD(AwaitAllWaitHandle, fromMap, const Variant& dependencies) { if (LIKELY(dependencies.isObject())) { auto obj = dependencies.getObjectData(); if (LIKELY(obj->isCollection() && isMapCollection(obj->collectionType()))) { assertx(collections::isType(obj->getVMClass(), CollectionType::Map, CollectionType::ImmMap)); return c_AwaitAllWaitHandle::Create<false>([=](auto fn) { MixedArray::IterateV(static_cast<BaseMap*>(obj)->arrayData(), fn); }); } } failMap(); }
bool equals(const ObjectData* obj1, const ObjectData* obj2) { assertx(isValidCollection(obj1->collectionType())); if (!obj2->isCollection()) return false; auto ct1 = obj1->collectionType(); auto ct2 = obj2->collectionType(); if (isMapCollection(ct1) && isMapCollection(ct2)) { // For migration purposes, distinct Map types should compare equal return BaseMap::Equals( BaseMap::EqualityFlavor::OrderIrrelevant, obj1, obj2); } if (isVectorCollection(ct1) && isVectorCollection(ct2)) { return BaseVector::Equals(obj1, obj2); } if (isSetCollection(ct1) && isSetCollection(ct2)) { return BaseSet::Equals(obj1, obj2); } if (ct1 != ct2) return false; assert(ct1 == CollectionType::Pair); return c_Pair::Equals(obj1, obj2); }
ALWAYS_INLINE typename std::enable_if< std::is_base_of<BaseMap, TMap>::value, Object>::type BaseMap::php_differenceByKey(const Variant& it) { if (!it.isObject()) { SystemLib::throwInvalidArgumentExceptionObject( "Parameter it must be an instance of Iterable"); } ObjectData* obj = it.getObjectData(); TMap* target = BaseMap::Clone<TMap>(this); auto ret = Object::attach(target); if (obj->isCollection()) { if (isMapCollection(obj->collectionType())) { auto map = static_cast<BaseMap*>(obj); auto* eLimit = map->elmLimit(); for (auto* e = map->firstElm(); e != eLimit; e = nextElm(e, eLimit)) { if (e->hasIntKey()) { target->remove((int64_t)e->ikey); } else { assert(e->hasStrKey()); target->remove(e->skey); } } return ret; } } for (ArrayIter iter(obj); iter; ++iter) { Variant k = iter.first(); if (k.isInteger()) { target->remove(k.toInt64()); } else { assert(k.isString()); target->remove(k.getStringData()); } } return ret; }