Predicate Predicate::substitute(const TemplateVarMap& templateVarMap, const Predicate& selfconst) const { switch (kind()) { case TRUE: { return Predicate::True(); } case FALSE: { return Predicate::False(); } case SELFCONST: { return selfconst.copy(); } case AND: { return Predicate::And(andLeft().substitute(templateVarMap, selfconst), andRight().substitute(templateVarMap, selfconst)); } case OR: { return Predicate::Or(orLeft().substitute(templateVarMap, selfconst), orRight().substitute(templateVarMap, selfconst)); } case SATISFIES: { return Predicate::Satisfies(satisfiesType()->substitute(templateVarMap, selfconst), satisfiesRequirement()->substitute(templateVarMap, selfconst)); } case VARIABLE: { const auto iterator = templateVarMap.find(variableTemplateVar()); if (iterator == templateVarMap.end()) { return Predicate::Variable(variableTemplateVar()); } const auto& templateValue = iterator->second; return templateValue.makePredicate(); } } locic_unreachable("Unknown predicate kind."); }