bytedeco / javacpp

The missing bridge between Java and native C++
Other
4.43k stars 576 forks source link

Support anonymous template parameters #742

Closed HGuillemet closed 5 months ago

HGuillemet commented 5 months ago

Add support for anonymous type template parameters, such as:

template <typename ModuleType, typename>

We use a dummy name [2] as a key in the template map. If we used null or the empty string, we couldn't have more than 1 anonymous parameter.

Regression tests: no change in existing presets.

saudet commented 5 months ago

Why square brackets? If we want something that looks like it's for templates, why not <...>?

HGuillemet commented 5 months ago

We must use something that cannot be an identifier, and that encodes the position of the parameter in the list. Now it could be anything but I would also avoid something that could be the value of a template parameter, even if I don't think it'll break something, just to avoid confusion. <2> could be a value in case of nested templates.

HGuillemet commented 5 months ago

It could be useful to also amend TemplateMap.toString to generate a string that is equivalent to what was parsed (generate typename instead of [2], @2, $2$ or whatever "private" encoding we use). TemplateMap.toString is used to build fullnames of templated functions.

saudet commented 5 months ago

Yeah, no, let's not try to encode anything. Let's just do as with functions, that is arg0, arg1, arg2, ... If that causes a conflict at some point, let's get back to it at that point.

HGuillemet commented 5 months ago

Why do you want to risk a conflict when we can avoid it ? Parsing of template<typename arg1, typename> would fail in your case. What's the problem with using somethong like @arg1 ?

saudet commented 5 months ago

Meh, ok, whatever, @arg0, etc sounds OK. It just won't allow us to use them as identifiers if we need them for some reason

HGuillemet commented 5 months ago

In what situation could we use this placeholder as an identifier ?

HGuillemet commented 5 months ago

Can we finalize this ? I think we just need something to act as a key for the template map. Something depending on the position of the parameter, and something that won't clash with explicit names given to other parameters. I don't think we will ever get() from the template map using this key. But I may overlook some cases.

saudet commented 5 months ago

We could potentially attach some Info to them at some point, and in that case we're already using the slash for "basic/containers" and "basic/types", so what about "template/arg0", ... Good enough?

HGuillemet commented 5 months ago

Why not. Or typename/0. But I don't think we need to make this crafted illegal name visible from presets author. If we change TemplateMap.toString with something like:

    public String toString() {
        String s = "<";
        for (Map.Entry<String, Type> e : entrySet()) {
            if (s.length() > 1) {
                s += ",";
            }
            Type t = e.getValue();
            if (t == null) {
                String k = e.getKey();
                s += k.startsWith("@") ? "typename" : k; // HERE
            } else {
                s += t.cppName;
            }
        }
        if (s.endsWith(">")) {
            s += " ";
        }
        return s + ">";
    }

Then if we want to attach an info to this function template:

template <typename ModuleType, typename>
void f(ModuleType m);

before it's instantiated, we use:

new Info("f<ModuleType, typename>(ModuleType)")

(f<typename ModuleType, typename>, or even better f<typename,typename>, would be more logical but this would need that we distinguish type and non-type parameters in templateMap, which we do not. We could, with minor changes, but is it worth ? Any other use for this distinction ?).

saudet commented 5 months ago

Yeah ok, still doesn't justify putting garbage in the map. It occurs to me that we could just put "typename arg0", etc, with a space in it, right?

HGuillemet commented 5 months ago

ok done