This commit is contained in:
parent
5036cb9ca6
commit
10fcf731d9
|
@ -354,6 +354,13 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
if (tok)
|
if (tok)
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
if (tok->str() == ">" && level == 0)
|
||||||
|
return numberOfParameters;
|
||||||
|
else if (tok->str() == "," && level == 0) {
|
||||||
|
++numberOfParameters;
|
||||||
|
tok = tok->next();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip std::
|
// skip std::
|
||||||
|
@ -1930,12 +1937,14 @@ static Token *skipTernaryOp(Token *tok, Token *backToken)
|
||||||
|
|
||||||
void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
||||||
{
|
{
|
||||||
|
// start could be erased so use the token before start if available
|
||||||
|
Token * first = (start && start->previous()) ? start->previous() : mTokenList.front();
|
||||||
bool again = true;
|
bool again = true;
|
||||||
|
|
||||||
while (again) {
|
while (again) {
|
||||||
again = false;
|
again = false;
|
||||||
|
|
||||||
for (Token *tok = start; tok && tok != end; tok = tok->next()) {
|
for (Token *tok = first->next(); tok && tok != end; tok = tok->next()) {
|
||||||
if (tok->str() == "sizeof") {
|
if (tok->str() == "sizeof") {
|
||||||
// sizeof('x')
|
// sizeof('x')
|
||||||
if (Token::Match(tok->next(), "( %char% )")) {
|
if (Token::Match(tok->next(), "( %char% )")) {
|
||||||
|
@ -1980,11 +1989,11 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simplifyCalculations(start, end))
|
if (simplifyCalculations(first->next(), end))
|
||||||
again = true;
|
again = true;
|
||||||
|
|
||||||
for (Token *tok = start; tok && tok != end; tok = tok->next()) {
|
for (Token *tok = first->next(); tok && tok != end; tok = tok->next()) {
|
||||||
if (tok->str() == "?" && tok->previous()->isNumber()) {
|
if (tok->str() == "?" && (tok->previous()->isNumber() || tok->previous()->isBoolean())) {
|
||||||
const int offset = (tok->previous()->str() == ")") ? 2 : 1;
|
const int offset = (tok->previous()->str() == ")") ? 2 : 1;
|
||||||
|
|
||||||
// Find the token ":" then go to the next token
|
// Find the token ":" then go to the next token
|
||||||
|
@ -2043,24 +2052,60 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Token *tok = start; tok && tok != end; tok = tok->next()) {
|
for (Token *tok = first->next(); tok && tok != end; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "( %num% )") && !Token::Match(tok->previous(), "%name%")) {
|
if (Token::Match(tok, "( %num%|%bool% )") &&
|
||||||
|
(tok->previous() && !Token::Match(tok->previous(), "%name%"))) {
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
|
again = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool validTokenStart(bool bounded, const Token *tok, const Token *frontToken, int offset)
|
||||||
|
{
|
||||||
|
if (!bounded)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (frontToken)
|
||||||
|
frontToken = frontToken->previous();
|
||||||
|
|
||||||
|
while (tok && offset <= 0) {
|
||||||
|
if (tok == frontToken)
|
||||||
|
return false;
|
||||||
|
++offset;
|
||||||
|
tok = tok->previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok && offset > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool validTokenEnd(bool bounded, const Token *tok, const Token *backToken, int offset)
|
||||||
|
{
|
||||||
|
if (!bounded)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
while (tok && offset >= 0) {
|
||||||
|
if (tok == backToken)
|
||||||
|
return false;
|
||||||
|
--offset;
|
||||||
|
tok = tok->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok && offset < 0;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: This is not the correct class for simplifyCalculations(), so it
|
// TODO: This is not the correct class for simplifyCalculations(), so it
|
||||||
// should be moved away.
|
// should be moved away.
|
||||||
bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToken)
|
bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToken)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
const bool bounded = frontToken || backToken;
|
||||||
if (!frontToken) {
|
if (!frontToken) {
|
||||||
frontToken = mTokenList.front();
|
frontToken = mTokenList.front();
|
||||||
}
|
}
|
||||||
for (Token *tok = frontToken; tok != backToken; tok = tok->next()) {
|
for (Token *tok = frontToken; tok && tok != backToken; tok = tok->next()) {
|
||||||
// Remove parentheses around variable..
|
// Remove parentheses around variable..
|
||||||
// keep parentheses here: dynamic_cast<Fred *>(p);
|
// keep parentheses here: dynamic_cast<Fred *>(p);
|
||||||
// keep parentheses here: A operator * (int);
|
// keep parentheses here: A operator * (int);
|
||||||
|
@ -2069,8 +2114,11 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
// keep parentheses here: operator new [] (size_t);
|
// keep parentheses here: operator new [] (size_t);
|
||||||
// keep parentheses here: Functor()(a ... )
|
// keep parentheses here: Functor()(a ... )
|
||||||
// keep parentheses here: ) ( var ) ;
|
// keep parentheses here: ) ( var ) ;
|
||||||
if ((Token::Match(tok->next(), "( %name% ) ;|)|,|]") ||
|
if (validTokenEnd(bounded, tok, backToken, 4) &&
|
||||||
(Token::Match(tok->next(), "( %name% ) %cop%") && (tok->tokAt(2)->varId()>0 || !Token::Match(tok->tokAt(4), "[*&+-~]")))) &&
|
(Token::Match(tok->next(), "( %name% ) ;|)|,|]") ||
|
||||||
|
(Token::Match(tok->next(), "( %name% ) %cop%") &&
|
||||||
|
(tok->tokAt(2)->varId()>0 ||
|
||||||
|
!Token::Match(tok->tokAt(4), "[*&+-~]")))) &&
|
||||||
!tok->isName() &&
|
!tok->isName() &&
|
||||||
tok->str() != ">" &&
|
tok->str() != ">" &&
|
||||||
tok->str() != ")" &&
|
tok->str() != ")" &&
|
||||||
|
@ -2081,23 +2129,28 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok->previous(), "(|&&|%oror% %char% %comp% %num% &&|%oror%|)")) {
|
if (validTokenEnd(bounded, tok, backToken, 3) &&
|
||||||
|
Token::Match(tok->previous(), "(|&&|%oror% %char% %comp% %num% &&|%oror%|)")) {
|
||||||
tok->str(MathLib::toString(MathLib::toLongNumber(tok->str())));
|
tok->str(MathLib::toString(MathLib::toLongNumber(tok->str())));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->isNumber()) {
|
if (tok && tok->isNumber()) {
|
||||||
if (simplifyNumericCalculations(tok)) {
|
if (validTokenEnd(bounded, tok, backToken, 2) &&
|
||||||
|
simplifyNumericCalculations(tok)) {
|
||||||
ret = true;
|
ret = true;
|
||||||
Token *prev = tok->tokAt(-2);
|
Token *prev = tok->tokAt(-2);
|
||||||
while (prev && simplifyNumericCalculations(prev)) {
|
while (validTokenStart(bounded, tok, frontToken, -2) &&
|
||||||
|
prev && simplifyNumericCalculations(prev)) {
|
||||||
tok = prev;
|
tok = prev;
|
||||||
prev = prev->tokAt(-2);
|
prev = prev->tokAt(-2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove redundant conditions (0&&x) (1||x)
|
// Remove redundant conditions (0&&x) (1||x)
|
||||||
if (Token::Match(tok->previous(), "[(=,] 0 &&") ||
|
if (validTokenStart(bounded, tok, frontToken, -1) &&
|
||||||
Token::Match(tok->previous(), "[(=,] 1 %oror%")) {
|
validTokenEnd(bounded, tok, backToken, 1) &&
|
||||||
|
(Token::Match(tok->previous(), "[(=,] 0 &&") ||
|
||||||
|
Token::Match(tok->previous(), "[(=,] 1 %oror%"))) {
|
||||||
unsigned int par = 0;
|
unsigned int par = 0;
|
||||||
const Token *tok2 = tok;
|
const Token *tok2 = tok;
|
||||||
const bool andAnd = (tok->next()->str() == "&&");
|
const bool andAnd = (tok->next()->str() == "&&");
|
||||||
|
@ -2118,9 +2171,10 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->str() == "0") {
|
if (tok->str() == "0" && validTokenStart(bounded, tok, frontToken, -1)) {
|
||||||
if ((Token::Match(tok->previous(), "[+-] 0 %cop%|;") && isLowerThanMulDiv(tok->next())) ||
|
if (validTokenEnd(bounded, tok, backToken, 1) &&
|
||||||
(Token::Match(tok->previous(), "%or% 0 %cop%|;") && isLowerThanXor(tok->next()))) {
|
((Token::Match(tok->previous(), "[+-] 0 %cop%|;") && isLowerThanMulDiv(tok->next())) ||
|
||||||
|
(Token::Match(tok->previous(), "%or% 0 %cop%|;") && isLowerThanXor(tok->next())))) {
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
if (Token::Match(tok->tokAt(-4), "[;{}] %name% = %name% [+-|] 0 ;") &&
|
if (Token::Match(tok->tokAt(-4), "[;{}] %name% = %name% [+-|] 0 ;") &&
|
||||||
tok->strAt(-3) == tok->previous()->str()) {
|
tok->strAt(-3) == tok->previous()->str()) {
|
||||||
|
@ -2131,22 +2185,26 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
tok->deleteNext(2);
|
tok->deleteNext(2);
|
||||||
}
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
} else if (Token::Match(tok->previous(), "[=([,] 0 [+|]") ||
|
} else if (validTokenEnd(bounded, tok, backToken, 1) &&
|
||||||
Token::Match(tok->previous(), "return|case 0 [+|]")) {
|
(Token::Match(tok->previous(), "[=([,] 0 [+|]") ||
|
||||||
|
Token::Match(tok->previous(), "return|case 0 [+|]"))) {
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
tok->deleteNext(2);
|
tok->deleteNext(2);
|
||||||
ret = true;
|
ret = true;
|
||||||
} else if (Token::Match(tok->previous(), "[=[(,] 0 * %name%|%num% ,|]|)|;|=|%cop%") ||
|
} else if ((((Token::Match(tok->previous(), "[=[(,] 0 * %name%|%num% ,|]|)|;|=|%cop%") ||
|
||||||
Token::Match(tok->previous(), "[=[(,] 0 * (") ||
|
Token::Match(tok->previous(), "return|case 0 *|&& %name%|%num% ,|:|;|=|%cop%")) &&
|
||||||
Token::Match(tok->previous(), "return|case 0 *|&& %name%|%num% ,|:|;|=|%cop%") ||
|
validTokenEnd(bounded, tok, backToken, 3)) ||
|
||||||
Token::Match(tok->previous(), "return|case 0 *|&& (")) {
|
(((Token::Match(tok->previous(), "[=[(,] 0 * (") ||
|
||||||
|
Token::Match(tok->previous(), "return|case 0 *|&& (")) &&
|
||||||
|
validTokenEnd(bounded, tok, backToken, 2))))) {
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
if (tok->next()->str() == "(")
|
if (tok->next()->str() == "(")
|
||||||
eraseTokens(tok, tok->next()->link());
|
eraseTokens(tok, tok->next()->link());
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
ret = true;
|
ret = true;
|
||||||
} else if (Token::Match(tok->previous(), "[=[(,] 0 && *|& %any% ,|]|)|;|=|%cop%") ||
|
} else if (validTokenEnd(bounded, tok, backToken, 4) &&
|
||||||
Token::Match(tok->previous(), "return|case 0 && *|& %any% ,|:|;|=|%cop%")) {
|
(Token::Match(tok->previous(), "[=[(,] 0 && *|& %any% ,|]|)|;|=|%cop%") ||
|
||||||
|
Token::Match(tok->previous(), "return|case 0 && *|& %any% ,|:|;|=|%cop%"))) {
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
if (tok->next()->str() == "(")
|
if (tok->next()->str() == "(")
|
||||||
|
@ -2156,16 +2214,18 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->str() == "1") {
|
if (tok->str() == "1" && validTokenStart(bounded, tok, frontToken, -1)) {
|
||||||
if (Token::Match(tok->previous(), "[=[(,] 1 %oror% %any% ,|]|)|;|=|%cop%") ||
|
if (validTokenEnd(bounded, tok, backToken, 3) &&
|
||||||
Token::Match(tok->previous(), "return|case 1 %oror% %any% ,|:|;|=|%cop%")) {
|
(Token::Match(tok->previous(), "[=[(,] 1 %oror% %any% ,|]|)|;|=|%cop%") ||
|
||||||
|
Token::Match(tok->previous(), "return|case 1 %oror% %any% ,|:|;|=|%cop%"))) {
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
if (tok->next()->str() == "(")
|
if (tok->next()->str() == "(")
|
||||||
eraseTokens(tok, tok->next()->link());
|
eraseTokens(tok, tok->next()->link());
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
ret = true;
|
ret = true;
|
||||||
} else if (Token::Match(tok->previous(), "[=[(,] 1 %oror% *|& %any% ,|]|)|;|=|%cop%") ||
|
} else if (validTokenEnd(bounded, tok, backToken, 4) &&
|
||||||
Token::Match(tok->previous(), "return|case 1 %oror% *|& %any% ,|:|;|=|%cop%")) {
|
(Token::Match(tok->previous(), "[=[(,] 1 %oror% *|& %any% ,|]|)|;|=|%cop%") ||
|
||||||
|
Token::Match(tok->previous(), "return|case 1 %oror% *|& %any% ,|:|;|=|%cop%"))) {
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
if (tok->next()->str() == "(")
|
if (tok->next()->str() == "(")
|
||||||
|
@ -2175,7 +2235,10 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok->tokAt(-2), "%any% * 1") || Token::Match(tok->previous(), "%any% 1 *")) {
|
if ((Token::Match(tok->tokAt(-2), "%any% * 1") &&
|
||||||
|
validTokenStart(bounded, tok, frontToken, -2)) ||
|
||||||
|
(Token::Match(tok->previous(), "%any% 1 *") &&
|
||||||
|
validTokenStart(bounded, tok, frontToken, -1))) {
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
if (tok->str() == "*")
|
if (tok->str() == "*")
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
|
@ -2184,15 +2247,19 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove parentheses around number..
|
// Remove parentheses around number..
|
||||||
if (Token::Match(tok->tokAt(-2), "%op%|< ( %num% )") && tok->strAt(-2) != ">") {
|
if (validTokenStart(bounded, tok, frontToken, -2) &&
|
||||||
|
Token::Match(tok->tokAt(-2), "%op%|< ( %num% )") &&
|
||||||
|
tok->strAt(-2) != ">") {
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok->previous(), "( 0 [|+]") ||
|
if (validTokenStart(bounded, tok, frontToken, -1) &&
|
||||||
Token::Match(tok->previous(), "[|+-] 0 )")) {
|
validTokenEnd(bounded, tok, backToken, 1) &&
|
||||||
|
(Token::Match(tok->previous(), "( 0 [|+]") ||
|
||||||
|
Token::Match(tok->previous(), "[|+-] 0 )"))) {
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
if (Token::Match(tok, "[|+-]"))
|
if (Token::Match(tok, "[|+-]"))
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
|
@ -2200,10 +2267,13 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok, "%num% %comp% %num%") &&
|
if (validTokenEnd(bounded, tok, backToken, 2) &&
|
||||||
|
Token::Match(tok, "%num% %comp% %num%") &&
|
||||||
MathLib::isInt(tok->str()) &&
|
MathLib::isInt(tok->str()) &&
|
||||||
MathLib::isInt(tok->strAt(2))) {
|
MathLib::isInt(tok->strAt(2))) {
|
||||||
if (Token::Match(tok->previous(), "(|&&|%oror%") && Token::Match(tok->tokAt(3), ")|&&|%oror%|?")) {
|
if (validTokenStart(bounded, tok, frontToken, -1) &&
|
||||||
|
Token::Match(tok->previous(), "(|&&|%oror%") &&
|
||||||
|
Token::Match(tok->tokAt(3), ")|&&|%oror%|?")) {
|
||||||
const MathLib::bigint op1(MathLib::toLongNumber(tok->str()));
|
const MathLib::bigint op1(MathLib::toLongNumber(tok->str()));
|
||||||
const std::string &cmp(tok->next()->str());
|
const std::string &cmp(tok->next()->str());
|
||||||
const MathLib::bigint op2(MathLib::toLongNumber(tok->strAt(2)));
|
const MathLib::bigint op2(MathLib::toLongNumber(tok->strAt(2)));
|
||||||
|
|
|
@ -141,6 +141,7 @@ private:
|
||||||
TEST_CASE(template101); // #8968
|
TEST_CASE(template101); // #8968
|
||||||
TEST_CASE(template102); // #9005
|
TEST_CASE(template102); // #9005
|
||||||
TEST_CASE(template103);
|
TEST_CASE(template103);
|
||||||
|
TEST_CASE(template104); // #9021
|
||||||
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
||||||
|
@ -184,6 +185,8 @@ private:
|
||||||
|
|
||||||
TEST_CASE(templateTypeDeduction1); // #8962
|
TEST_CASE(templateTypeDeduction1); // #8962
|
||||||
TEST_CASE(templateTypeDeduction2);
|
TEST_CASE(templateTypeDeduction2);
|
||||||
|
|
||||||
|
TEST_CASE(simplifyTemplateArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tok(const char code[], bool debugwarnings = false, Settings::PlatformType type = Settings::Native) {
|
std::string tok(const char code[], bool debugwarnings = false, Settings::PlatformType type = Settings::Native) {
|
||||||
|
@ -1275,7 +1278,7 @@ private:
|
||||||
"void foo ( ) { "
|
"void foo ( ) { "
|
||||||
"Foo<true> myFoo ; "
|
"Foo<true> myFoo ; "
|
||||||
"} struct Foo<true> { "
|
"} struct Foo<true> { "
|
||||||
"std :: array < int , true ? 1 : 2 > mfoo ; "
|
"std :: array < int , 1 > mfoo ; "
|
||||||
"} ;";
|
"} ;";
|
||||||
ASSERT_EQUALS(expected, tok(code, true));
|
ASSERT_EQUALS(expected, tok(code, true));
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -2354,6 +2357,32 @@ private:
|
||||||
ASSERT_EQUALS(exp, tok(code));
|
ASSERT_EQUALS(exp, tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void template104() { // #9021
|
||||||
|
const char code[] = "template < int i >\n"
|
||||||
|
"auto key ( ) { return hana :: test :: ct_eq < i > { } ; }\n"
|
||||||
|
"template < int i >\n"
|
||||||
|
"auto val ( ) { return hana :: test :: ct_eq < - i > { } ; }\n"
|
||||||
|
"template < int i , int j >\n"
|
||||||
|
"auto p ( ) { return :: minimal_product ( key < i > ( ) , val < j > ( ) ) ; }\n"
|
||||||
|
"int main ( ) {\n"
|
||||||
|
" BOOST_HANA_CONSTANT_CHECK ( hana :: equal (\n"
|
||||||
|
" hana :: at_key ( hana :: make_map ( p < 0 , 0 > ( ) ) , key < 0 > ( ) ) ,\n"
|
||||||
|
" val < 0 > ( ) ) ) ;\n"
|
||||||
|
"}";
|
||||||
|
const char exp[] = "auto key<0> ( ) ; "
|
||||||
|
"auto val<0> ( ) ; "
|
||||||
|
"auto p<0,0> ( ) ; "
|
||||||
|
"int main ( ) { "
|
||||||
|
"BOOST_HANA_CONSTANT_CHECK ( hana :: equal ( "
|
||||||
|
"hana :: at_key ( hana :: make_map ( p<0,0> ( ) ) , key<0> ( ) ) , "
|
||||||
|
"val<0> ( ) ) ) ; "
|
||||||
|
"} "
|
||||||
|
"auto p<0,0> ( ) { return :: minimal_product ( key<0> ( ) , val<0> ( ) ) ; } "
|
||||||
|
"auto val<0> ( ) { return hana :: test :: ct_eq < - 0 > { } ; } "
|
||||||
|
"auto key<0> ( ) { return hana :: test :: ct_eq < 0 > { } ; }";
|
||||||
|
ASSERT_EQUALS(exp, tok(code));
|
||||||
|
}
|
||||||
|
|
||||||
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
const char code[] = "template <typename T> struct C {};\n"
|
const char code[] = "template <typename T> struct C {};\n"
|
||||||
"template <typename T> struct S {a};\n"
|
"template <typename T> struct S {a};\n"
|
||||||
|
@ -3435,6 +3464,23 @@ private:
|
||||||
TODO_ASSERT_EQUALS(expected, actual, tok(code));
|
TODO_ASSERT_EQUALS(expected, actual, tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simplifyTemplateArgs() {
|
||||||
|
ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template<int N> foo = N; foo < ( 2 ) >;"));
|
||||||
|
ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template<int N> foo = N; foo < 1 + 1 >;"));
|
||||||
|
ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template<int N> foo = N; foo < ( 1 + 1 ) >;"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("foo<2,2> = 4 ; foo<2,2> ;", tok("template<int N, int M> foo = N * M; foo < ( 2 ), ( 2 ) >;"));
|
||||||
|
ASSERT_EQUALS("foo<2,2> = 4 ; foo<2,2> ;", tok("template<int N, int M> foo = N * M; foo < 1 + 1, 1 + 1 >;"));
|
||||||
|
ASSERT_EQUALS("foo<2,2> = 4 ; foo<2,2> ;", tok("template<int N, int M> foo = N * M; foo < ( 1 + 1 ), ( 1 + 1 ) >;"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("foo<true> = true ; foo<true> ;", tok("template<bool N> foo = N; foo < true ? true : false >;"));
|
||||||
|
ASSERT_EQUALS("foo<false> = false ; foo<false> ;", tok("template<bool N> foo = N; foo < false ? true : false >;"));
|
||||||
|
ASSERT_EQUALS("foo<true> = true ; foo<true> ;", tok("template<bool N> foo = N; foo < 1 ? true : false >;"));
|
||||||
|
ASSERT_EQUALS("foo<false> = false ; foo<false> ;", tok("template<bool N> foo = N; foo < 0 ? true : false >;"));
|
||||||
|
ASSERT_EQUALS("foo<true> = true ; foo<true> ;", tok("template<bool N> foo = N; foo < (1 + 1 ) ? true : false >;"));
|
||||||
|
ASSERT_EQUALS("foo<false> = false ; foo<false> ;", tok("template<bool N> foo = N; foo < ( 1 - 1) ? true : false >;"));
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestSimplifyTemplate)
|
REGISTER_TEST(TestSimplifyTemplate)
|
||||||
|
|
Loading…
Reference in New Issue