Skip to content

Commit 81da87b

Browse files
author
Your Name
committed
Use stl algorithm
1 parent f64190d commit 81da87b

1 file changed

Lines changed: 72 additions & 64 deletions

File tree

lib/templatesimplifier.cpp

Lines changed: 72 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <map>
3535
#include <memory>
3636
#include <stack>
37+
#include <numeric>
3738
#include <type_traits>
3839
#include <unordered_map>
3940
#include <utility>
@@ -1117,12 +1118,11 @@ static ParsedType parseType(const Token* tok,
11171118
type.nameStart = start;
11181119
type.nameEnd = last;
11191120
if (templateParams && start == last) {
1120-
for (std::size_t i = 0; i < templateParams->size(); ++i) {
1121-
if ((*templateParams)[i]->str() == start->str()) {
1122-
result.templateParamIndex = static_cast<int>(i);
1123-
break;
1124-
}
1125-
}
1121+
const auto it = std::find_if(templateParams->cbegin(), templateParams->cend(), [&](const Token* templateParam) {
1122+
return templateParam->str() == start->str();
1123+
});
1124+
if (it != templateParams->cend())
1125+
result.templateParamIndex = static_cast<int>(it - templateParams->cbegin());
11261126
}
11271127
} else
11281128
return ParsedType();
@@ -1241,8 +1241,7 @@ static std::vector<DeducedToken> renderDeducedType(const ExprType& type, bool ke
12411241
break;
12421242
}
12431243
}
1244-
for (int i = 0; i < type.pointer; ++i)
1245-
tokens.emplace_back("*");
1244+
tokens.insert(tokens.end(), type.pointer, DeducedToken("*"));
12461245
if (type.pointer > 0 && keepTopConst && type.topConst)
12471246
tokens.emplace_back("const");
12481247
return tokens;
@@ -1660,10 +1659,43 @@ static ExprType parseOperandType(const DeductionContext& ctx, const Token*& tok,
16601659
return type;
16611660
}
16621661

1662+
static bool isArithmeticOp(const std::string& s)
1663+
{
1664+
return s == "+" || s == "-" || s == "*" || s == "/" || s == "%";
1665+
}
1666+
1667+
static bool isComparisonOp(const std::string& s)
1668+
{
1669+
return s == "==" || s == "!=" || s == "<=" || s == ">=" || s == "&&" || s == "||";
1670+
}
1671+
1672+
static bool isBitOp(const std::string& s)
1673+
{
1674+
return s == "&" || s == "|" || s == "^";
1675+
}
1676+
1677+
static bool isShiftOp(const std::string& s)
1678+
{
1679+
return s == "<<" || s == ">>";
1680+
}
1681+
16631682
static bool isSupportedBinaryOp(const std::string& s)
16641683
{
1665-
return s == "+" || s == "-" || s == "*" || s == "/" || s == "%" || s == "&" || s == "|" || s == "^" || s == "<<" ||
1666-
s == ">>" || s == "==" || s == "!=" || s == "<=" || s == ">=" || s == "&&" || s == "||";
1684+
return isArithmeticOp(s) || isComparisonOp(s) || isBitOp(s) || isShiftOp(s);
1685+
}
1686+
1687+
static bool isPointerType(const ExprType& type)
1688+
{
1689+
return type.pointer > 0;
1690+
}
1691+
1692+
// fold |operands| with the usual arithmetic conversions
1693+
static ExprType convertArithmeticTypes(const Settings& settings, std::vector<ExprType>::const_iterator begin,
1694+
std::vector<ExprType>::const_iterator end, const ExprType& first)
1695+
{
1696+
return std::accumulate(begin, end, first, [&](const ExprType& lhs, const ExprType& rhs) {
1697+
return usualArithmeticConversion(settings, lhs, rhs);
1698+
});
16671699
}
16681700

16691701
// Determine the type of the expression [start, end). This is a flat scan:
@@ -1696,22 +1728,10 @@ static ExprType evalExpressionType(const DeductionContext& ctx, const Token* sta
16961728
if (ops.empty())
16971729
return operands[0];
16981730

1699-
bool hasCmp = false;
1700-
bool hasBit = false;
1701-
bool hasShift = false;
1702-
std::size_t firstShift = ops.size();
1703-
for (std::size_t i = 0; i < ops.size(); ++i) {
1704-
const std::string& s = ops[i];
1705-
if (s == "==" || s == "!=" || s == "<=" || s == ">=" || s == "&&" || s == "||")
1706-
hasCmp = true;
1707-
else if (s == "&" || s == "|" || s == "^")
1708-
hasBit = true;
1709-
else if (s == "<<" || s == ">>") {
1710-
hasShift = true;
1711-
if (firstShift == ops.size())
1712-
firstShift = i;
1713-
}
1714-
}
1731+
const bool hasCmp = std::any_of(ops.cbegin(), ops.cend(), isComparisonOp);
1732+
const bool hasBit = std::any_of(ops.cbegin(), ops.cend(), isBitOp);
1733+
const auto firstShift = std::find_if(ops.cbegin(), ops.cend(), isShiftOp);
1734+
const bool hasShift = firstShift != ops.cend();
17151735
// the grouping of the operators must not influence the result type
17161736
if (hasCmp && (hasBit || hasShift))
17171737
return ExprType();
@@ -1722,28 +1742,26 @@ static ExprType evalExpressionType(const DeductionContext& ctx, const Token* sta
17221742
return result;
17231743
}
17241744

1745+
// class types (operator overloads) are not supported
1746+
if (std::any_of(operands.cbegin(), operands.cend(), [](const ExprType& operand) {
1747+
return operand.pointer == 0 && !operand.isArithmetic();
1748+
}))
1749+
return ExprType();
1750+
17251751
// pointer arithmetic
1726-
std::size_t pointerCount = 0;
1727-
std::size_t pointerIndex = 0;
1728-
for (std::size_t i = 0; i < operands.size(); ++i) {
1729-
if (operands[i].pointer > 0) {
1730-
++pointerCount;
1731-
pointerIndex = i;
1732-
} else if (!operands[i].isArithmetic())
1733-
return ExprType(); // class types (operator overloads) are not supported
1734-
}
1752+
const std::size_t pointerCount = std::count_if(operands.cbegin(), operands.cend(), isPointerType);
17351753
if (pointerCount > 1)
17361754
return ExprType();
17371755
if (pointerCount == 1) {
17381756
if (std::any_of(ops.cbegin(), ops.cend(), [](const std::string& s) {
17391757
return s != "+" && s != "-";
17401758
}))
17411759
return ExprType();
1742-
for (std::size_t i = 0; i < operands.size(); ++i) {
1743-
if (i != pointerIndex && !operands[i].isIntegral())
1744-
return ExprType();
1745-
}
1746-
ExprType result = operands[pointerIndex];
1760+
if (!std::all_of(operands.cbegin(), operands.cend(), [](const ExprType& operand) {
1761+
return operand.pointer > 0 || operand.isIntegral();
1762+
}))
1763+
return ExprType();
1764+
ExprType result = *std::find_if(operands.cbegin(), operands.cend(), isPointerType);
17471765
result.topConst = false;
17481766
result.fromArray = false;
17491767
return result;
@@ -1754,24 +1772,16 @@ static ExprType evalExpressionType(const DeductionContext& ctx, const Token* sta
17541772
return ExprType();
17551773
// the result is the promoted type of the sub expression left of the
17561774
// first shift operator
1757-
ExprType result = operands[0];
1758-
for (std::size_t i = 1; i <= firstShift; ++i) {
1759-
result = usualArithmeticConversion(*ctx.settings, result, operands[i]);
1760-
if (!result.valid)
1761-
return ExprType();
1762-
}
1763-
return promoteType(*ctx.settings, result);
1775+
const std::size_t leftOfShift = firstShift - ops.cbegin();
1776+
const ExprType result = convertArithmeticTypes(*ctx.settings, operands.cbegin() + 1,
1777+
operands.cbegin() + 1 + leftOfShift, operands[0]);
1778+
return result.valid ? promoteType(*ctx.settings, result) : ExprType();
17641779
}
17651780

17661781
if (hasBit && !std::all_of(operands.cbegin(), operands.cend(), isIntegralType))
17671782
return ExprType();
17681783

1769-
ExprType result = operands[0];
1770-
for (std::size_t i = 1; i < operands.size(); ++i) {
1771-
result = usualArithmeticConversion(*ctx.settings, result, operands[i]);
1772-
if (!result.valid)
1773-
return ExprType();
1774-
}
1784+
ExprType result = convertArithmeticTypes(*ctx.settings, operands.cbegin() + 1, operands.cend(), operands[0]);
17751785
result.fromArray = false;
17761786
return result;
17771787
}
@@ -1959,23 +1969,21 @@ static void deduceTemplateArgumentsAtFunctionCall(const DeductionContext& ctx,
19591969
if (matches.size() > 1) {
19601970
// identical deductions are interchangeable; otherwise the unique
19611971
// candidate with the most exact matches wins, or nothing is deduced
1962-
bool identical = true;
1963-
for (std::size_t i = 1; i < matches.size() && identical; ++i)
1964-
identical = (matches[i].deduced == matches[0].deduced);
1972+
const bool identical = std::all_of(matches.cbegin() + 1, matches.cend(), [&](const Candidate& match) {
1973+
return match.deduced == matches[0].deduced;
1974+
});
19651975
if (!identical) {
19661976
const int maxExact =
19671977
std::max_element(matches.cbegin(), matches.cend(), [](const Candidate& lhs, const Candidate& rhs) {
19681978
return lhs.exactMatches < rhs.exactMatches;
19691979
})->exactMatches;
1970-
std::size_t numberOfBest = 0;
1971-
for (std::size_t i = 0; i < matches.size(); ++i) {
1972-
if (matches[i].exactMatches == maxExact) {
1973-
++numberOfBest;
1974-
winner = i;
1975-
}
1976-
}
1977-
if (numberOfBest != 1)
1980+
if (std::count_if(matches.cbegin(), matches.cend(), [&](const Candidate& match) {
1981+
return match.exactMatches == maxExact;
1982+
}) != 1)
19781983
return;
1984+
winner = std::find_if(matches.cbegin(), matches.cend(), [&](const Candidate& match) {
1985+
return match.exactMatches == maxExact;
1986+
}) - matches.cbegin();
19791987
}
19801988
}
19811989

0 commit comments

Comments
 (0)