// ============================================================================
// This file was autogenerated
// It is presented side to side with its source: modifiable_immutable_test.h
// It is not used in the compilation
//    (see integration_tests/bindings/pybind_mylib.cpp which contains the full binding
//     code, including this code)
// ============================================================================

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/numpy.h>
#include "mylib/mylib_main/mylib.h"

namespace py = pybind11;

// <litgen_glue_code>  // Autogenerated code below! Do not edit!
struct BoxedBool
{
    bool value;
    BoxedBool(bool v = false) : value(v) {}
    std::string __repr__() const { return std::string("BoxedBool(") + std::to_string(value) + ")"; }
};
struct BoxedString
{
    std::string value;
    BoxedString(std::string v = "") : value(v) {}
    std::string __repr__() const { return std::string("BoxedString(") + value + ")"; }
};

// </litgen_glue_code> // Autogenerated code end


void py_init_module_mylib(py::module& m)
{
    // <litgen_pydef> // Autogenerated code below! Do not edit!
    ////////////////////    <generated_from:BoxedTypes>    ////////////////////
    auto pyClassBoxedBool =
        py::class_<BoxedBool>
            (m, "BoxedBool", "")
        .def_readwrite("value", &BoxedBool::value, "")
        .def(py::init<bool>(),
            py::arg("v") = false)
        .def("__repr__",
            &BoxedBool::__repr__)
        ;


    auto pyClassBoxedString =
        py::class_<BoxedString>
            (m, "BoxedString", "")
        .def_readwrite("value", &BoxedString::value, "")
        .def(py::init<std::string>(),
            py::arg("v") = "")
        .def("__repr__",
            &BoxedString::__repr__)
        ;
    ////////////////////    </generated_from:BoxedTypes>    ////////////////////


    ////////////////////    <generated_from:modifiable_immutable_test.h>    ////////////////////
    m.def("toggle_bool_pointer",
        [](BoxedBool & v)
        {
            auto ToggleBoolPointer_adapt_modifiable_immutable = [](BoxedBool & v)
            {
                bool * v_boxed_value = & (v.value);

                ToggleBoolPointer(v_boxed_value);
            };

            ToggleBoolPointer_adapt_modifiable_immutable(v);
        },
        py::arg("v"),
        " Test with pointer:\n Will be published in python as:\n -->    def toggle_bool_pointer(v: BoxedBool) -> None:");

    m.def("toggle_bool_nullable",
        [](BoxedBool * v = nullptr)
        {
            auto ToggleBoolNullable_adapt_modifiable_immutable = [](BoxedBool * v = nullptr)
            {
                bool * v_boxed_value = nullptr;
                if (v != nullptr)
                    v_boxed_value = & (v->value);

                ToggleBoolNullable(v_boxed_value);
            };

            ToggleBoolNullable_adapt_modifiable_immutable(v);
        },
        py::arg("v") = py::none(),
        " Test with nullable pointer\n Will be published in python as:\n -->    def toggle_bool_nullable(v: BoxedBool = None) -> None:");

    m.def("toggle_bool_reference",
        [](BoxedBool & v)
        {
            auto ToggleBoolReference_adapt_modifiable_immutable = [](BoxedBool & v)
            {
                bool & v_boxed_value = v.value;

                ToggleBoolReference(v_boxed_value);
            };

            ToggleBoolReference_adapt_modifiable_immutable(v);
        },
        py::arg("v"),
        " Test with reference\n Will be published in python as:\n -->    def toggle_bool_reference(v: BoxedBool) -> None:");

    m.def("modify_string",
        [](BoxedString & s)
        {
            auto ModifyString_adapt_modifiable_immutable = [](BoxedString & s)
            {
                std::string * s_boxed_value = & (s.value);

                ModifyString(s_boxed_value);
            };

            ModifyString_adapt_modifiable_immutable(s);
        },
        py::arg("s"),
        " Test modifiable String\n Will be published in python as:\n -->    def modify_string(s: BoxedString) -> None:");

    m.def("change_bool_int",
        [](const char * label, int value) -> std::tuple<bool, int>
        {
            auto ChangeBoolInt_adapt_modifiable_immutable_to_return = [](const char * label, int value) -> std::tuple<bool, int>
            {
                int * value_adapt_modifiable = & value;

                bool r = ChangeBoolInt(label, value_adapt_modifiable);
                return std::make_tuple(r, value);
            };

            return ChangeBoolInt_adapt_modifiable_immutable_to_return(label, value);
        },
        py::arg("label"), py::arg("value"),
        " Test with int param + int return type\n Will be published in python as:\n --> def change_bool_int(label: str, value: int) -> Tuple[bool, int]:");

    m.def("change_void_int",
        [](const char * label, int value) -> int
        {
            auto ChangeVoidInt_adapt_modifiable_immutable_to_return = [](const char * label, int value) -> int
            {
                int * value_adapt_modifiable = & value;

                ChangeVoidInt(label, value_adapt_modifiable);
                return value;
            };

            return ChangeVoidInt_adapt_modifiable_immutable_to_return(label, value);
        },
        py::arg("label"), py::arg("value"),
        " Will be published in python as:\n -->    def change_void_int(label: str, value: int) -> int:");

    m.def("change_bool_int2",
        [](const char * label, int value1, int value2) -> std::tuple<bool, int, int>
        {
            auto ChangeBoolInt2_adapt_modifiable_immutable_to_return = [](const char * label, int value1, int value2) -> std::tuple<bool, int, int>
            {
                int * value1_adapt_modifiable = & value1;
                int * value2_adapt_modifiable = & value2;

                bool r = ChangeBoolInt2(label, value1_adapt_modifiable, value2_adapt_modifiable);
                return std::make_tuple(r, value1, value2);
            };

            return ChangeBoolInt2_adapt_modifiable_immutable_to_return(label, value1, value2);
        },
        py::arg("label"), py::arg("value1"), py::arg("value2"),
        " Will be published in python as:\n -->    def change_bool_int2(label: str, value1: int, value2: int) -> Tuple[bool, int, int]:");

    m.def("change_void_int_default_null",
        [](const char * label, std::optional<int> value = std::nullopt) -> std::tuple<bool, std::optional<int>>
        {
            auto ChangeVoidIntDefaultNull_adapt_modifiable_immutable_to_return = [](const char * label, std::optional<int> value = std::nullopt) -> std::tuple<bool, std::optional<int>>
            {
                int * value_adapt_modifiable = nullptr;
                if (value.has_value())
                    value_adapt_modifiable = & (*value);

                bool r = ChangeVoidIntDefaultNull(label, value_adapt_modifiable);
                return std::make_tuple(r, value);
            };

            return ChangeVoidIntDefaultNull_adapt_modifiable_immutable_to_return(label, value);
        },
        py::arg("label"), py::arg("value") = py::none(),
        " Will be published in python as:\n -->    def change_void_int_default_null(label: str, value: Optional[int] = None) -> Tuple[bool, Optional[int]]:");

    m.def("change_void_int_array",
        [](const char * label, std::array<int, 3> value) -> std::tuple<bool, std::array<int, 3>>
        {
            auto ChangeVoidIntArray_adapt_modifiable_immutable_to_return = [](const char * label, std::array<int, 3> value) -> std::tuple<bool, std::array<int, 3>>
            {
                int * value_adapt_modifiable = value.data();

                bool r = ChangeVoidIntArray(label, value_adapt_modifiable);
                return std::make_tuple(r, value);
            };

            return ChangeVoidIntArray_adapt_modifiable_immutable_to_return(label, value);
        },
        py::arg("label"), py::arg("value"),
        " Will be published in python as:\n -->    def change_void_int_array(label: str, value: List[int]) -> Tuple[bool, List[int]]:");
    ////////////////////    </generated_from:modifiable_immutable_test.h>    ////////////////////

    // </litgen_pydef> // Autogenerated code end
}
