using System;
using System.Collections.Generic;
using System.Linq;
namespace CppSharp.AST
{
public class TemplateTemplateParameter : Template
{
///
/// Whether this template template parameter is a template parameter pack.
/// template<template<class T> ...MetaFunctions> struct Apply;
///
public bool IsParameterPack { get; set; }
///
/// Whether this parameter pack is a pack expansion.
/// A template template parameter pack is a pack expansion if its template parameter list contains an unexpanded parameter pack.
///
public bool IsPackExpansion { get; set; }
///
/// Whether this parameter is a template template parameter pack that has a known list of different template parameter lists at different positions.
/// A parameter pack is an expanded parameter pack when the original parameter pack's template parameter list was itself a pack expansion, and that expansion has already been expanded. For exampe, given:
///
/// template<typename...Types> struct Outer { template<template<Types> class...Templates> struct Inner; };
///
/// The parameter pack Templates is a pack expansion, which expands the pack Types.When Types is supplied with template arguments by instantiating Outer, the instantiation of Templates is an expanded parameter pack.
///
public bool IsExpandedParameterPack { get; set; }
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitTemplateTemplateParameterDecl(this);
}
}
///
/// Represents a template parameter
///
public class TypeTemplateParameter : Declaration
{
///
/// Get the nesting depth of the template parameter.
///
public uint Depth { get; set; }
///
/// Get the index of the template parameter within its parameter list.
///
public uint Index { get; set; }
///
/// Whether this parameter is a non-type template parameter pack.
///
/// If the parameter is a parameter pack, the type may be a PackExpansionType.In the following example, the Dims parameter is a parameter pack (whose type is 'unsigned').
/// template<typename T, unsigned...Dims> struct multi_array;
///
///
public bool IsParameterPack { get; set; }
// Generic type constraint
public string Constraint;
public QualifiedType DefaultArgument { get; set; }
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitTemplateParameterDecl(this);
}
}
///
/// Represents a hard-coded template parameter
///
public class NonTypeTemplateParameter : Declaration
{
///
/// Get the nesting depth of the template parameter.
///
public uint Depth { get; set; }
///
/// Get the index of the template parameter within its parameter list.
///
public uint Index { get; set; }
///
/// Whether this parameter is a non-type template parameter pack.
///
/// If the parameter is a parameter pack, the type may be a PackExpansionType.In the following example, the Dims parameter is a parameter pack (whose type is 'unsigned').
/// template<typename T, unsigned...Dims> struct multi_array;
///
///
public bool IsParameterPack { get; set; }
public Expression DefaultArgument { get; set; }
///
/// Get the position of the template parameter within its parameter list.
///
public uint Position { get; set; }
///
/// Whether this parameter pack is a pack expansion.
///
/// A non-type template parameter pack is a pack expansion if its type contains an unexpanded parameter pack.In this case, we will have built a PackExpansionType wrapping the type.
///
///
public bool IsPackExpansion { get; set; }
///
/// Whether this parameter is a non-type template parameter pack that has a known list of different types at different positions.
/// A parameter pack is an expanded parameter pack when the original parameter pack's type was itself a pack expansion, and that expansion has already been expanded. For example, given:
///
/// template<typename...Types>
/// struct X {
/// template<Types...Values>
/// struct Y { /* ... */ };
/// };
///
/// The parameter pack Values has a PackExpansionType as its type, which expands Types.When Types is supplied with template arguments by instantiating X,
/// the instantiation of Values becomes an expanded parameter pack.For example, instantiating X<int, unsigned int>
/// results in Values being an expanded parameter pack with expansion types int and unsigned int.
///
public bool IsExpandedParameterPack { get; set; }
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitNonTypeTemplateParameterDecl(this);
}
}
///
/// The base class of all kinds of template declarations
/// (e.g., class, function, etc.).
///
public abstract class Template : Declaration
{
// Name of the declaration.
public override string Name
{
get
{
if (TemplatedDecl != null)
return TemplatedDecl.Name;
return base.Name;
}
set
{
base.Name = value;
if (TemplatedDecl != null)
TemplatedDecl.Name = value;
}
}
protected Template()
{
Parameters = new List();
}
protected Template(Declaration decl)
{
TemplatedDecl = decl;
Parameters = new List();
}
public Declaration TemplatedDecl;
public List Parameters;
public override string ToString()
{
return TemplatedDecl.ToString();
}
}
///
/// Declaration of a type alias template.
///
public class TypeAliasTemplate : Template
{
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitTypeAliasTemplateDecl(this);
}
}
///
/// Declaration of a class template.
///
public class ClassTemplate : Template
{
public List Specializations;
public Class TemplatedClass
{
get { return TemplatedDecl as Class; }
}
public ClassTemplate()
{
Specializations = new List();
}
public ClassTemplate(Declaration decl)
: base(decl)
{
Specializations = new List();
}
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitClassTemplateDecl(this);
}
public override string Name
{
get
{
if(TemplatedDecl != null)
return TemplatedClass.Name;
return base.Name;
}
set
{
if(TemplatedDecl != null)
TemplatedClass.Name = value;
else
base.Name = value;
}
}
public override string OriginalName
{
get
{
if(TemplatedDecl != null)
return TemplatedClass.OriginalName;
return base.OriginalName;
}
set
{
if(TemplatedDecl != null)
TemplatedClass.OriginalName = value;
else
base.OriginalName = value;
}
}
public ClassTemplateSpecialization FindSpecializationByUSR(string usr)
{
return Specializations.FirstOrDefault(spec => spec.USR == usr);
}
public ClassTemplatePartialSpecialization FindPartialSpecializationByUSR(string usr)
{
return FindSpecializationByUSR(usr) as ClassTemplatePartialSpecialization;
}
}
///
/// Describes the kind of template specialization that a particular
/// template specialization declaration represents.
///
public enum TemplateSpecializationKind
{
/// This template specialization was formed from a template-id but has
/// not yet been declared, defined, or instantiated.
Undeclared,
/// This template specialization was implicitly instantiated from a
/// template.
ImplicitInstantiation,
/// This template specialization was declared or defined by an explicit
/// specialization or partial specialization.
ExplicitSpecialization,
/// This template specialization was instantiated from a template due
/// to an explicit instantiation declaration request.
ExplicitInstantiationDeclaration,
/// This template specialization was instantiated from a template due
/// to an explicit instantiation definition request.
ExplicitInstantiationDefinition
}
///
/// Represents a class template specialization, which refers to a class
/// template with a given set of template arguments.
///
public class ClassTemplateSpecialization : Class
{
public ClassTemplate TemplatedDecl;
public List Arguments;
public TemplateSpecializationKind SpecializationKind;
public ClassTemplateSpecialization()
{
Arguments = new List();
}
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitClassTemplateSpecializationDecl(this);
}
public override string ToString()
{
var args = string.Join(", ", Arguments.Select(a => a.ToString()));
return string.Format("{0}<{1}> [{2}]", OriginalName, args, SpecializationKind);
}
}
///
/// Represents a class template partial specialization, which refers to
/// a class template with a given partial set of template arguments.
///
public class ClassTemplatePartialSpecialization : ClassTemplateSpecialization
{
}
///
/// Declaration of a template function.
///
public class FunctionTemplate : Template
{
public List Specializations;
public FunctionTemplate()
{
Specializations = new List();
}
public FunctionTemplate(Declaration decl)
: base(decl)
{
Specializations = new List();
}
public Function TemplatedFunction
{
get { return TemplatedDecl as Function; }
}
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitFunctionTemplateDecl(this);
}
}
///
/// Represents a function template specialization, which refers to a function
/// template with a given set of template arguments.
///
public class FunctionTemplateSpecialization
{
public FunctionTemplate Template;
public List Arguments;
public Function SpecializedFunction;
public TemplateSpecializationKind SpecializationKind;
public FunctionTemplateSpecialization()
{
Arguments = new List();
}
public FunctionTemplateSpecialization(FunctionTemplateSpecialization fts)
{
Template = fts.Template;
Arguments = new List();
Arguments.AddRange(fts.Arguments);
SpecializedFunction = fts.SpecializedFunction;
SpecializationKind = fts.SpecializationKind;
}
public T Visit(IDeclVisitor visitor)
{
return visitor.VisitFunctionTemplateSpecializationDecl(this);
}
}
///
/// Represents a declaration of a variable template.
///
public class VarTemplate : Template
{
public List Specializations;
public Variable TemplatedVariable
{
get { return TemplatedDecl as Variable; }
}
public VarTemplate()
{
Specializations = new List();
}
public VarTemplate(Variable var) : base(var)
{
Specializations = new List();
}
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitVarTemplateDecl(this);
}
}
///
/// Represents a var template specialization, which refers to a var
/// template with a given set of template arguments.
///
public class VarTemplateSpecialization : Variable
{
public VarTemplate TemplatedDecl;
public List Arguments;
public TemplateSpecializationKind SpecializationKind;
public VarTemplateSpecialization()
{
Arguments = new List();
}
}
///
/// Represents a variable template partial specialization, which refers to
/// a variable template with a given partial set of template arguments.
///
public class VarTemplatePartialSpecialization : VarTemplateSpecialization
{
}
}