unsigned NumArgs,
const TemplateArgument *Args) const;
- QualType getPackExpansionType(QualType Pattern);
+ QualType getPackExpansionType(QualType Pattern,
+ llvm::Optional<unsigned> NumExpansions);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const;
/// the pattern of the pack expansion.
///
/// \param Ellipsis Will be set to the location of the ellipsis.
+ ///
+ /// \param NumExpansions Will be set to the number of expansions that will
+ /// be generated from this pack expansion, if known a priori.
TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
+ llvm::Optional<unsigned> &NumExpansions,
ASTContext &Context) const;
};
#include "llvm/Support/type_traits.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
/// \brief The pattern of the pack expansion.
QualType Pattern;
- PackExpansionType(QualType Pattern, QualType Canon)
+ /// \brief The number of expansions that this pack expansion will
+ /// generate when substituted (+1), or indicates that
+ ///
+ /// This field will only have a non-zero value when some of the parameter
+ /// packs that occur within the pattern have been substituted but others have
+ /// not.
+ unsigned NumExpansions;
+
+ PackExpansionType(QualType Pattern, QualType Canon,
+ llvm::Optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon, /*Dependent=*/true,
/*VariableModified=*/Pattern->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false),
- Pattern(Pattern) { }
+ Pattern(Pattern),
+ NumExpansions(NumExpansions? *NumExpansions + 1: 0) { }
friend class ASTContext; // ASTContext creates these
-
+
public:
/// \brief Retrieve the pattern of this pack expansion, which is the
/// type that will be repeatedly instantiated when instantiating the
/// pack expansion itself.
QualType getPattern() const { return Pattern; }
+ /// \brief Retrieve the number of expansions that this pack expansion will
+ /// generate, if known.
+ llvm::Optional<unsigned> getNumExpansions() const {
+ if (NumExpansions)
+ return NumExpansions - 1;
+
+ return llvm::Optional<unsigned>();
+ }
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPattern());
+ Profile(ID, getPattern(), getNumExpansions());
}
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern) {
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
+ llvm::Optional<unsigned> NumExpansions) {
ID.AddPointer(Pattern.getAsOpaquePtr());
+ ID.AddBoolean(NumExpansions);
+ if (NumExpansions)
+ ID.AddInteger(*NumExpansions);
}
static bool classof(const Type *T) {
def err_pack_expansion_length_conflict : Error<
"pack expansion contains parameter packs %0 and %1 that have different "
"lengths (%2 vs. %3)">;
+def err_pack_expansion_length_conflict_multilevel : Error<
+ "pack expansion contains parameter pack %0 that has a different "
+ "length (%1 vs. %2) from outer parameter packs">;
def err_pack_expansion_member_init : Error<
"pack expansion for initialization of member %0">;
/// \brief Construct a pack expansion type from the pattern of the pack
/// expansion.
TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern,
- SourceLocation EllipsisLoc);
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions);
/// \brief Construct a pack expansion type from the pattern of the pack
/// expansion.
QualType CheckPackExpansion(QualType Pattern,
SourceRange PatternRange,
- SourceLocation EllipsisLoc);
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions);
/// \brief Invoked when parsing an expression followed by an ellipsis, which
/// creates a pack expansion.
/// C++0x [temp.arg.explicit]p9.
///
/// \param NumExpansions The number of separate arguments that will be in
- /// the expanded form of the corresponding pack expansion. Must be set when
- /// \c ShouldExpand is \c true.
+ /// the expanded form of the corresponding pack expansion. This is both an
+ /// input and an output parameter, which can be set by the caller if the
+ /// number of expansions is known a priori (e.g., due to a prior substitution)
+ /// and will be set by the callee when the number of expansions is known.
+ /// The callee must set this value when \c ShouldExpand is \c true; it may
+ /// set this value in other cases.
///
/// \returns true if an error occurred (e.g., because the parameter packs
/// are to be instantiated with arguments of different lengths), false
const MultiLevelTemplateArgumentList &TemplateArgs,
bool &ShouldExpand,
bool &RetainExpansion,
- unsigned &NumExpansions);
+ llvm::Optional<unsigned> &NumExpansions);
/// \brief Determine the number of arguments in the given pack expansion
/// type.
return QualType(T, 0);
}
-QualType ASTContext::getPackExpansionType(QualType Pattern) {
+QualType ASTContext::getPackExpansionType(QualType Pattern,
+ llvm::Optional<unsigned> NumExpansions) {
llvm::FoldingSetNodeID ID;
- PackExpansionType::Profile(ID, Pattern);
+ PackExpansionType::Profile(ID, Pattern, NumExpansions);
assert(Pattern->containsUnexpandedParameterPack() &&
"Pack expansions must expand one or more parameter packs");
QualType Canon;
if (!Pattern.isCanonical()) {
- Canon = getPackExpansionType(getCanonicalType(Pattern));
+ Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions);
// Find the insert position again.
PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
}
- T = new (*this) PackExpansionType(Pattern, Canon);
+ T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions);
Types.push_back(T);
PackExpansionTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
QualType ArgType = Context.getTypeDeclType(TTP);
if (TTP->isParameterPack())
- ArgType = Context.getPackExpansionType(ArgType);
+ ArgType = Context.getPackExpansionType(ArgType,
+ llvm::Optional<unsigned>());
Arg = TemplateArgument(ArgType);
} else if (NonTypeTemplateParmDecl *NTTP =
TemplateArgumentLoc
TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
+ llvm::Optional<unsigned> &NumExpansions,
ASTContext &Context) const {
assert(Argument.isPackExpansion());
Ellipsis = Expansion.getEllipsisLoc();
TypeLoc Pattern = Expansion.getPatternLoc();
+ NumExpansions = Expansion.getTypePtr()->getNumExpansions();
// FIXME: This is horrible. We know where the source location data is for
// the pattern, and we have the pattern's type, but we are forced to copy
= cast<PackExpansionExpr>(Argument.getAsExpr());
Expr *Pattern = Expansion->getPattern();
Ellipsis = Expansion->getEllipsisLoc();
+ // FIXME: Variadic templates num expansions
return TemplateArgumentLoc(Pattern, Pattern);
}
case TemplateArgument::TemplateExpansion:
+ // FIXME: Variadic templates num expansions
Ellipsis = getTemplateEllipsisLoc();
return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
getTemplateQualifierRange(),
unsigned NumUnexpanded,
bool &ShouldExpand,
bool &RetainExpansion,
- unsigned &NumExpansions) {
+ llvm::Optional<unsigned> &NumExpansions) {
return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
PatternRange, Unexpanded,
NumUnexpanded,
// We still have unexpanded parameter packs, which means that
// our function parameter is still a function parameter pack.
// Therefore, make its type a pack expansion type.
- NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc());
+ // FIXME: Variadic templates num expansions.
+ NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(),
+ llvm::Optional<unsigned>());
}
} else {
NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
Unexpanded);
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (CheckParameterPacksForExpansion(Base->getEllipsisLoc(),
Base->getSourceRange(),
Unexpanded.data(), Unexpanded.size(),
// If we should expand this pack expansion now, do so.
if (ShouldExpand) {
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
bool Expand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions
+ = PackExpansion->getNumExpansions();
if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),
SourceRange(),
Unexpanded.data(),
if (!Expand) {
// We can't expand this pack expansion into separate arguments yet;
- // just substitute into the argument pack.
+ // just substitute into the pattern and create a new pack expansion
+ // type.
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
QualType T = SemaRef.SubstType(PackExpansion->getPattern(),
TemplateArgs,
if (T.isNull())
break;
+ T = SemaRef.Context.getPackExpansionType(T, NumExpansions);
Exceptions.push_back(T);
continue;
}
// Substitute into the pack expansion pattern for each template
bool Invalid = false;
- for (unsigned ArgIdx = 0; ArgIdx != NumExpansions; ++ArgIdx) {
+ for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx);
QualType T = SemaRef.SubstType(PackExpansion->getPattern(),
collectUnexpandedParameterPacks(BaseTL, Unexpanded);
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(),
BaseTL.getSourceRange(),
Unexpanded.data(),
assert(ShouldExpand && "Partial instantiation of base initializer?");
// Loop over all of the arguments in the argument pack(s),
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
// Instantiate the initializer.
if (!TSInfo)
return true;
- TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
+ TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc,
+ llvm::Optional<unsigned>());
if (!TSResult)
return true;
}
TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
- SourceLocation EllipsisLoc) {
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
// Create the pack expansion type and source-location information.
QualType Result = CheckPackExpansion(Pattern->getType(),
Pattern->getTypeLoc().getSourceRange(),
- EllipsisLoc);
+ EllipsisLoc, NumExpansions);
if (Result.isNull())
return 0;
QualType Sema::CheckPackExpansion(QualType Pattern,
SourceRange PatternRange,
- SourceLocation EllipsisLoc) {
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
// C++0x [temp.variadic]p5:
// The pattern of a pack expansion shall name one or more
// parameter packs that are not expanded by a nested pack
return QualType();
}
- return Context.getPackExpansionType(Pattern);
+ return Context.getPackExpansionType(Pattern, NumExpansions);
}
ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
const MultiLevelTemplateArgumentList &TemplateArgs,
bool &ShouldExpand,
bool &RetainExpansion,
- unsigned &NumExpansions) {
+ llvm::Optional<unsigned> &NumExpansions) {
ShouldExpand = true;
RetainExpansion = false;
std::pair<IdentifierInfo *, SourceLocation> FirstPack;
RetainExpansion = true;
}
- if (!HaveFirstPack) {
+ if (!NumExpansions) {
// The is the first pack we've seen for which we have an argument.
// Record it.
NumExpansions = NewPackSize;
continue;
}
- if (NewPackSize != NumExpansions) {
+ if (NewPackSize != *NumExpansions) {
// C++0x [temp.variadic]p5:
// All of the parameter packs expanded by a pack expansion shall have
// the same number of arguments specified.
- Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
- << FirstPack.first << Name << NumExpansions << NewPackSize
- << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
+ if (HaveFirstPack)
+ Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
+ << FirstPack.first << Name << *NumExpansions << NewPackSize
+ << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
+ else
+ Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
+ << Name << *NumExpansions << NewPackSize
+ << SourceRange(Unexpanded[I].second);
return true;
}
}
<< T << D.getSourceRange();
D.setEllipsisLoc(SourceLocation());
} else {
- T = Context.getPackExpansionType(T);
+ T = Context.getPackExpansionType(T, llvm::Optional<unsigned>());
}
break;
// parameter packs in the type of the non-type template parameter, then
// it expands those parameter packs.
if (T->containsUnexpandedParameterPack())
- T = Context.getPackExpansionType(T);
+ T = Context.getPackExpansionType(T, llvm::Optional<unsigned>());
else if (!getLangOptions().CPlusPlus0x)
Diag(D.getEllipsisLoc(), diag::err_variadic_templates);
break;
/// C++0x [temp.arg.explicit]p9.
///
/// \param NumExpansions The number of separate arguments that will be in
- /// the expanded form of the corresponding pack expansion. Must be set when
- /// \c ShouldExpand is \c true.
+ /// the expanded form of the corresponding pack expansion. This is both an
+ /// input and an output parameter, which can be set by the caller if the
+ /// number of expansions is known a priori (e.g., due to a prior substitution)
+ /// and will be set by the callee when the number of expansions is known.
+ /// The callee must set this value when \c ShouldExpand is \c true; it may
+ /// set this value in other cases.
///
/// \returns true if an error occurred (e.g., because the parameter packs
/// are to be instantiated with arguments of different lengths), false
unsigned NumUnexpanded,
bool &ShouldExpand,
bool &RetainExpansion,
- unsigned &NumExpansions) {
+ llvm::Optional<unsigned> &NumExpansions) {
ShouldExpand = false;
return false;
}
/// Subclasses may override this routine to provide different behavior.
QualType RebuildPackExpansionType(QualType Pattern,
SourceRange PatternRange,
- SourceLocation EllipsisLoc) {
- return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc);
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
+ return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
+ NumExpansions);
}
/// \brief Build a new nested-name-specifier given the prefix and an
/// for a template argument. Subclasses may override this routine to provide
/// different behavior.
TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
- SourceLocation EllipsisLoc) {
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
switch (Pattern.getArgument().getKind()) {
case TemplateArgument::Expression: {
ExprResult Result
case TemplateArgument::Type:
if (TypeSourceInfo *Expansion
= getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
- EllipsisLoc))
+ EllipsisLoc,
+ NumExpansions))
return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
Expansion);
break;
// be expanded.
bool Expand = true;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
Pattern->getSourceRange(),
Unexpanded.data(),
if (OutPattern.isInvalid())
return true;
+ // FIXME: Variadic templates NumExpansions
ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
Expansion->getEllipsisLoc());
if (Out.isInvalid())
// The transform has determined that we should perform an elementwise
// expansion of the pattern. Do so.
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
ExprResult Out = getDerived().TransformExpr(Pattern);
if (Out.isInvalid())
// We have a pack expansion, for which we will be substituting into
// the pattern.
SourceLocation Ellipsis;
+ llvm::Optional<unsigned> OrigNumExpansions;
TemplateArgumentLoc Pattern
- = In.getPackExpansionPattern(Ellipsis, getSema().Context);
+ = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions,
+ getSema().Context);
llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
// be expanded.
bool Expand = true;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions = OrigNumExpansions;
if (getDerived().TryExpandParameterPacks(Ellipsis,
Pattern.getSourceRange(),
Unexpanded.data(),
if (getDerived().TransformTemplateArgument(Pattern, OutPattern))
return true;
- Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis);
+ Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
+ NumExpansions);
if (Out.getArgument().isNull())
return true;
// The transform has determined that we should perform an elementwise
// expansion of the pattern. Do so.
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
if (getDerived().TransformTemplateArgument(Pattern, Out))
return true;
if (Out.getArgument().containsUnexpandedParameterPack()) {
- Out = getDerived().RebuildPackExpansion(Out, Ellipsis);
+ Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
+ OrigNumExpansions);
if (Out.getArgument().isNull())
return true;
}
if (getDerived().TransformTemplateArgument(Pattern, Out))
return true;
- Out = getDerived().RebuildPackExpansion(Out, Ellipsis);
+ Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
+ OrigNumExpansions);
if (Out.getArgument().isNull())
return true;
// Determine whether we should expand the parameter packs.
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
Pattern.getSourceRange(),
Unexpanded.data(),
// Expand the function parameter pack into multiple, separate
// parameters.
getDerived().ExpandingFunctionParameterPack(OldParm);
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
ParmVarDecl *NewParm
= getDerived().TransformFunctionTypeParam(OldParm);
// expansion.
}
+ // FIXME: Variadic templates num expansions
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm);
if (!NewParm)
// declaration for this parameter.
QualType OldType = ParamTypes[i];
bool IsPackExpansion = false;
+ llvm::Optional<unsigned> NumExpansions;
if (const PackExpansionType *Expansion
= dyn_cast<PackExpansionType>(OldType)) {
// We have a function parameter pack that may need to be expanded.
// Determine whether we should expand the parameter packs.
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
Unexpanded.data(),
Unexpanded.size(),
if (ShouldExpand) {
// Expand the function parameter pack into multiple, separate
// parameters.
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
QualType NewType = getDerived().TransformType(Pattern);
if (NewType.isNull())
return true;
if (IsPackExpansion)
- NewType = getSema().Context.getPackExpansionType(NewType);
+ NewType = getSema().Context.getPackExpansionType(NewType,
+ NumExpansions);
OutParamTypes.push_back(NewType);
if (PVars)
Pattern != TL.getPatternLoc().getType()) {
Result = getDerived().RebuildPackExpansionType(Pattern,
TL.getPatternLoc().getSourceRange(),
- TL.getEllipsisLoc());
+ TL.getEllipsisLoc(),
+ TL.getTypePtr()->getNumExpansions());
if (Result.isNull())
return QualType();
}
UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
&Unexpanded, 1,
ShouldExpand, RetainExpansion,
// that stores that length.
return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
E->getPackLoc(), E->getRParenLoc(),
- NumExpansions);
+ *NumExpansions);
}
template<typename Derived>
QualType Pattern = GetType(Record[0]);
if (Pattern.isNull())
return QualType();
-
- return Context->getPackExpansionType(Pattern);
+ llvm::Optional<unsigned> NumExpansions;
+ if (Record[1])
+ NumExpansions = Record[1] - 1;
+ return Context->getPackExpansionType(Pattern, NumExpansions);
}
case TYPE_ELABORATED: {
void ASTTypeWriter::VisitPackExpansionType(const PackExpansionType *T) {
Writer.AddTypeRef(T->getPattern(), Record);
+ if (llvm::Optional<unsigned> NumExpansions = T->getNumExpansions())
+ Record.push_back(*NumExpansions + 1);
+ else
+ Record.push_back(0);
Code = TYPE_PACK_EXPANSION;
}
template<typename ...Types>
struct X {
- template<typename> struct Inner;
+ template<typename> struct Inner {
+ static const unsigned value = 1;
+ };
template<typename ...YTypes>
struct Inner<tuple<pair<Types, YTypes>...> > {
- static const unsigned zero = sizeof...(Types) - sizeof...(YTypes);
+ static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
};
};
int check0[X<short, int, long>::Inner<tuple<pair<short, unsigned short>,
pair<int, unsigned int>,
pair<long, unsigned long>>
- >::zero == 0? 1 : -1];
+ >::value == 0? 1 : -1];
+
+ int check1[X<short, int>::Inner<tuple<pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>>
+ >::value == 1? 1 : -1];
}