天天看點

d組合結構

​​原文​​ 題目:

template AFields() {int a;}
struct A { mixin AFields; }
template BFields() {int b;}
struct B { mixin BFields; }
struct AB { mixin AFields; mixin BFields; }
A a; a.a = 1;
B b; b.b = 2;
AB ab; ab.a = 3; ab.b = 4;      

如何編寫​

​連接配接構​

​​,來編譯.這裡不控制​

​A與B​

​​,也沒有​

​AFields/BFields​

​.

struct A { int a; }
struct B { int b; }
mixin CatStruct!("AB", A, B);//這裡.
AB ab;
ab.a = 1; ab.b = 2;      

1命名元組

import std.meta, std.traits, std.typecons;

// 交織
template Interleave(A...)
{
    static if(A.length == 0)
        alias A Interleave;
    else
        alias AliasSeq!(A[0], A[A.length/2],
            Interleave!(A[1..A.length/2], A[A.length/2+1..$])) Interleave;
}

// 幫助函數
template FieldTypeNameTuple(A)
{
    alias Interleave!(Fields!A, FieldNameTuple!A) FieldTypeNameTuple;
}

template CatStruct(A...)
{
    alias Tuple!(staticMap!(FieldTypeNameTuple, A)) CatStruct;//靜映射
}

// 用法

struct A { int a; }
struct B { int b; }
struct C { int c; }

alias CatStruct!(A, B, C) ABC;      

使用代理

import std.typecons;

struct A { int a; }
struct B { int b; }

struct AB
{
  mixin MultiProxy!(A, B);
}

mixin template MultiProxy(A, B) {
  private A _a;
  private B _b;

  mixin Proxy!_a aProxy;
  mixin Proxy!_b bProxy;

  template opDispatch(string op) {
    static if (is(typeof(aProxy.opDispatch!op))) {
      alias opDispatch = aProxy.opDispatch!op;
    }
    else {
      alias opDispatch = bProxy.opDispatch!op;
    }
  }
}

unittest
{
  AB ab;
  ab.a = 4;
  ab.b = 5;

  assert(ab.a == 4);
  assert(ab.b == 5);
}      

标準庫方法

​​參考​​

mixin template CatStruct(string name, T...) { 
//連接配接構
    static import std.traits, std.conv; 
    private string _code_generator() { 
        string code = "struct " ~ name ~ " {"; 
        foreach(oidx, t; T) { 
            foreach(idx, field; std.traits.FieldTypeTuple!t) 
                 // 怪物行.
                code ~= "std.traits.FieldTypeTuple!(T["~std.conv.to!string(oidx)~"])["~std.conv.to!string(idx)~"] "~ std.traits.FieldNameTuple!t[idx] ~ ";"; 
        } 
        code ~= "}"; 
        return code; 
    } 
    mixin(_code_generator()); 
}      
struct A { import arsd.color; Color a; } 

AB ab; 
import arsd.color; 
ab.a = Color.white; ab.b = 2;
//接着
struct A { import arsd.color; Color a; } 
struct B { int b; } 
struct Color { static Color white() { return Color.init; } } 
mixin CatStruct!("AB", A, B);  

AB ab; 
import arsd.color; 
ab.a = Color.white; ab.b = 2;