class Integer : public node::ObjectWrap {
public:

	static bool HasInstance(v8::Isolate* isolate, v8::Local<v8::Value> value) {
		return v8::Local<v8::Boolean>::Cast(
			v8::Local<v8::Function>::New(isolate, isInstance)->Call(OnlyContext, v8::Undefined(isolate), 1, &value).ToLocalChecked()
		)->Value();
	}

	static sqlite3_int64 GetValue(v8::Local<v8::Object> integer) {
		return static_cast<Integer*>(integer->GetAlignedPointerFromInternalField(0))->value;
	}

	static v8::Local<v8::Value> New(v8::Isolate* isolate, sqlite3_int64 value, bool safe_ints) {
		if (safe_ints) {
			*controller = { true, value };
			return v8::Local<v8::Function>::New(isolate, constructor)->NewInstance(OnlyContext).ToLocalChecked();
		}
		return v8::Number::New(isolate, (double)value);
	}

private:
	REGISTER(Init) {
		UseContext;
		v8::Local<v8::Function> _constructor = v8::Local<v8::Function>::Cast(Require(module, "integer"));
		v8::Local<v8::Function> _isInstance = v8::Local<v8::Function>::Cast(_constructor->Get(ctx, StringFromUtf8(isolate, "isInstance", -1)).ToLocalChecked());
		v8::Local<v8::Object> prototype = v8::Local<v8::Object>::Cast(_constructor->Get(ctx, StringFromUtf8(isolate, "prototype", -1)).ToLocalChecked());
		constructor.Reset(isolate, _constructor);
		isInstance.Reset(isolate, _isInstance);
		controller = static_cast<ConstructorController*>(prototype->GetAlignedPointerFromInternalField(0));
	}

	explicit Integer(char _) : node::ObjectWrap() { assert(false); }

	struct ConstructorController {
		bool privileges;
		int64_t value;
	};

	static v8::Persistent<v8::Function> constructor;
	static v8::Persistent<v8::Function> isInstance;
	static Integer::ConstructorController* controller;

	int64_t value;
};
