Templates.java
/*
* Copyright (C) 2023 Herv�� Guillemet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
* the Free Software Foundation (subject to the "Classpath" exception),
* either version 2, or any later version (collectively, the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/
* http://www.gnu.org/software/classpath/license.html
*
* or as provided in the LICENSE.txt file that accompanied this code.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bytedeco.javacpp.tools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Templates {
static final Pattern templatePattern = Pattern.compile("<[^<>=]*>");
/** Remove template arguments from s, taking care of nested templates, default arguments {@code (xxx<>), operator <=>, ->}, etc */
static String strip(String s) {
Matcher m;
do {
m = templatePattern.matcher(s);
s = m.replaceFirst("");
} while (!m.hitEnd());
return s;
}
/** Returns {@code strip(s).length() == s.length()}. */
static boolean notExists(String s) {
return strip(s).length() == s.length();
}
/** Returns {@code splitNamespace(s, false)}. */
static List<String> splitNamespace(String s) {
return splitNamespace(s, false);
}
/**
* Split s at ::, but taking care of qualified template arguments and qualified function parameters.
* If returnParams is true, returned list contains an extra element with function parameters, or the empty
* string if none are present.
*/
static List<String> splitNamespace(String s, boolean returnParams) {
String sTemplatesMasked = s;
for (;;) {
Matcher m = templatePattern.matcher(sTemplatesMasked);
if (m.find()) {
char[] c = new char[m.end() - m.start()];
Arrays.fill(c, '.');
sTemplatesMasked = sTemplatesMasked.substring(0, m.start()) + new String(c) + sTemplatesMasked.substring(m.end());
} else {
break;
}
}
ArrayList<String> comps = new ArrayList<>();
int pIndex = sTemplatesMasked.lastIndexOf(')'); // last because of function pointer types like void(*)()
if (pIndex > 0) {
// Pointer list may contain function pointer types with parentheses
int count = 1;
for (pIndex--; pIndex >= 0; pIndex--) {
char c = sTemplatesMasked.charAt(pIndex);
if (c == ')') {
count++;
} else if (c == '(') {
count--;
if (count == 0) {
break;
}
}
}
}
int start = 0;
for (;;) {
int i = sTemplatesMasked.indexOf("::", start);
if (i >= 0 && (i < pIndex || pIndex == -1)) {
comps.add(s.substring(start, i));
start = i + 2;
} else {
break;
}
}
String params;
if (pIndex >= 0) {
comps.add(s.substring(start, pIndex));
params = s.substring(pIndex);
} else {
comps.add(s.substring(start));
params = "";
}
if (returnParams) {
comps.add(params);
}
return comps;
}
}