#ifndef JSSetIterator_h
#define JSSetIterator_h
#include "JSDestructibleObject.h"
#include "JSSet.h"
#include "MapData.h"
namespace JSC {
enum SetIterationKind : uint32_t {
SetIterateKey,
SetIterateValue,
SetIterateKeyValue,
};
class JSSetIterator : 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 JSSetIterator* create(VM& vm, Structure* structure, JSSet* iteratedObject, SetIterationKind kind)
{
JSSetIterator* instance = new (NotNull, allocateCell<JSSetIterator>(vm.heap)) JSSetIterator(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 == SetIterateValue || m_kind == SetIterateKey)
value = m_iterator.key();
else
value = createPair(callFrame, m_iterator.key(), m_iterator.key());
++m_iterator;
return true;
}
void finish()
{
m_iterator.finish();
}
private:
static const unsigned StructureFlags = Base::StructureFlags | OverridesVisitChildren;
JSSetIterator(VM& vm, Structure* structure, JSSet* iteratedObject, SetIterationKind kind)
: Base(vm, structure)
, m_iterator(iteratedObject->mapData()->begin())
, m_kind(kind)
{
}
void finishCreation(VM&, JSSet*);
JSValue createPair(CallFrame*, JSValue, JSValue);
static void visitChildren(JSCell*, SlotVisitor&);
WriteBarrier<MapData> m_iteratedObjectData;
MapData::const_iterator m_iterator;
SetIterationKind m_kind;
};
}
#endif // !defined(JSSetIterator_h)