Thread overview
How to specity a list of fields with default to a mixin template?
17 hours ago
realhet
13 hours ago
monkyyy
13 hours ago
Inkrementator
17 hours ago

Hello,

mixin template T(string def, alias C = typeof(mixin("new class{"~def~"}")))
{
    enum generatedStr = FieldTypeTuple!C.stringof;
}

void main()
{
    {
    	mixin T!"int a, b;";
        pragma(msg, generatedStr);  //works
    }
    {
	    struct LocalStruct(){ int aaa; }
        mixin T!"LocalStruct ls;";  //can't see localStruct
    	pragma(msg, generatedStr);
    }
}

Is there a way to capture local scope in templates?

I've tried to put the expansion of the field declaration into the template parameter list, but it is still can't see my local types.

My problem is that I already have a robust Class field/constructor/declarator/parent/child/list generator thing, and I choosed to specify the list of field declaration by mixing in a string into a D construct. I tried function parameters, and now in the example, there is a mixed in anonym class.

But now in whatever modules I want to use my 'Smart" classes I have to replicate this same header code to ensure it can see the local declarations.

Now it was good for half a year, but today I found out that if a module with a generator template uses another module with a generator template, the imported module will have 2 generators and wil fail.

I would be able to solve this by:

mixin genFields!(AliasSeq!(int, string), ["field1", "field2"], AliasSeq!(5, "str"/+default values+/));

But this is not so nice.

This is the nice form:

mixin genFields!"int field1=5; string field2=`str`;";

But I unable to find a way to parse this declaration in the scope where my types are.
I have to copy the genFields template into whatever module I want to use it, and I must be careful not to import 2 or more genFields to the same scope.

Anyone have an idea?

13 hours ago

On Sunday, 2 March 2025 at 19:31:06 UTC, realhet wrote:

>

Anyone have an idea?

Such things are extremely discouraged and I could suggest maybe 3 hacks

>

But I unable to find a way to parse this declaration in the scope where my types are.

--- foo.d
import std;
public import bar;
myint fizz;

import foobar;
unittest{
	makeconstructor!("myint buzz;") hello;
	//hello.importstring.writeln;
	hello.buzz=3;
}
--- bar.d

alias myint=int;

--- foobar.d

string parseimport(string s){
	return s[0..$-2];
}
	
template makeconstructor(string s,string file=__FILE__){
	struct makeconstructor{
	//enum importstring="import "~file.parseimport~";";
	mixin("import "~file.parseimport~";");
	mixin(s);
	}
}

if its global scope you have this option

13 hours ago

On Sunday, 2 March 2025 at 19:31:06 UTC, realhet wrote:

>

Anyone have an idea?

While template mixins have access to the caller scope, the default values for parameters apparently don't. If you inline the default value, it will work

import std.traits;
mixin template T(string def)
{
	enum generatedStr = FieldTypeTuple!(typeof(mixin("new class{"~def~"}"))).stringof;
}

void main()
{
	mixin T!"int a, b;" mixin1;
	pragma(msg, mixin1.generatedStr);
	struct LocalStruct{ int aaa; }
	mixin T!"LocalStruct ls;" mixin2;
	pragma(msg, mixin2.generatedStr);
}