ValueArray Alias::selfTemplateArgs() const { ValueArray templateArgs; templateArgs.reserve(templateVariables().size()); for (const auto templateVar: templateVariables()) { // Refer to the template variables of this type alias. templateArgs.push_back(templateVar->selfRefValue()); } return templateArgs; }
Value Value::substitute(const TemplateVarMap& templateVarMap, const Predicate& selfconst) const { switch (kind()) { case CONSTANT: return copy(); case ALIAS: { ValueArray arguments; arguments.reserve(aliasTemplateArguments().size()); for (const auto& argument: aliasTemplateArguments()) { arguments.push_back(argument.substitute(templateVarMap, selfconst)); } return Value::Alias(alias(), std::move(arguments), type()->substitute(templateVarMap, selfconst)); } case TERNARY: { return Value::Ternary(ternaryCondition().substitute(templateVarMap, selfconst), ternaryIfTrue().substitute(templateVarMap, selfconst), ternaryIfFalse().substitute(templateVarMap, selfconst)); } case TYPEREF: return Value::TypeRef(typeRefType()->substitute(templateVarMap, selfconst), type()->substitute(templateVarMap, selfconst)); case TEMPLATEVARREF: { const auto iterator = templateVarMap.find(templateVar()); if (iterator != templateVarMap.end()) { return iterator->second.copy(); } else { return copy(); } } case CALL: { auto value = callValue().substitute(templateVarMap, selfconst); ValueArray parameters; parameters.reserve(callParameters().size()); for (const auto& parameter: callParameters()) { parameters.push_back(parameter.substitute(templateVarMap, selfconst)); } return Call(std::move(value), std::move(parameters), type()->substitute(templateVarMap, selfconst)); } case FUNCTIONREF: { ValueArray templateArguments; templateArguments.reserve(functionRefTemplateArguments().size()); for (const auto& templateArgument: functionRefTemplateArguments()) { templateArguments.push_back(templateArgument.substitute(templateVarMap, selfconst)); } return FunctionRef(functionRefParentType()->substitute(templateVarMap, selfconst), functionRefFunction(), std::move(templateArguments), type()->substitute(templateVarMap, selfconst)); } case CAPABILITYTEST: { return CapabilityTest(capabilityTestCheckType()->substitute(templateVarMap, selfconst), capabilityTestCapabilityType()->substitute(templateVarMap, selfconst), type()); } case PREDICATE: { return PredicateExpr(predicate().substitute(templateVarMap, selfconst), type()); } default: locic_unreachable("Invalid value kind for substitute()."); } }