digitalmars.D.learn - String of templated struct at compile time
- divi (32/32) Sep 19 2019 Due to prior design choices, I have the following setup:
- Adam D. Ruppe (33/39) Sep 19 2019 Just how constrained are you? I'd be inclined to completely
- divi (7/11) Sep 19 2019 I didn't know that, and it explains a lot. I can be flexible on
- divi (14/14) Sep 19 2019 You know what, just because I want to watch the world burn I did
- Adam D. Ruppe (2/3) Sep 19 2019 gross but hey if it works it works
Due to prior design choices, I have the following setup:
enum K { A, B }
mixin template Magic()
{
   mixin(`alias Other = ` ~ magic() ~ `!(K.B);`);
}
struct S(K k) if (k == K.B) {}
struct S(K k)
   if (k == K.A)
{
   mixin Magic; // magic() returns "S"
}
struct T(K k) if (k == K.B) {}
struct T(K k)
   if (k == K.A)
{
   mixin Magic; // magic() returns "T"
}
alias A(alias T) = T!(K.A);
void main()
{
   A!S a;
}
Is there any possible way I can write magic() so that the above 
code works as intended? n.b. it must be able to go through the 
alias A.
For what it's worth, I'm trying to define "Other" for the generic 
struct parameterised with k == K.A such that I can instantiate 
it's sister struct parameterised by K.B, e.g.
A!S a; // type is S!(K.A)
alias U = a.Other;
U b; // type is S!(K.B)
 Sep 19 2019
On Thursday, 19 September 2019 at 19:49:02 UTC, divi wrote:
 Due to prior design choices, I have the following setup:
 enum K { A, B }
 mixin template Magic()
 {
   mixin(`alias Other = ` ~ magic() ~ `!(K.B);`);
 }
Just how constrained are you? I'd be inclined to completely 
remove the magic() function and make it something like this:
mixin template Magic()
{
   static if(is(typeof(this) == T!(A), alias T, A...))
         alias Other = T!(K.B);
   else
         static assert(0);
}
But then you also need to change the constraint to something more 
along these lines:
struct S(K k)
{
   static if (k == K.A)
     mixin Magic; // now makes S!(K.B)
}
That is, moving the if from a constraint outside to a static if 
inside. The reason for this is kinda crazy: the token `S` inside 
that struct (and thus inside its template mixin) refers to the 
*current instantiation*. Which includes the conflicting 
constraint.
I don't know if there's a way around that. I think it is a minor 
design flaw in the language personally and would love to see it 
changed... but I don't know if you can work around it directly, 
even with mixin strings and external helpers, since the 
constraint is even copied in the .stringof! Well, I guess you 
could slice the string on the first " " and cut that stuff off 
and maybe convince the compiler to look up the template at top 
level again. That'd probably work but is liable to maybe getting 
lost in aliases.
If changing that constraint is possible though you can get a 
reasonably robust solution.
 Sep 19 2019
On Thursday, 19 September 2019 at 20:16:49 UTC, Adam D. Ruppe wrote:The reason for this is kinda crazy: the token `S` inside that struct (and thus inside its template mixin) refers to the *current instantiation*. Which includes the conflicting constraint.I didn't know that, and it explains a lot. I can be flexible on this and hadn't thought about moving the constraint inside the struct. It doesn't seem as aesthetically pleasing but would probably result in a better API I suppose. Thanks Adam!
 Sep 19 2019
You know what, just because I want to watch the world burn I did 
the horrible hacky way.
mixin template Magic()
{
   import std.array : split;
   static if (is(typeof(this) == T!(A), alias T, A...)) {
     mixin(`alias Other = ` ~ T.stringof.split('(')[0] ~ 
`!(K.B);`);
   }
   else
   {
     static assert (0);
   }
}
 Sep 19 2019
On Thursday, 19 September 2019 at 21:55:57 UTC, divi wrote:You know what, just because I want to watch the world burngross but hey if it works it works
 Sep 19 2019








 
  
  
  Adam D. Ruppe <destructionator gmail.com>
 Adam D. Ruppe <destructionator gmail.com>