There's a really obvious refactoring opportunity in this (working) code.
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
// Match against the ni codes of the rule
if(rule.get_ni1() == *iter)
{
// If there's a match, check if it's flagged include or exclude
const std::string flag = rule.get_op1();
// If include, code is included unless a later rule excludes it
if(flag == "INCLUDE"){ included = true; }
// If exclude, code is specifically excluded
else if(flag == "EXCLUDE"){ return false; }
}
if(rule.get_ni2() == *iter)
{
const std::string flag = rule.get_op2();
if(flag == "INCLUDE"){ included = true; }
else if(flag == "EXCLUDE"){ return false; }
}
if(rule.get_ni3() == *iter)
{
const std::string flag = rule.get_op3();
if(flag == "INCLUDE"){ included = true; }
else if(flag == "EXCLUDE"){ return false; }
}
if(rule.get_ni4() == *iter)
{
const std::string flag = rule.get_op4();
if(flag == "INCLUDE"){ included = true; }
else if(flag == "EXCLUDE"){ return false; }
}
if(rule.get_ni5() == *iter)
{
const std::string flag = rule.get_op5();
if(flag == "INCLUDE"){ included = true; }
else if(flag == "EXCLUDE"){ return false; }
}
}
return included;
}
I want to turn it to something like:
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
// Match against the ni codes of the rule
included |= matchNICode(rule.get_ni1(), rule.get_op1);
included |= matchNICode(rule.get_ni2(), rule.get_op2);
included |= matchNICode(rule.get_ni3(), rule.get_op3);
included |= matchNICode(rule.get_ni4(), rule.get_op4);
included |= matchNICode(rule.get_ni5(), rule.get_op5);
}
return included;
}
bool Translations::matchNICode(const std::string& ni,
const std::string& op)
{
if(ni == *iter)
{
if(op == "INCLUDE"){ return true; }
else if(op == "EXCLUDE"){ /*Return worse than false*/ }
}
return false;
}
The problem is that I can't get around the problem that I want to exit early if it's an exclude statement.
Note that I can't change the structure of the Rule class.
Any advice?