#ifndef JSMapIterator_h
#define JSMapIterator_h
#include "JSDestructibleObject.h"
#include "JSMap.h"
#include "MapData.h"
namespace JSC {
enum MapIterationKind : uint32_t {
MapIterateKey,
MapIterateValue,
MapIterateKeyValue,
};
class JSMapIterator : public JSDestructibleObject {
public:
typedef JSDestructibleObject Base;
DECLARE_EXPORT_INFO;
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
static JSMapIterator* create(VM& vm, Structure* structure, JSMap* iteratedObject, MapIterationKind kind)
{
JSMapIterator* instance = new (NotNull, allocateCell<JSMapIterator>(vm.heap)) JSMapIterator(vm, structure, iteratedObject, kind);
instance->finishCreation(vm, iteratedObject);
return instance;
}
bool next(CallFrame* callFrame, JSValue& value)
{
if (!m_iterator.ensureSlot())
return false;
if (m_kind == MapIterateValue)
value = m_iterator.value();
else if (m_kind == MapIterateKey)
value = m_iterator.key();
else
value = createPair(callFrame, m_iterator.key(), m_iterator.value());
++m_iterator;
return true;
}
void finish()
{
m_iterator.finish();
}
private:
static const unsigned StructureFlags = Base::StructureFlags | OverridesVisitChildren;
JSMapIterator(VM& vm, Structure* structure, JSMap* iteratedObject, MapIterationKind kind)
: Base(vm, structure)
, m_iterator(iteratedObject->mapData()->begin())
, m_kind(kind)
{
}
void finishCreation(VM&, JSMap*);
JSValue createPair(CallFrame*, JSValue, JSValue);
static void visitChildren(JSCell*, SlotVisitor&);
WriteBarrier<MapData> m_iteratedObjectData;
MapData::const_iterator m_iterator;
MapIterationKind m_kind;
};
}
#endif // !defined(JSMapIterator_h)