2010-02-12 4 views
1

similaires à Boost Preprocessor library for generating a set of types based on a list of basic types e.g. PointI32, PointF32 etc. in C++/CLI Je demande comment générer:T4 (Text Template Transformation Toolkit) pour générer un ensemble de types basé sur une liste de types de base, par ex. PointI32, PointF32 etc. en C#

struct Point##TYPE_SUFFIX_NAME 
{ 
    TYPE X 
    { get; set; } 
    TYPE Y; 
    { get; set; } 

    // Other code 
}; 

pour différents types de données de base (POD), par exemple:

PointF32, PointF64, PointI32 etc. 

utilisant T4 (Text Template Toolkit de transformation) dans Visual Studio 2008 ou version ultérieure.

Voir http://www.olegsych.com/2007/12/text-template-transformation-toolkit/ et http://msdn.microsoft.com/en-us/library/bb126445.aspx

Répondre

2

Eh bien, j'ai la réponse moi-même. J'ai créé le T4 suivant inclure des fichiers:

  • SignedIntegersSuffices.ttinclude
  • UnsignedIntegersSuffices.ttinclude
  • IntegersSuffices.ttinclude
  • FloatsSuffices.ttinclude
  • BasicTypesSuffices.ttinclude

et le modèle T4 réelle est PointTypes.tt. Ces fichiers sont simplement ajoutés à un projet C# et Visual Studio détecte le .tt et génère un fichier PointTypes.cs correspondant, chaque fois que le fichier .tt est enregistré.

Ces fichiers sont répertoriés ci-dessous.

SignedIntegersSuffices.ttinclude

<#+ 
IEnumerable<KeyValuePair<string, string>> SignedIntegersSuffices() 
{ 
    var signedIntegersSuffices = new KeyValuePair<string, string>[] { 
     new KeyValuePair<string, string>("sbyte", "I8"), 
     new KeyValuePair<string, string>("short", "I16"), 
     new KeyValuePair<string, string>("int", "I32"), 
     new KeyValuePair<string, string>("long", "I64") 
    }; 
    return signedIntegersSuffices; 
} 
#> 

UnsignedIntegersSuffices.ttinclude

<#+ 
IEnumerable<KeyValuePair<string, string>> UnsignedIntegersSuffices() 
{ 
    var signedIntegersSuffices = new KeyValuePair<string, string>[] { 
     new KeyValuePair<string, string>("byte", "UI8"), 
     new KeyValuePair<string, string>("ushort", "UI16"), 
     new KeyValuePair<string, string>("uint", "UI32"), 
     new KeyValuePair<string, string>("ulong", "UI64") 
    }; 
    return signedIntegersSuffices; 
} 
#> 

IntegersSuffices.ttinclude

<#@ include file="SignedIntegersSuffices.ttinclude" #> 
<#@ include file="UnsignedIntegersSuffices.ttinclude" #> 
<#+ 
    // Insert any template procedures here 
    IEnumerable<KeyValuePair<string, string>> IntegersSuffices() 
    { 
     var integersSuffices = SignedIntegersSuffices().Concat(UnsignedIntegersSuffices()); 
     return integersSuffices; 
    } 
#> 

FloatsSuffices.ttinclude

<#+ 
    // Insert any template procedures here 
    IEnumerable<KeyValuePair<string, string>> FloatsSuffices() 
    { 
     var floatsSuffices = new KeyValuePair<string, string>[] { 
      new KeyValuePair<string, string>("float", "F32"), 
      new KeyValuePair<string, string>("double", "F64") 
     }; 
     return floatsSuffices; 
    } 
#> 

BasicTypesSuffices.ttinclude

<#@ include file="IntegersSuffices.ttinclude" #> 
<#@ include file="FloatsSuffices.ttinclude" #> 
<#+ 
    // Insert any template procedures here 
    IEnumerable<KeyValuePair<string, string>> BasicTypesSuffices() 
    { 
     var basicTypesSuffices = IntegersSuffices().Concat(FloatsSuffices()); 
     return basicTypesSuffices; 
    } 
#> 

Et enfin le fichier modèle réel PointTypes.tt:

<#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" language="C#v3.5" debug="true" hostSpecific="true" #> 
<#@ output extension=".cs" #> 
<#@ Assembly Name="System.dll" #> 
<#@ Assembly Name="System.Core.dll" #> 
<#@ import namespace="System" #> 
<#@ import namespace="System.IO" #> 
<#@ import namespace="System.Diagnostics" #> 
<#@ import namespace="System.Linq" #> 
<#@ import namespace="System.Collections" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ include file="BasicTypesSuffices.ttinclude" #> 
namespace TextTemplatesTest 
{ 
<# 
    const string pointPrefix = "Point"; 
    foreach (var typeSuffix in BasicTypesSuffices()) 
    { 
     string type = typeSuffix.Key; 
     string suffix = typeSuffix.Value; 
#> 
    public struct <#= pointPrefix #><#= suffix #> 
    { 
     <#= pointPrefix #><#= suffix #>(<#= type #> x, <#= type #> y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public <#= type #> X 
     { get; set; } 
     public <#= type #> Y 
     { get; set; } 
    } 
<# 
    } 
#> 
} 

Le fichier de sortie PointTypes.cs ressemblera alors à ceci:

namespace TextTemplatesTest 
{ 
    public struct PointI8 
    { 
     PointI8(sbyte x, sbyte y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public sbyte X 
     { get; set; } 
     public sbyte Y 
     { get; set; } 
    } 
    public struct PointI16 
    { 
     PointI16(short x, short y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public short X 
     { get; set; } 
     public short Y 
     { get; set; } 
    } 
    public struct PointI32 
    { 
     PointI32(int x, int y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public int X 
     { get; set; } 
     public int Y 
     { get; set; } 
    } 
    public struct PointI64 
    { 
     PointI64(long x, long y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public long X 
     { get; set; } 
     public long Y 
     { get; set; } 
    } 
    public struct PointUI8 
    { 
     PointUI8(byte x, byte y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public byte X 
     { get; set; } 
     public byte Y 
     { get; set; } 
    } 
    public struct PointUI16 
    { 
     PointUI16(ushort x, ushort y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public ushort X 
     { get; set; } 
     public ushort Y 
     { get; set; } 
    } 
    public struct PointUI32 
    { 
     PointUI32(uint x, uint y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public uint X 
     { get; set; } 
     public uint Y 
     { get; set; } 
    } 
    public struct PointUI64 
    { 
     PointUI64(ulong x, ulong y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public ulong X 
     { get; set; } 
     public ulong Y 
     { get; set; } 
    } 
    public struct PointF32 
    { 
     PointF32(float x, float y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public float X 
     { get; set; } 
     public float Y 
     { get; set; } 
    } 
    public struct PointF64 
    { 
     PointF64(double x, double y) 
      : this() 
     { 
      X = x; 
      Y = y; 
     } 

     public double X 
     { get; set; } 
     public double Y 
     { get; set; } 
    } 
} 

assez simple et très efficace. Maintenant, bien sûr, cela aurait pu être fait en utilisant des génériques, etc, mais ce n'est pas le point ici. Ceci est conçu comme un simple exemple de génération de code pour plusieurs types de base.

Les commentaires pour améliorer ceci ou similaire sont les bienvenus.

Questions connexes