Thread overview
Passing variadic template parameters AND default call site __FILE__, __LINE__ template parameters.
2 days ago
realhet
2 days ago
monkyyy
2 days ago
realhet
2 days ago
monkyyy
1 day ago
realhet
1 day ago
realhet
1 day ago
realhet
1 day ago
monkyyy
2 days ago

Hello,

template T1(string FILE=__FILE__, size_t LINE=__LINE__, A...)
{
enum T1 = FILE ~ LINE.text ~ A.text;
}

pragma(msg, T1!(__FILE__,__LINE__, "hello", " world")); //works
pragma(msg, T1!(__FILE__,__LINE__,i"Hello $("World")")); //works
pragma(msg, T1!(i"Hello $("World")")); //error: does not match template declaration `T1(string FILE = __FILE__, ulong LINE = __LINE__, A...)`

After "A..." I can't put anything, so it seems it is impossible to combine the two superpowers: call site evaluation and variadic template parameters.

I can do similar functionality by function evaluation, but not with template instantiation.
Is there a way to do this functionality?

2 days ago

On Tuesday, 27 May 2025 at 10:20:40 UTC, realhet wrote:

>

Hello,

template T1(string FILE=__FILE__, size_t LINE=__LINE__, A...)
{
enum T1 = FILE ~ LINE.text ~ A.text;
}

pragma(msg, T1!(__FILE__,__LINE__, "hello", " world")); //works
pragma(msg, T1!(__FILE__,__LINE__,i"Hello $("World")")); //works
pragma(msg, T1!(i"Hello $("World")")); //error: does not match template declaration `T1(string FILE = __FILE__, ulong LINE = __LINE__, A...)`

After "A..." I can't put anything, so it seems it is impossible to combine the two superpowers: call site evaluation and variadic template parameters.

I can do similar functionality by function evaluation, but not with template instantiation.
Is there a way to do this functionality?

import std;
template T2(string FILE=__FILE__, size_t LINE=__LINE__){
template T2(A...){
	alias T2=T1!(FILE,LINE,A);
}}
template T1(string FILE=__FILE__, size_t LINE=__LINE__,A...){
	enum T1 = FILE ~ LINE.text ~ A.text;
}
alias t2=T2!();
pragma(msg, t2!(i"Hello $("World")"));


/*
import std;
void main(){
	foreach(i;0..8){
		"alias a".write;
		i.write;
		"=void,".write;
}}
*/
template T3(alias a0=void,alias a1=void,alias a2=void,alias a3=void,alias a4=void,alias a5=void,alias a6=void,alias a7=void,string FILE=__FILE__, size_t LINE=__LINE__){
	alias A=AliasSeq!();
	static foreach(int I;0..8){
		alias B(int J:I)=mixin("a"~I.stringof);
		static if( ! is(B!I==void)){
			A=AliasSeq!(A,B!I);
	}}
	alias T3=T1!(FILE,LINE,A);
}

pragma(msg, T3!(i"goodbye $("World")"));


template pack(A...){
	alias unpack=A;
}
alias T4(alias A,string FILE=__FILE__, size_t LINE=__LINE__)=T1!(FILE,LINE,A.unpack);
pragma(msg, T4!(pack!(i"farwell $("World")")));
2 days ago

On Tuesday, 27 May 2025 at 15:01:38 UTC, monkyyy wrote:

>

On Tuesday, 27 May 2025 at 10:20:40 UTC, realhet wrote:

Hi and thanks for trying!

t2!(x) //The problem with this is the LINE will point to the alias declaration, not the pragma.

Interesting trick: template nested inside a template.

T3!(x) //This works perfectly, but the 8 alias has a really low limit on the contents of the IES string: 3 $() blocks and it's out of parameters. Maybe if I generate this template with a string mixin, but I'm affraid the compiler would go crazy. I'm planning to use it with 1000 lines of shader code and lots of constanst injected into that with $().

Interesting tricks: alias reassignment and templateParameterValueSpecialization (wow! It avoids the redeclaration error I normally get.).

T4!(pack!(x)) //Unlike T3, it has no limitations but it needs an extra work at the call site. The simplest extra work is manually writing FILE,LINE btw.

Interesting trick: How to pack a whole AliasSeq into a single slot. I got to rememper this, it's so cool. template pack(A...) { alias unpack=A; }

Final thoughts: I think the only conflict is on the language level, as the data form FILE and LINE are always accessible inside the compiler. But maybe in the future there will be a __traits for this. And also for COLUMN. But I also understand that these simple looking things are super complicated inside the compiler.

Thx for the template tricks!

2 days ago

On Tuesday, 27 May 2025 at 21:07:51 UTC, realhet wrote:

>

Interesting tricks: alias reassignment and templateParameterValueSpecialization (wow! It avoids the redeclaration error I normally get.).

There bugs here, it works in this case(I have theories why) and in opend its considered a regression and adr will undo "optimizations"; but this is unstable and considered unimportant by the core devs

Specialization as a lookup table is valid. Trying to escape references to static forloop, risky.

1 day ago

On Tuesday, 27 May 2025 at 21:16:57 UTC, monkyyy wrote:

>

On Tuesday, 27 May 2025 at 21:07:51 UTC, realhet wrote:

I stay in safety and choose this way:

enum _LOCATION_(string FILE=__FILE__, size_t LINE=__LINE__) = FILE~'('~LINE.text~",1)";

enum loc1 = (_LOCATION_!());
enum loc2 = (_LOCATION_!());

We just can't eliminate the !() with alias, it's mandatory.

And I write this signature (_LOCATION_!()) to every place where it is needed. But not by myself, by my machine. It will be hidden in my editor to reduce visual noise.

Maybe I can make it more type-safe by not returning a string "file.d(12,1)", but returning a struct. Howerer IES also starts and ends with special structs, easy to detect those.

1 day ago

On Wednesday, 28 May 2025 at 10:13:43 UTC, realhet wrote:

>

On Tuesday, 27 May 2025 at 21:16:57 UTC, monkyyy wrote:

>

On Tuesday, 27 May 2025 at 21:07:51 UTC, realhet wrote:

I've found a way to eliminate !() by using a function:

struct LOCATION_t2
{
    string location;
    string toString() const => location;
}

auto LOC2(string FILE=__FILE__, size_t LINE=__LINE__)
=> LOCATION_t2(FILE~'('~LINE.text~",1)");

pragma(msg, LOC2);				//LOCATION_t2("onlineapp.d(28,1)")
pragma(msg, LOC2.text);			//onlineapp.d(29,1)
pragma(msg, i"$(LOC2)");		//AliasSeq!(InterpolationHeader(), InterpolatedExpression(), LOC2, InterpolationFooter()) //!no line number
pragma(msg, i"$(LOC2)".text);	//onlineapp.d-mixin-31(31,1)  //!!line number is still there!

Also encapsulating it in a struct, so it's safer because (LOCATION_t2 != string).

I love this LEGO set :]

1 day ago
On Wednesday, May 28, 2025 5:04:06 AM Mountain Daylight Time realhet via Digitalmars-d-learn wrote:
> I've found a way to eliminate !() by using a function:

Just FYI, you almost never want to instantiate a template with a file and line number anyway, because that means that every single template instantiation is going to be unique, and that's going to mean a lot of template bloat.

Once in a blue moon, you do need the file or line number to be a template argument, but it's pretty much always better to make them function arguments if you can.

- Jonathan M Davis




1 day ago
On Wednesday, 28 May 2025 at 11:32:53 UTC, Jonathan M Davis wrote:
> On Wednesday, May 28, 2025 5:04:06 AM Mountain Daylight Time realhet via Digitalmars-d-learn wrote:
Yes, most of the time I can put __FILE__ and __LINE__ onto a runtime function parameter.

But this time it is a requirement:
I must write the __FILE__ and __LINE__ with pragma(msg, ...)

Update: I can only avoid !() when I'm in the same module.  When importing that function, into another module, there will be an implicit alias and it will lock onto a single __FILE__  __LINE__ location inside the imported module.



1 day ago
On Wednesday, 28 May 2025 at 11:32:53 UTC, Jonathan M Davis wrote:
> On Wednesday, May 28, 2025 5:04:06 AM Mountain Daylight Time realhet via Digitalmars-d-learn wrote:
>> I've found a way to eliminate !() by using a function:
>
> Just FYI, you almost never want to instantiate a template with a file and line number anyway, because that means that every single template instantiation is going to be unique, and that's going to mean a lot of template bloat.

Dememoization is necessary for lots of things.