/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#pragma once

#if ENABLE(INDEXED_DATABASE)

#include "IDBCursorWithValue.h"
#include "JSIDBCursor.h"
#include <wtf/NeverDestroyed.h>

namespace WebCore {

class JSIDBCursorWithValue : public JSIDBCursor {
public:
    typedef JSIDBCursor Base;
    typedef IDBCursorWithValue DOMWrapped;
    static JSIDBCursorWithValue* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<IDBCursorWithValue>&& impl)
    {
        JSIDBCursorWithValue* ptr = new (NotNull, JSC::allocateCell<JSIDBCursorWithValue>(globalObject->vm().heap)) JSIDBCursorWithValue(structure, *globalObject, WTFMove(impl));
        ptr->finishCreation(globalObject->vm());
        return ptr;
    }

    static JSC::JSObject* createPrototype(JSC::VM&, JSC::JSGlobalObject*);
    static JSC::JSObject* prototype(JSC::VM&, JSC::JSGlobalObject*);

    DECLARE_INFO;

    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
    static void visitChildren(JSCell*, JSC::SlotVisitor&);
    void visitAdditionalChildren(JSC::SlotVisitor&);

    IDBCursorWithValue& wrapped() const
    {
        return static_cast<IDBCursorWithValue&>(Base::wrapped());
    }
protected:
    JSIDBCursorWithValue(JSC::Structure*, JSDOMGlobalObject&, Ref<IDBCursorWithValue>&&);

    void finishCreation(JSC::VM& vm)
    {
        Base::finishCreation(vm);
        ASSERT(inherits(info()));
    }

};

class JSIDBCursorWithValueOwner : public JSC::WeakHandleOwner {
public:
    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
};

inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, IDBCursorWithValue*)
{
    static NeverDestroyed<JSIDBCursorWithValueOwner> owner;
    return &owner.get();
}

inline void* wrapperKey(IDBCursorWithValue* wrappableObject)
{
    return wrappableObject;
}


template<> struct JSDOMWrapperConverterTraits<IDBCursorWithValue> {
    using WrapperClass = JSIDBCursorWithValue;
};

} // namespace WebCore

#endif // ENABLE(INDEXED_DATABASE)
