Parse parameter names and body from a stringified lambda.
Extracts identifiers from the parameter list by stripping type tokens (everything up to and including the last space or * before the identifier). Extracts body as the text between the first { and the matching closing }.
74 {
75 KernelSource ks;
76 ks.raw = std::string(stringified);
77
78
79 const auto bracket = stringified.find('[');
80 const auto paren_open = stringified.find('(', bracket);
81 if (paren_open == std::string_view::npos)
82 return ks;
83
84 std::size_t depth = 1;
85 std::size_t paren_close = paren_open + 1;
86 while (paren_close < stringified.size() && depth > 0) {
87 if (stringified[paren_close] == '(') {
88 ++depth;
89 } else if (stringified[paren_close] == ')') {
90 --depth;
91 }
92 ++paren_close;
93 }
94 --paren_close;
95
96 const auto params_text = stringified.substr(paren_open + 1, paren_close - paren_open - 1);
97
98
99 auto extract_name = [](std::string_view param) -> std::string {
100
101 auto end = param.find_last_not_of(" \t\n\r");
102 if (end == std::string_view::npos)
103 return {};
104 param = param.substr(0, end + 1);
105
106 auto sep = param.find_last_of(" *\t");
107 if (sep == std::string_view::npos)
108 return std::string(param);
109 return std::string(param.substr(sep + 1));
110 };
111
112 std::size_t start = 0;
113 while (start < params_text.size()) {
114
115 int angle = 0, paren = 0;
116 std::size_t pos = start;
117 while (pos < params_text.size()) {
118 char c = params_text[pos];
119 if (c == '<') {
120 ++angle;
121 } else if (c == '>') {
122 --angle;
123 } else if (c == '(') {
124 ++paren;
125 } else if (c == ')') {
126 --paren;
127 } else if (c == ',' && angle == 0 && paren == 0) {
128 break;
129 }
130 ++pos;
131 }
132 auto name = extract_name(params_text.substr(start, pos - start));
133 if (!name.empty())
134 ks.param_names.push_back(std::move(name));
135 start = (pos < params_text.size()) ? pos + 1 : pos;
136 }
137
138
139 const auto brace_open = stringified.find('{', paren_close);
140 if (brace_open == std::string_view::npos)
141 return ks;
142
143 depth = 1;
144 std::size_t brace_close = brace_open + 1;
145 while (brace_close < stringified.size() && depth > 0) {
146 if (stringified[brace_close] == '{') {
147 ++depth;
148 } else if (stringified[brace_close] == '}') {
149 --depth;
150 }
151 ++brace_close;
152 }
153 --brace_close;
154
155 ks.body = std::string(stringified.substr(brace_open + 1, brace_close - brace_open - 1));
156 return ks;
157 }