{#
    C++ template support
#}
{% import "pybind11.cpp.j2" as pybind11 %}

{% for inc in type_caster_includes %}
#include <{{ inc }}>
{% endfor %}

namespace rpygen {

{% if cls.namespace %}
using namespace {{ cls.namespace }};
{% endif %}

{% for decl in using_declarations %}
using {{ decl.format() }};
{% endfor %}

template <{{ cls.template.parameter_list }}>
struct bind_{{ cls.full_cpp_name_identifier }} {

    {{ pybind11.cls_user_using(cls) }}
    {{ pybind11.cls_auto_using(cls) }}
    {{ pybind11.cls_consts(cls) }}
    {{ pybind11.cls_decl(cls) }}

    py::module &m;
    std::string clsName;

bind_{{ cls.full_cpp_name_identifier }}(py::module &m, const char * clsName) :
    {# TODO: embedded structs will fail here #}
    {{ pybind11.cls_init(cls, "clsName") }}
    m(m),
    clsName(clsName)
{
    {{ pybind11.cls_def_enum(cls, cls.var_name) }}
}

void finish(const char * set_doc = NULL, const char * add_doc = NULL) {

    {{ pybind11.cls_def(cls, cls.var_name) }}

    if (set_doc) {
        {{ cls.var_name }}.doc() = set_doc;
    }
    if (add_doc) {
        {{ cls.var_name }}.doc() = py::cast<std::string>({{ cls.var_name }}.doc()) + add_doc;
    }

    {{ cls.template.inline_code }}
}

}; // struct bind_{{ cls.full_cpp_name_identifier }}

}; // namespace rpygen
