| 150 | } |
| 151 | |
| 152 | bool cmForEachFunctionBlocker::ReplayZipLists( |
| 153 | std::vector<cmListFileFunction> const& functions, |
| 154 | cmExecutionStatus& inStatus) |
| 155 | { |
| 156 | assert("Unexpected number of iteration variables" && |
| 157 | this->IterationVarsCount >= 1); |
| 158 | |
| 159 | auto& mf = inStatus.GetMakefile(); |
| 160 | |
| 161 | // Expand the list of list-variables into a list of lists of strings |
| 162 | std::vector<cmList> values; |
| 163 | values.reserve(this->Args.size() - this->IterationVarsCount); |
| 164 | // Also track the longest list size |
| 165 | std::size_t maxItems = 0u; |
| 166 | for (auto const& var : |
| 167 | cmMakeRange(this->Args).advance(this->IterationVarsCount)) { |
| 168 | cmList items; |
| 169 | auto const& value = mf.GetSafeDefinition(var); |
| 170 | if (!value.empty()) { |
| 171 | items.assign(value, cmList::EmptyElements::Yes); |
| 172 | } |
| 173 | maxItems = std::max(maxItems, items.size()); |
| 174 | values.emplace_back(std::move(items)); |
| 175 | } |
| 176 | |
| 177 | // Form the list of iteration variables |
| 178 | std::vector<std::string> iterationVars; |
| 179 | if (this->IterationVarsCount > 1) { |
| 180 | // If multiple iteration variables has given, |
| 181 | // just copy them to the `iterationVars` list. |
| 182 | iterationVars.reserve(values.size()); |
| 183 | std::copy(this->Args.begin(), |
| 184 | this->Args.begin() + this->IterationVarsCount, |
| 185 | std::back_inserter(iterationVars)); |
| 186 | } else { |
| 187 | // In case of the only iteration variable, |
| 188 | // generate names as `var_name_N`, |
| 189 | // where `N` is the count of lists to zip |
| 190 | iterationVars.resize(values.size()); |
| 191 | auto const iter_var_prefix = cmStrCat(this->Args.front(), '_'); |
| 192 | auto i = 0u; |
| 193 | std::generate( |
| 194 | iterationVars.begin(), iterationVars.end(), |
| 195 | [&]() -> std::string { return cmStrCat(iter_var_prefix, i++); }); |
| 196 | } |
| 197 | assert("Sanity check" && iterationVars.size() == values.size()); |
| 198 | |
| 199 | // Store old values for iteration variables |
| 200 | std::map<std::string, cm::optional<std::string>> oldDefs; |
| 201 | for (auto i = 0u; i < values.size(); ++i) { |
| 202 | auto const& varName = iterationVars[i]; |
| 203 | if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) { |
| 204 | oldDefs.emplace(varName, mf.GetSafeDefinition(varName)); |
| 205 | } else if (mf.IsNormalDefinitionSet(varName)) { |
| 206 | oldDefs.emplace(varName, *mf.GetDefinition(varName)); |
| 207 | } else { |
| 208 | oldDefs.emplace(varName, cm::nullopt); |
| 209 | } |
no test coverage detected