Cleanest pattern for building up a complex type? sequence of mixin templates?
monkyyy
crazymonkyyy at gmail.com
Sat Jul 4 01:28:05 UTC 2026
my current best candidate gist for making an extremely complex
struct:
```d
import std;
struct metastruct(int I,string S,behavoir...){
enum myI=I;
enum myS=S;
static foreach(__amixintemplate;behavoir){
mixin __amixintemplate!();
}}
mixin template fooreturnsi(){
auto foo()=>I;
}
alias vec(int N)=metastruct!(N,"vec",fooreturnsi);
string getS(T...)(metastruct!T){
return metastruct!T.myS;
}
unittest{
vec!3 bar;
bar.foo.writeln;
}
```
`metastruct` has known arguments that I can trust to be there,
`fooreturnsi` can depend on`I` and could impliment op overloads,
then `vec` can be simplifications of the api, that still shares
an overload set so if I need to I can write meta code that see
everything `getS`
---
everything after this point is for context:
---
originally I asked ai; ai was dumb see here:
https://claude.ai/share/d794d2a6-7b52-4061-b83e-09a78730ac89
I then was considering this for a while:
```d
import std;
template foo(){
enum int bar=3;
void foobar(T)(T t)=>t.writeln;
}
unittest{
__traits(allMembers,foo!()).writeln;
}
template extend(alias A,string field,Args...){
static foreach(a;__traits(allMembers,A!())){
pragma(msg,a.stringof);
mixin("alias ",a,"=A!().",a,";");
}
mixin("alias ",field,"=Args;");
}
unittest{
alias bar=extend!(foo,"baz",int,float,bool);
bar.bar.writeln;
bar.baz.stringof.writeln;
}
```
this "extend" would've been verbose and incredibly slow to compile
adr in response suggested mixin templates,
---
code to clean up:
```d
#!opend test app.d
--- app.d
import std;
template defaultlensbehavoir(){
enum _offsetof(alias T)=T.offsetof;
enum _stringof(alias T)=T.stringof;
enum _typeid(alias T)=typeid(typeof(T));
alias introspectops=AliasSeq!(_offsetof,_typeid,_stringof);
int opCmp(T)(T a,T b){
static foreach(OP;introspectops){
if(mixin("a.",__traits(identifier,OP),"!=","b.",__traits(identifier,OP))){
return
mixin("a.",__traits(identifier,OP),"<","b.",__traits(identifier,OP))?1:-1;
}
}
return 0;
}
alias setIntersection=dynamicSetIntersection;
enum carrytypeinfo=false;
enum opassignpicky=false;
enum string makeerrormessage1(T,alias typethoery)="lol idk";
enum string[] traits=["dim"];
}
alias lens(types...)=lensexpert!(defaultlensbehavoir,types);
struct lensexpert(alias introspectionbehavoir,types...){
static struct introspectionpacket{
//alias T=types[0].tupleof[0];
static foreach(OP;introspectionbehavoir!().introspectops){
mixin("typeof(OP!(types[0].tupleof[0]))
",__traits(identifier,OP),";");
}
int opCmp(typeof(this)
b)=>introspectionbehavoir!().opCmp(this,b);
}
enum introspectionpacket[] makepacket(T)=(){
introspectionpacket[] output;
static foreach(A;T.tupleof){
output.length++;
static foreach(OP;introspectionbehavoir!().introspectops){
mixin("output[$-1].",__traits(identifier,OP),"=OP!A;");
}}
return output;
}();
enum introspectionpacket[][] packets=(){
introspectionpacket[][] output;
static foreach(T;types){
output~=makepacket!T;
//output.length++;
//static foreach(A;T.tupleof){
// output[$-1].length++;
// static foreach(OP;introspectionbehavoir!().introspectops){
// //__traits(getMember,output[$-1][$-1],OP.stringof/*.until('(').to!string*/)=OP!A;
// mixin("output[$-1][$-1].",__traits(identifier,OP),"=OP!A;");
}//}}
return output;
}();
enum introspectionpacket[]
typethoery=introspectionbehavoir!().setIntersection(packets).array;
//enum bool hasfield(string
s)=typethoery.map!(a=>a._stringof).canFind(s);
enum bool hasfield(string s)=(){return
typethoery.map!(a=>a._stringof).canFind(s);}();//??? `need `this`
to access member `map`` wtf?
//---
static if(introspectionbehavoir!().carrytypeinfo){
TypeInfo typeinfo;
}
void* where;
static foreach(trait;introspectionbehavoir!().traits){
mixin("typeof(types[0].",trait,") ",trait,";");
}
//---
void opAssign(T)(ref T t){
enum
ismatching=introspectionbehavoir!().setIntersection(makepacket!T,typethoery).count==typethoery.length;
//introspectionbehavoir!().setIntersection(makepacket!T,typethoery).writeln;
//ismatching.writeln;
static if( ! ismatching){
static if(introspectionbehavoir!().opassignpicky){
static
assert(0,introspectionbehavoir!().makeerrormessage1!(T,typethoery));
} else {
pragma(msg,"WARNING:"~introspectionbehavoir!().makeerrormessage1!(T,typethoery));
}}
//---
static if(introspectionbehavoir!().carrytypeinfo){
typeinfo=typeid(T);
}
where=&t;
static foreach(trait;introspectionbehavoir!().traits){
mixin(trait,"=T.",trait,";");
}
}
ref opDispatch(string field)() if (hasfield!field){
return mixin("(cast(types[0]*)where).",field);
}
}
struct vec2{
enum dim=2;
int x;
int y;
}
struct vec3{
enum dim=3;
int x;
int y;
int z;
}
struct vec99{
enum dim=99;
int x;
int y;
int z;
int w;
int[99] a;
}
struct vec1{int x; enum dim=1;}
struct vec2wrong{
enum dim=2;
int y;
int x;
}
unittest{
alias foo=lens!(vec2,vec3);
//foo.introspectionpacket.init.writeln;
//setIntersection(foo.packets[0],foo.packets[1]).writeln;
//foo.packets[1..$].fold!setIntersection(foo.packets[0]).writeln;
//foo.packets.writeln;
//foo.typethoery.writeln;
"---".writeln;
foo bar;
bar=new vec99();
bar.dim.writeln;
bar=new vec1();
bar=new vec2wrong();
bar.dim.writeln;
//foo.hasfield!"x".writeln;
bar.x=3;
assert(bar.x==3);
}
//--- ai code https://github.com/dlang/phobos/issues/11044
struct DynamicSetIntersection(alias less = "a < b", R)
if (isInputRange!R)
{
private:
R[] _input;
alias comp = binaryFun!less;
alias TElementType = ElementType!R;
void adjustPosition()
{
if (empty) return;
size_t done = _input.length;
if (_input.length > 1) while (true)
{
foreach (i; 0 .. _input.length)
{
ref r = _input[i];
ref next = _input[(i + 1) % _input.length];
if (comp(next.front, r.front))
{
do
{
next.popFront();
if (next.empty) return;
} while (comp(next.front, r.front));
done = _input.length;
}
if (--done == 0) return;
}
}
}
public:
///
this(R[] input)
{
this._input = input;
adjustPosition();
}
///
@property bool empty()
{
if (_input.length == 0) return true;
foreach (ref r; _input)
{
if (r.empty) return true;
}
return false;
}
///
void popFront()
{
assert(!empty, "Can not popFront of empty
DynamicSetIntersection");
debug
{
if (_input.length > 1)
{
foreach (i; 0 .. _input.length)
{
ref r = _input[i];
ref next = _input[(i + 1) % _input.length];
assert(!comp(r.front, next.front), "Set
elements must not contradict the less predicate");
}
}
}
foreach (ref r; _input)
{
r.popFront();
}
adjustPosition();
}
///
@property TElementType front()
{
assert(!empty, "Can not get front of empty
DynamicSetIntersection");
return _input[0].front;
}
static if (isForwardRange!R)
{
///
@property DynamicSetIntersection save()
{
auto ret = this;
ret._input = new R[_input.length];
foreach (i, ref r; _input)
{
ret._input[i] = r.save;
}
return ret;
}
}
}
/// Ditto
auto dynamicSetIntersection(alias less = "a < b",
RangeOfRanges...)(RangeOfRanges ranges)
{
static if(RangeOfRanges.length==1){
return DynamicSetIntersection!(less,
ElementType!RangeOfRanges)(ranges.array);
} else {
return setIntersection(ranges);
}
}
```
ai research chat:
https://claude.ai/share/2ce343e1-6210-4573-8def-2bb877f5078b
most watchable video Ive seen: https://youtu.be/a09aBGccUTE
More information about the Digitalmars-d-learn
mailing list