// WARNING: Please don't edit this file. It was generated by Python/WinRT v2.0.0-beta.2

#include "py.Windows.Devices.Gpio.h"


namespace py::cpp::Windows::Devices::Gpio
{
    // ----- GpioChangeCounter class --------------------

    static PyObject* _new_GpioChangeCounter(PyTypeObject* type, PyObject* args, PyObject* kwds) noexcept
    {
        if (kwds != nullptr)
        {
            py::set_invalid_kwd_args_error();
            return nullptr;
        }

        auto arg_count = PyTuple_Size(args);
        if (arg_count == 1)
        {
            try
            {
                auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioPin>(args, 0);

                winrt::Windows::Devices::Gpio::GpioChangeCounter instance{ param0 };
                return py::wrap(instance, type);
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static void _dealloc_GpioChangeCounter(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self) noexcept
    {
        auto tp = Py_TYPE(self);
        std::destroy_at(&self->obj);
        tp->tp_free(self);
        Py_DECREF(tp);
    }

    static PyObject* GpioChangeCounter_Close(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"Close", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Close();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeCounter_Read(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"Read", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(self->obj.Read());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeCounter_Reset(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"Reset", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(self->obj.Reset());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeCounter_Start(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"Start", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Start();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeCounter_Stop(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"Stop", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Stop();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeCounter_get_Polarity(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"Polarity"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.Polarity());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static int GpioChangeCounter_put_Polarity(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* arg, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"Polarity"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return -1;
        }

        if (arg == nullptr)
        {
            PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
            return -1;
        }

        try
        {
            auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioChangePolarity>(arg);

            self->obj.Polarity(param0);
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static PyObject* GpioChangeCounter_get_IsStarted(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeCounter", L"IsStarted"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.IsStarted());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _assign_array_GpioChangeCounter(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        auto array = std::make_unique<py::ComArray<winrt::Windows::Devices::Gpio::GpioChangeCounter>>();
        if (!py::cpp::_winrt::Array_Assign(arg, std::move(array)))
        {
            return nullptr;
        }
        Py_RETURN_NONE;
    }

    static PyObject* _from_GpioChangeCounter(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        try
        {
            auto return_value = py::convert_to<winrt::Windows::Foundation::IInspectable>(arg);
            return py::convert(return_value.as<winrt::Windows::Devices::Gpio::GpioChangeCounter>());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _enter_GpioChangeCounter(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* /*unused*/) noexcept
    {
        return Py_NewRef(self);
    }

    static PyObject* _exit_GpioChangeCounter(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter* self, PyObject* /*unused*/) noexcept
    {
        try
        {
            self->obj.Close();
            Py_RETURN_FALSE;
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyMethodDef _methods_GpioChangeCounter[] = {
        { "close", reinterpret_cast<PyCFunction>(GpioChangeCounter_Close), METH_VARARGS, nullptr },
        { "read", reinterpret_cast<PyCFunction>(GpioChangeCounter_Read), METH_VARARGS, nullptr },
        { "reset", reinterpret_cast<PyCFunction>(GpioChangeCounter_Reset), METH_VARARGS, nullptr },
        { "start", reinterpret_cast<PyCFunction>(GpioChangeCounter_Start), METH_VARARGS, nullptr },
        { "stop", reinterpret_cast<PyCFunction>(GpioChangeCounter_Stop), METH_VARARGS, nullptr },
        { "_assign_array_", _assign_array_GpioChangeCounter, METH_O | METH_STATIC, nullptr },
        { "_from", reinterpret_cast<PyCFunction>(_from_GpioChangeCounter), METH_O | METH_STATIC, nullptr },
        { "__enter__", reinterpret_cast<PyCFunction>(_enter_GpioChangeCounter), METH_NOARGS, nullptr },
        { "__exit__",  reinterpret_cast<PyCFunction>(_exit_GpioChangeCounter), METH_VARARGS, nullptr },
        { }
    };

    static PyGetSetDef _getset_GpioChangeCounter[] = {
        { "polarity", reinterpret_cast<getter>(GpioChangeCounter_get_Polarity), reinterpret_cast<setter>(GpioChangeCounter_put_Polarity), nullptr, nullptr },
        { "is_started", reinterpret_cast<getter>(GpioChangeCounter_get_IsStarted), nullptr, nullptr, nullptr },
        { }
    };

    static PyType_Slot _type_slots_GpioChangeCounter[] = 
    {
        { Py_tp_new, reinterpret_cast<void*>(_new_GpioChangeCounter) },
        { Py_tp_dealloc, reinterpret_cast<void*>(_dealloc_GpioChangeCounter) },
        { Py_tp_methods, reinterpret_cast<void*>(_methods_GpioChangeCounter) },
        { Py_tp_getset, reinterpret_cast<void*>(_getset_GpioChangeCounter) },
        { },
    };

    static PyType_Spec type_spec_GpioChangeCounter =
    {
        "winrt._winrt_windows_devices_gpio.GpioChangeCounter",
        sizeof(py::wrapper::Windows::Devices::Gpio::GpioChangeCounter),
        0,
        Py_TPFLAGS_DEFAULT,
        _type_slots_GpioChangeCounter
    };

    // ----- GpioChangeReader class --------------------

    static PyObject* _new_GpioChangeReader(PyTypeObject* type, PyObject* args, PyObject* kwds) noexcept
    {
        if (kwds != nullptr)
        {
            py::set_invalid_kwd_args_error();
            return nullptr;
        }

        auto arg_count = PyTuple_Size(args);
        if (arg_count == 1)
        {
            try
            {
                auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioPin>(args, 0);

                winrt::Windows::Devices::Gpio::GpioChangeReader instance{ param0 };
                return py::wrap(instance, type);
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else if (arg_count == 2)
        {
            try
            {
                auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioPin>(args, 0);
                auto param1 = py::convert_to<int32_t>(args, 1);

                winrt::Windows::Devices::Gpio::GpioChangeReader instance{ param0, param1 };
                return py::wrap(instance, type);
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static void _dealloc_GpioChangeReader(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self) noexcept
    {
        auto tp = Py_TYPE(self);
        std::destroy_at(&self->obj);
        tp->tp_free(self);
        Py_DECREF(tp);
    }

    static PyObject* GpioChangeReader_Clear(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Clear", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Clear();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_Close(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Close", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Close();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_GetAllItems(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"GetAllItems", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(self->obj.GetAllItems());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_GetNextItem(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"GetNextItem", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(self->obj.GetNextItem());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_PeekNextItem(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"PeekNextItem", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(self->obj.PeekNextItem());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_Start(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Start", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Start();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_Stop(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Stop", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Stop();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_WaitForItemsAsync(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 1)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"WaitForItemsAsync", 1))
            {
                py::set_arg_count_version_error(1);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<int32_t>(args, 0);

                return py::convert(self->obj.WaitForItemsAsync(param0));
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_get_Polarity(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Polarity"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.Polarity());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static int GpioChangeReader_put_Polarity(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* arg, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Polarity"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return -1;
        }

        if (arg == nullptr)
        {
            PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
            return -1;
        }

        try
        {
            auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioChangePolarity>(arg);

            self->obj.Polarity(param0);
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static PyObject* GpioChangeReader_get_Capacity(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Capacity"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.Capacity());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_get_IsEmpty(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"IsEmpty"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.IsEmpty());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_get_IsOverflowed(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"IsOverflowed"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.IsOverflowed());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_get_IsStarted(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"IsStarted"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.IsStarted());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* GpioChangeReader_get_Length(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioChangeReader", L"Length"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.Length());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _assign_array_GpioChangeReader(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        auto array = std::make_unique<py::ComArray<winrt::Windows::Devices::Gpio::GpioChangeReader>>();
        if (!py::cpp::_winrt::Array_Assign(arg, std::move(array)))
        {
            return nullptr;
        }
        Py_RETURN_NONE;
    }

    static PyObject* _from_GpioChangeReader(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        try
        {
            auto return_value = py::convert_to<winrt::Windows::Foundation::IInspectable>(arg);
            return py::convert(return_value.as<winrt::Windows::Devices::Gpio::GpioChangeReader>());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _enter_GpioChangeReader(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* /*unused*/) noexcept
    {
        return Py_NewRef(self);
    }

    static PyObject* _exit_GpioChangeReader(py::wrapper::Windows::Devices::Gpio::GpioChangeReader* self, PyObject* /*unused*/) noexcept
    {
        try
        {
            self->obj.Close();
            Py_RETURN_FALSE;
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyMethodDef _methods_GpioChangeReader[] = {
        { "clear", reinterpret_cast<PyCFunction>(GpioChangeReader_Clear), METH_VARARGS, nullptr },
        { "close", reinterpret_cast<PyCFunction>(GpioChangeReader_Close), METH_VARARGS, nullptr },
        { "get_all_items", reinterpret_cast<PyCFunction>(GpioChangeReader_GetAllItems), METH_VARARGS, nullptr },
        { "get_next_item", reinterpret_cast<PyCFunction>(GpioChangeReader_GetNextItem), METH_VARARGS, nullptr },
        { "peek_next_item", reinterpret_cast<PyCFunction>(GpioChangeReader_PeekNextItem), METH_VARARGS, nullptr },
        { "start", reinterpret_cast<PyCFunction>(GpioChangeReader_Start), METH_VARARGS, nullptr },
        { "stop", reinterpret_cast<PyCFunction>(GpioChangeReader_Stop), METH_VARARGS, nullptr },
        { "wait_for_items_async", reinterpret_cast<PyCFunction>(GpioChangeReader_WaitForItemsAsync), METH_VARARGS, nullptr },
        { "_assign_array_", _assign_array_GpioChangeReader, METH_O | METH_STATIC, nullptr },
        { "_from", reinterpret_cast<PyCFunction>(_from_GpioChangeReader), METH_O | METH_STATIC, nullptr },
        { "__enter__", reinterpret_cast<PyCFunction>(_enter_GpioChangeReader), METH_NOARGS, nullptr },
        { "__exit__",  reinterpret_cast<PyCFunction>(_exit_GpioChangeReader), METH_VARARGS, nullptr },
        { }
    };

    static PyGetSetDef _getset_GpioChangeReader[] = {
        { "polarity", reinterpret_cast<getter>(GpioChangeReader_get_Polarity), reinterpret_cast<setter>(GpioChangeReader_put_Polarity), nullptr, nullptr },
        { "capacity", reinterpret_cast<getter>(GpioChangeReader_get_Capacity), nullptr, nullptr, nullptr },
        { "is_empty", reinterpret_cast<getter>(GpioChangeReader_get_IsEmpty), nullptr, nullptr, nullptr },
        { "is_overflowed", reinterpret_cast<getter>(GpioChangeReader_get_IsOverflowed), nullptr, nullptr, nullptr },
        { "is_started", reinterpret_cast<getter>(GpioChangeReader_get_IsStarted), nullptr, nullptr, nullptr },
        { "length", reinterpret_cast<getter>(GpioChangeReader_get_Length), nullptr, nullptr, nullptr },
        { }
    };

    static PyType_Slot _type_slots_GpioChangeReader[] = 
    {
        { Py_tp_new, reinterpret_cast<void*>(_new_GpioChangeReader) },
        { Py_tp_dealloc, reinterpret_cast<void*>(_dealloc_GpioChangeReader) },
        { Py_tp_methods, reinterpret_cast<void*>(_methods_GpioChangeReader) },
        { Py_tp_getset, reinterpret_cast<void*>(_getset_GpioChangeReader) },
        { },
    };

    static PyType_Spec type_spec_GpioChangeReader =
    {
        "winrt._winrt_windows_devices_gpio.GpioChangeReader",
        sizeof(py::wrapper::Windows::Devices::Gpio::GpioChangeReader),
        0,
        Py_TPFLAGS_DEFAULT,
        _type_slots_GpioChangeReader
    };

    // ----- GpioController class --------------------

    static PyObject* _new_GpioController(PyTypeObject* /*unused*/, PyObject* /*unused*/, PyObject* /*unused*/) noexcept
    {
        static_assert(py::py_type<winrt::Windows::Devices::Gpio::GpioController>::type_name);
        py::set_invalid_activation_error(py::py_type<winrt::Windows::Devices::Gpio::GpioController>::type_name);
        return nullptr;
    }

    static void _dealloc_GpioController(py::wrapper::Windows::Devices::Gpio::GpioController* self) noexcept
    {
        auto tp = Py_TYPE(self);
        std::destroy_at(&self->obj);
        tp->tp_free(self);
        Py_DECREF(tp);
    }

    static PyObject* GpioController_GetControllersAsync(PyObject* /*unused*/, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 1)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioController", L"GetControllersAsync", 1))
            {
                py::set_arg_count_version_error(1);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::Provider::IGpioProvider>(args, 0);

                return py::convert(winrt::Windows::Devices::Gpio::GpioController::GetControllersAsync(param0));
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioController_GetDefault(PyObject* /*unused*/, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioController", L"GetDefault", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(winrt::Windows::Devices::Gpio::GpioController::GetDefault());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioController_GetDefaultAsync(PyObject* /*unused*/, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioController", L"GetDefaultAsync", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(winrt::Windows::Devices::Gpio::GpioController::GetDefaultAsync());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioController_OpenPin(py::wrapper::Windows::Devices::Gpio::GpioController* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 1)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioController", L"OpenPin", 1))
            {
                py::set_arg_count_version_error(1);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<int32_t>(args, 0);

                return py::convert(self->obj.OpenPin(param0));
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else if (arg_count == 2)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioController", L"OpenPin", 2))
            {
                py::set_arg_count_version_error(2);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<int32_t>(args, 0);
                auto param1 = py::convert_to<winrt::Windows::Devices::Gpio::GpioSharingMode>(args, 1);

                return py::convert(self->obj.OpenPin(param0, param1));
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioController_TryOpenPin(py::wrapper::Windows::Devices::Gpio::GpioController* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 2)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioController", L"TryOpenPin", 2))
            {
                py::set_arg_count_version_error(2);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<int32_t>(args, 0);
                auto param1 = py::convert_to<winrt::Windows::Devices::Gpio::GpioSharingMode>(args, 1);
                winrt::Windows::Devices::Gpio::GpioPin param2 { nullptr };
                winrt::Windows::Devices::Gpio::GpioOpenStatus param3 {  };

                auto return_value = self->obj.TryOpenPin(param0, param1, param2, param3);

                py::pyobj_handle out_return_value{ py::convert(return_value) };
                if (!out_return_value)
                {
                    return nullptr;
                }
                py::pyobj_handle out2{ py::convert(param2) };
                if (!out2)
                {
                    return nullptr;
                }
                py::pyobj_handle out3{ py::convert(param3) };
                if (!out3)
                {
                    return nullptr;
                }
                return PyTuple_Pack(3, out_return_value.get(), out2.get(), out3.get());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioController_get_PinCount(py::wrapper::Windows::Devices::Gpio::GpioController* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioController", L"PinCount"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.PinCount());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _assign_array_GpioController(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        auto array = std::make_unique<py::ComArray<winrt::Windows::Devices::Gpio::GpioController>>();
        if (!py::cpp::_winrt::Array_Assign(arg, std::move(array)))
        {
            return nullptr;
        }
        Py_RETURN_NONE;
    }

    static PyObject* _from_GpioController(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        try
        {
            auto return_value = py::convert_to<winrt::Windows::Foundation::IInspectable>(arg);
            return py::convert(return_value.as<winrt::Windows::Devices::Gpio::GpioController>());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyMethodDef _methods_GpioController[] = {
        { "open_pin", reinterpret_cast<PyCFunction>(GpioController_OpenPin), METH_VARARGS, nullptr },
        { "try_open_pin", reinterpret_cast<PyCFunction>(GpioController_TryOpenPin), METH_VARARGS, nullptr },
        { "_assign_array_", _assign_array_GpioController, METH_O | METH_STATIC, nullptr },
        { "_from", reinterpret_cast<PyCFunction>(_from_GpioController), METH_O | METH_STATIC, nullptr },
        { }
    };

    static PyGetSetDef _getset_GpioController[] = {
        { "pin_count", reinterpret_cast<getter>(GpioController_get_PinCount), nullptr, nullptr, nullptr },
        { }
    };

    static PyType_Slot _type_slots_GpioController[] = 
    {
        { Py_tp_new, reinterpret_cast<void*>(_new_GpioController) },
        { Py_tp_dealloc, reinterpret_cast<void*>(_dealloc_GpioController) },
        { Py_tp_methods, reinterpret_cast<void*>(_methods_GpioController) },
        { Py_tp_getset, reinterpret_cast<void*>(_getset_GpioController) },
        { },
    };

    static PyType_Spec type_spec_GpioController =
    {
        "winrt._winrt_windows_devices_gpio.GpioController",
        sizeof(py::wrapper::Windows::Devices::Gpio::GpioController),
        0,
        Py_TPFLAGS_DEFAULT,
        _type_slots_GpioController
    };

    static PyGetSetDef getset_GpioController_Static[] = {
        { }
    };

    static PyMethodDef methods_GpioController_Static[] = {
        { "get_controllers_async", reinterpret_cast<PyCFunction>(GpioController_GetControllersAsync), METH_VARARGS, nullptr },
        { "get_default", reinterpret_cast<PyCFunction>(GpioController_GetDefault), METH_VARARGS, nullptr },
        { "get_default_async", reinterpret_cast<PyCFunction>(GpioController_GetDefaultAsync), METH_VARARGS, nullptr },
        { }
    };

    static PyType_Slot type_slots_GpioController_Static[] = 
    {
        { Py_tp_base, reinterpret_cast<void*>(&PyType_Type) },
        { Py_tp_getset, reinterpret_cast<void*>(getset_GpioController_Static) },
        { Py_tp_methods, reinterpret_cast<void*>(methods_GpioController_Static) },
        { }
    };

    static PyType_Spec type_spec_GpioController_Static =
    {
        "winrt._winrt_windows_devices_gpio.GpioController_Static",
        static_cast<int>(PyType_Type.tp_basicsize),
        static_cast<int>(PyType_Type.tp_itemsize),
        Py_TPFLAGS_DEFAULT,
        type_slots_GpioController_Static
    };

    // ----- GpioPin class --------------------

    static PyObject* _new_GpioPin(PyTypeObject* /*unused*/, PyObject* /*unused*/, PyObject* /*unused*/) noexcept
    {
        static_assert(py::py_type<winrt::Windows::Devices::Gpio::GpioPin>::type_name);
        py::set_invalid_activation_error(py::py_type<winrt::Windows::Devices::Gpio::GpioPin>::type_name);
        return nullptr;
    }

    static void _dealloc_GpioPin(py::wrapper::Windows::Devices::Gpio::GpioPin* self) noexcept
    {
        auto tp = Py_TYPE(self);
        std::destroy_at(&self->obj);
        tp->tp_free(self);
        Py_DECREF(tp);
    }

    static PyObject* GpioPin_Close(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioPin", L"Close", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                self->obj.Close();
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioPin_GetDriveMode(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioPin", L"GetDriveMode", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(self->obj.GetDriveMode());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioPin_IsDriveModeSupported(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 1)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioPin", L"IsDriveModeSupported", 1))
            {
                py::set_arg_count_version_error(1);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioPinDriveMode>(args, 0);

                return py::convert(self->obj.IsDriveModeSupported(param0));
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioPin_Read(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 0)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioPin", L"Read", 0))
            {
                py::set_arg_count_version_error(0);
                return nullptr;
            }

            try
            {
                return py::convert(self->obj.Read());
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioPin_SetDriveMode(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 1)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioPin", L"SetDriveMode", 1))
            {
                py::set_arg_count_version_error(1);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioPinDriveMode>(args, 0);

                self->obj.SetDriveMode(param0);
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioPin_Write(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* args) noexcept
    {
        auto arg_count = PyTuple_Size(args);

        if (arg_count == 1)
        {
            if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(L"Windows.Devices.Gpio.GpioPin", L"Write", 1))
            {
                py::set_arg_count_version_error(1);
                return nullptr;
            }

            try
            {
                auto param0 = py::convert_to<winrt::Windows::Devices::Gpio::GpioPinValue>(args, 0);

                self->obj.Write(param0);
                Py_RETURN_NONE;
            }
            catch (...)
            {
                py::to_PyErr();
                return nullptr;
            }
        }
        else
        {
            py::set_invalid_arg_count_error(arg_count);
            return nullptr;
        }
    }

    static PyObject* GpioPin_get_DebounceTimeout(py::wrapper::Windows::Devices::Gpio::GpioPin* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioPin", L"DebounceTimeout"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.DebounceTimeout());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static int GpioPin_put_DebounceTimeout(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* arg, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioPin", L"DebounceTimeout"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return -1;
        }

        if (arg == nullptr)
        {
            PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
            return -1;
        }

        try
        {
            auto param0 = py::convert_to<winrt::Windows::Foundation::TimeSpan>(arg);

            self->obj.DebounceTimeout(param0);
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static PyObject* GpioPin_get_PinNumber(py::wrapper::Windows::Devices::Gpio::GpioPin* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioPin", L"PinNumber"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.PinNumber());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* GpioPin_get_SharingMode(py::wrapper::Windows::Devices::Gpio::GpioPin* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioPin", L"SharingMode"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.SharingMode());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* GpioPin_add_ValueChanged(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* arg) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsEventPresent(L"Windows.Devices.Gpio.GpioPin", L"ValueChanged"))
        {
            PyErr_SetString(PyExc_AttributeError, "event is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            auto param0 = py::convert_to<winrt::Windows::Foundation::TypedEventHandler<winrt::Windows::Devices::Gpio::GpioPin, winrt::Windows::Devices::Gpio::GpioPinValueChangedEventArgs>>(arg);

            return py::convert(self->obj.ValueChanged(param0));
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* GpioPin_remove_ValueChanged(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* arg) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsEventPresent(L"Windows.Devices.Gpio.GpioPin", L"ValueChanged"))
        {
            PyErr_SetString(PyExc_AttributeError, "event is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            auto param0 = py::convert_to<winrt::event_token>(arg);

            self->obj.ValueChanged(param0);
            Py_RETURN_NONE;
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _assign_array_GpioPin(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        auto array = std::make_unique<py::ComArray<winrt::Windows::Devices::Gpio::GpioPin>>();
        if (!py::cpp::_winrt::Array_Assign(arg, std::move(array)))
        {
            return nullptr;
        }
        Py_RETURN_NONE;
    }

    static PyObject* _from_GpioPin(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        try
        {
            auto return_value = py::convert_to<winrt::Windows::Foundation::IInspectable>(arg);
            return py::convert(return_value.as<winrt::Windows::Devices::Gpio::GpioPin>());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _enter_GpioPin(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* /*unused*/) noexcept
    {
        return Py_NewRef(self);
    }

    static PyObject* _exit_GpioPin(py::wrapper::Windows::Devices::Gpio::GpioPin* self, PyObject* /*unused*/) noexcept
    {
        try
        {
            self->obj.Close();
            Py_RETURN_FALSE;
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyMethodDef _methods_GpioPin[] = {
        { "close", reinterpret_cast<PyCFunction>(GpioPin_Close), METH_VARARGS, nullptr },
        { "get_drive_mode", reinterpret_cast<PyCFunction>(GpioPin_GetDriveMode), METH_VARARGS, nullptr },
        { "is_drive_mode_supported", reinterpret_cast<PyCFunction>(GpioPin_IsDriveModeSupported), METH_VARARGS, nullptr },
        { "read", reinterpret_cast<PyCFunction>(GpioPin_Read), METH_VARARGS, nullptr },
        { "set_drive_mode", reinterpret_cast<PyCFunction>(GpioPin_SetDriveMode), METH_VARARGS, nullptr },
        { "write", reinterpret_cast<PyCFunction>(GpioPin_Write), METH_VARARGS, nullptr },
        { "add_value_changed", reinterpret_cast<PyCFunction>(GpioPin_add_ValueChanged), METH_O, nullptr },
        { "remove_value_changed", reinterpret_cast<PyCFunction>(GpioPin_remove_ValueChanged), METH_O, nullptr },
        { "_assign_array_", _assign_array_GpioPin, METH_O | METH_STATIC, nullptr },
        { "_from", reinterpret_cast<PyCFunction>(_from_GpioPin), METH_O | METH_STATIC, nullptr },
        { "__enter__", reinterpret_cast<PyCFunction>(_enter_GpioPin), METH_NOARGS, nullptr },
        { "__exit__",  reinterpret_cast<PyCFunction>(_exit_GpioPin), METH_VARARGS, nullptr },
        { }
    };

    static PyGetSetDef _getset_GpioPin[] = {
        { "debounce_timeout", reinterpret_cast<getter>(GpioPin_get_DebounceTimeout), reinterpret_cast<setter>(GpioPin_put_DebounceTimeout), nullptr, nullptr },
        { "pin_number", reinterpret_cast<getter>(GpioPin_get_PinNumber), nullptr, nullptr, nullptr },
        { "sharing_mode", reinterpret_cast<getter>(GpioPin_get_SharingMode), nullptr, nullptr, nullptr },
        { }
    };

    static PyType_Slot _type_slots_GpioPin[] = 
    {
        { Py_tp_new, reinterpret_cast<void*>(_new_GpioPin) },
        { Py_tp_dealloc, reinterpret_cast<void*>(_dealloc_GpioPin) },
        { Py_tp_methods, reinterpret_cast<void*>(_methods_GpioPin) },
        { Py_tp_getset, reinterpret_cast<void*>(_getset_GpioPin) },
        { },
    };

    static PyType_Spec type_spec_GpioPin =
    {
        "winrt._winrt_windows_devices_gpio.GpioPin",
        sizeof(py::wrapper::Windows::Devices::Gpio::GpioPin),
        0,
        Py_TPFLAGS_DEFAULT,
        _type_slots_GpioPin
    };

    // ----- GpioPinValueChangedEventArgs class --------------------

    static PyObject* _new_GpioPinValueChangedEventArgs(PyTypeObject* /*unused*/, PyObject* /*unused*/, PyObject* /*unused*/) noexcept
    {
        static_assert(py::py_type<winrt::Windows::Devices::Gpio::GpioPinValueChangedEventArgs>::type_name);
        py::set_invalid_activation_error(py::py_type<winrt::Windows::Devices::Gpio::GpioPinValueChangedEventArgs>::type_name);
        return nullptr;
    }

    static void _dealloc_GpioPinValueChangedEventArgs(py::wrapper::Windows::Devices::Gpio::GpioPinValueChangedEventArgs* self) noexcept
    {
        auto tp = Py_TYPE(self);
        std::destroy_at(&self->obj);
        tp->tp_free(self);
        Py_DECREF(tp);
    }

    static PyObject* GpioPinValueChangedEventArgs_get_Edge(py::wrapper::Windows::Devices::Gpio::GpioPinValueChangedEventArgs* self, void* /*unused*/) noexcept
    {
        if (!winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Devices.Gpio.GpioPinValueChangedEventArgs", L"Edge"))
        {
            PyErr_SetString(PyExc_AttributeError, "property is not available in this version of Windows");
            return nullptr;
        }

        try
        {
            return py::convert(self->obj.Edge());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyObject* _assign_array_GpioPinValueChangedEventArgs(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        auto array = std::make_unique<py::ComArray<winrt::Windows::Devices::Gpio::GpioPinValueChangedEventArgs>>();
        if (!py::cpp::_winrt::Array_Assign(arg, std::move(array)))
        {
            return nullptr;
        }
        Py_RETURN_NONE;
    }

    static PyObject* _from_GpioPinValueChangedEventArgs(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        try
        {
            auto return_value = py::convert_to<winrt::Windows::Foundation::IInspectable>(arg);
            return py::convert(return_value.as<winrt::Windows::Devices::Gpio::GpioPinValueChangedEventArgs>());
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static PyMethodDef _methods_GpioPinValueChangedEventArgs[] = {
        { "_assign_array_", _assign_array_GpioPinValueChangedEventArgs, METH_O | METH_STATIC, nullptr },
        { "_from", reinterpret_cast<PyCFunction>(_from_GpioPinValueChangedEventArgs), METH_O | METH_STATIC, nullptr },
        { }
    };

    static PyGetSetDef _getset_GpioPinValueChangedEventArgs[] = {
        { "edge", reinterpret_cast<getter>(GpioPinValueChangedEventArgs_get_Edge), nullptr, nullptr, nullptr },
        { }
    };

    static PyType_Slot _type_slots_GpioPinValueChangedEventArgs[] = 
    {
        { Py_tp_new, reinterpret_cast<void*>(_new_GpioPinValueChangedEventArgs) },
        { Py_tp_dealloc, reinterpret_cast<void*>(_dealloc_GpioPinValueChangedEventArgs) },
        { Py_tp_methods, reinterpret_cast<void*>(_methods_GpioPinValueChangedEventArgs) },
        { Py_tp_getset, reinterpret_cast<void*>(_getset_GpioPinValueChangedEventArgs) },
        { },
    };

    static PyType_Spec type_spec_GpioPinValueChangedEventArgs =
    {
        "winrt._winrt_windows_devices_gpio.GpioPinValueChangedEventArgs",
        sizeof(py::wrapper::Windows::Devices::Gpio::GpioPinValueChangedEventArgs),
        0,
        Py_TPFLAGS_DEFAULT,
        _type_slots_GpioPinValueChangedEventArgs
    };

    // ----- GpioChangeCount struct --------------------

    winrt_struct_wrapper<winrt::Windows::Devices::Gpio::GpioChangeCount>* _new_GpioChangeCount(PyTypeObject* subclass, PyObject* /*unused*/, PyObject* /*unused*/) noexcept
    {
        auto self = reinterpret_cast<winrt_struct_wrapper<winrt::Windows::Devices::Gpio::GpioChangeCount>*>(subclass->tp_alloc(subclass, 0));

        if (!self)
        {
            return nullptr;
        }

        std::construct_at(&self->obj);

        return self;
    }

    int _init_GpioChangeCount(winrt_struct_wrapper<winrt::Windows::Devices::Gpio::GpioChangeCount>* self, PyObject* args, PyObject* kwds) noexcept
    {
        auto tuple_size = PyTuple_Size(args);

        if ((tuple_size == 0) && (kwds == nullptr))
        {
            self->obj = {};
            return 0;
        }

        uint64_t _Count{};
        PyObject* _RelativeTime{};

        static const char* kwlist[] = {"count", "relative_time", nullptr};
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "KO", const_cast<char**>(kwlist), &_Count, &_RelativeTime))
        {
            return -1;
        }

        try
        {
            self->obj = {_Count, py::converter<winrt::Windows::Foundation::TimeSpan>::convert_to(_RelativeTime)};
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static void _dealloc_GpioChangeCount(py::wrapper::Windows::Devices::Gpio::GpioChangeCount* self) noexcept
    {
        auto tp = Py_TYPE(self);
        std::destroy_at(&self->obj);
        tp->tp_free(self);
        Py_DECREF(tp);
    }

    static PyObject* _assign_array_GpioChangeCount(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        auto array = std::make_unique<py::ComArray<winrt::Windows::Devices::Gpio::GpioChangeCount>>();
        if (!py::cpp::_winrt::Array_Assign(arg, std::move(array)))
        {
            return nullptr;
        }
        Py_RETURN_NONE;
    }

    static PyMethodDef _methods_GpioChangeCount[] = {
        { "_assign_array_", _assign_array_GpioChangeCount, METH_O | METH_STATIC, nullptr },
        { }
    };

    static PyObject* GpioChangeCount_get_Count(py::wrapper::Windows::Devices::Gpio::GpioChangeCount* self, void* /*unused*/) noexcept
    {
        try
        {
            return py::convert(self->obj.Count);
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static int GpioChangeCount_set_Count(py::wrapper::Windows::Devices::Gpio::GpioChangeCount* self, PyObject* arg, void* /*unused*/) noexcept
    {
        if (arg == nullptr)
        {
            PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
            return -1;
        }

        try
        {
            self->obj.Count = py::converter<uint64_t>::convert_to(arg);
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static PyObject* GpioChangeCount_get_RelativeTime(py::wrapper::Windows::Devices::Gpio::GpioChangeCount* self, void* /*unused*/) noexcept
    {
        try
        {
            return py::convert(self->obj.RelativeTime);
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static int GpioChangeCount_set_RelativeTime(py::wrapper::Windows::Devices::Gpio::GpioChangeCount* self, PyObject* arg, void* /*unused*/) noexcept
    {
        if (arg == nullptr)
        {
            PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
            return -1;
        }

        try
        {
            self->obj.RelativeTime = py::converter<winrt::Windows::Foundation::TimeSpan>::convert_to(arg);
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static PyGetSetDef _getset_GpioChangeCount[] = {
        { "count", reinterpret_cast<getter>(GpioChangeCount_get_Count), reinterpret_cast<setter>(GpioChangeCount_set_Count), nullptr, nullptr },
        { "relative_time", reinterpret_cast<getter>(GpioChangeCount_get_RelativeTime), reinterpret_cast<setter>(GpioChangeCount_set_RelativeTime), nullptr, nullptr },
        { }
    };

    static PyType_Slot _type_slots_GpioChangeCount[] = 
    {
        { Py_tp_new, reinterpret_cast<void*>(_new_GpioChangeCount) },
        { Py_tp_init, reinterpret_cast<void*>(_init_GpioChangeCount) },
        { Py_tp_dealloc, reinterpret_cast<void*>(_dealloc_GpioChangeCount) },
        { Py_tp_methods, reinterpret_cast<void*>(_methods_GpioChangeCount) },
        { Py_tp_getset, reinterpret_cast<void*>(_getset_GpioChangeCount) },
        { },
    };

    static PyType_Spec type_spec_GpioChangeCount =
    {
        "winrt._winrt_windows_devices_gpio.GpioChangeCount",
        sizeof(py::wrapper::Windows::Devices::Gpio::GpioChangeCount),
        0,
        Py_TPFLAGS_DEFAULT,
        _type_slots_GpioChangeCount
    };

    // ----- GpioChangeRecord struct --------------------

    winrt_struct_wrapper<winrt::Windows::Devices::Gpio::GpioChangeRecord>* _new_GpioChangeRecord(PyTypeObject* subclass, PyObject* /*unused*/, PyObject* /*unused*/) noexcept
    {
        auto self = reinterpret_cast<winrt_struct_wrapper<winrt::Windows::Devices::Gpio::GpioChangeRecord>*>(subclass->tp_alloc(subclass, 0));

        if (!self)
        {
            return nullptr;
        }

        std::construct_at(&self->obj);

        return self;
    }

    int _init_GpioChangeRecord(winrt_struct_wrapper<winrt::Windows::Devices::Gpio::GpioChangeRecord>* self, PyObject* args, PyObject* kwds) noexcept
    {
        auto tuple_size = PyTuple_Size(args);

        if ((tuple_size == 0) && (kwds == nullptr))
        {
            self->obj = {};
            return 0;
        }

        PyObject* _RelativeTime{};
        int32_t _Edge{};

        static const char* kwlist[] = {"relative_time", "edge", nullptr};
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi", const_cast<char**>(kwlist), &_RelativeTime, &_Edge))
        {
            return -1;
        }

        try
        {
            self->obj = {py::converter<winrt::Windows::Foundation::TimeSpan>::convert_to(_RelativeTime), static_cast<winrt::Windows::Devices::Gpio::GpioPinEdge>(_Edge)};
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static void _dealloc_GpioChangeRecord(py::wrapper::Windows::Devices::Gpio::GpioChangeRecord* self) noexcept
    {
        auto tp = Py_TYPE(self);
        std::destroy_at(&self->obj);
        tp->tp_free(self);
        Py_DECREF(tp);
    }

    static PyObject* _assign_array_GpioChangeRecord(PyObject* /*unused*/, PyObject* arg) noexcept
    {
        auto array = std::make_unique<py::ComArray<winrt::Windows::Devices::Gpio::GpioChangeRecord>>();
        if (!py::cpp::_winrt::Array_Assign(arg, std::move(array)))
        {
            return nullptr;
        }
        Py_RETURN_NONE;
    }

    static PyMethodDef _methods_GpioChangeRecord[] = {
        { "_assign_array_", _assign_array_GpioChangeRecord, METH_O | METH_STATIC, nullptr },
        { }
    };

    static PyObject* GpioChangeRecord_get_RelativeTime(py::wrapper::Windows::Devices::Gpio::GpioChangeRecord* self, void* /*unused*/) noexcept
    {
        try
        {
            return py::convert(self->obj.RelativeTime);
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static int GpioChangeRecord_set_RelativeTime(py::wrapper::Windows::Devices::Gpio::GpioChangeRecord* self, PyObject* arg, void* /*unused*/) noexcept
    {
        if (arg == nullptr)
        {
            PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
            return -1;
        }

        try
        {
            self->obj.RelativeTime = py::converter<winrt::Windows::Foundation::TimeSpan>::convert_to(arg);
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static PyObject* GpioChangeRecord_get_Edge(py::wrapper::Windows::Devices::Gpio::GpioChangeRecord* self, void* /*unused*/) noexcept
    {
        try
        {
            return py::convert(self->obj.Edge);
        }
        catch (...)
        {
            py::to_PyErr();
            return nullptr;
        }
    }

    static int GpioChangeRecord_set_Edge(py::wrapper::Windows::Devices::Gpio::GpioChangeRecord* self, PyObject* arg, void* /*unused*/) noexcept
    {
        if (arg == nullptr)
        {
            PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
            return -1;
        }

        try
        {
            self->obj.Edge = py::converter<winrt::Windows::Devices::Gpio::GpioPinEdge>::convert_to(arg);
            return 0;
        }
        catch (...)
        {
            py::to_PyErr();
            return -1;
        }
    }

    static PyGetSetDef _getset_GpioChangeRecord[] = {
        { "relative_time", reinterpret_cast<getter>(GpioChangeRecord_get_RelativeTime), reinterpret_cast<setter>(GpioChangeRecord_set_RelativeTime), nullptr, nullptr },
        { "edge", reinterpret_cast<getter>(GpioChangeRecord_get_Edge), reinterpret_cast<setter>(GpioChangeRecord_set_Edge), nullptr, nullptr },
        { }
    };

    static PyType_Slot _type_slots_GpioChangeRecord[] = 
    {
        { Py_tp_new, reinterpret_cast<void*>(_new_GpioChangeRecord) },
        { Py_tp_init, reinterpret_cast<void*>(_init_GpioChangeRecord) },
        { Py_tp_dealloc, reinterpret_cast<void*>(_dealloc_GpioChangeRecord) },
        { Py_tp_methods, reinterpret_cast<void*>(_methods_GpioChangeRecord) },
        { Py_tp_getset, reinterpret_cast<void*>(_getset_GpioChangeRecord) },
        { },
    };

    static PyType_Spec type_spec_GpioChangeRecord =
    {
        "winrt._winrt_windows_devices_gpio.GpioChangeRecord",
        sizeof(py::wrapper::Windows::Devices::Gpio::GpioChangeRecord),
        0,
        Py_TPFLAGS_DEFAULT,
        _type_slots_GpioChangeRecord
    };

    // ----- Windows.Devices.Gpio Initialization --------------------
    PyDoc_STRVAR(module_doc, "Windows::Devices::Gpio");


    static PyModuleDef module_def
        = {PyModuleDef_HEAD_INIT,
           "_winrt_windows_devices_gpio",
           module_doc,
           0,
           nullptr,
           nullptr,
           nullptr,
           nullptr,
           nullptr};

} // py::cpp::Windows::Devices::Gpio

PyMODINIT_FUNC PyInit__winrt_windows_devices_gpio(void) noexcept
{
    using namespace py::cpp::Windows::Devices::Gpio;

    if (py::import_winrt_runtime() == -1)
    {
        return nullptr;
    }

    py::pyobj_handle module{PyModule_Create(&module_def)};

    if (!module)
    {
        return nullptr;
    }

    auto object_type = py::get_object_type();
    if (!object_type)
    {
        return nullptr;
    }

    py::pyobj_handle object_bases{PyTuple_Pack(1, object_type)};

    if (!object_bases)
    {
        return nullptr;
    }

    if (py::register_python_type(module.get(), &type_spec_GpioChangeCounter, object_bases.get(), nullptr) == -1)
    {
        return nullptr;
    }

    if (py::register_python_type(module.get(), &type_spec_GpioChangeReader, object_bases.get(), nullptr) == -1)
    {
        return nullptr;
    }

    py::pyobj_handle type_GpioController_Static{PyType_FromSpec(&type_spec_GpioController_Static)};
    if (!type_GpioController_Static)
    {
        return nullptr;
    }

    if (py::register_python_type(module.get(), &type_spec_GpioController, object_bases.get(), reinterpret_cast<PyTypeObject*>(type_GpioController_Static.get())) == -1)
    {
        return nullptr;
    }

    if (py::register_python_type(module.get(), &type_spec_GpioPin, object_bases.get(), nullptr) == -1)
    {
        return nullptr;
    }

    if (py::register_python_type(module.get(), &type_spec_GpioPinValueChangedEventArgs, object_bases.get(), nullptr) == -1)
    {
        return nullptr;
    }

    if (py::register_python_type(module.get(), &type_spec_GpioChangeCount, nullptr, nullptr) == -1)
    {
        return nullptr;
    }

    if (py::register_python_type(module.get(), &type_spec_GpioChangeRecord, nullptr, nullptr) == -1)
    {
        return nullptr;
    }


    return module.detach();
}
