Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
November 06, 2012 Re: Extracting template parameters | ||||
---|---|---|---|---|
| ||||
On 11/06/2012 04:20 PM, Joseph Rushton Wakeling wrote:
> The use-case I'm thinking of is a function something like this (somewhat
> pseudo-code-y):
>
> auto fooToBar(FooInstance f)
> {
> Bar!(f.T1, f.T2, f.T3) b;
> // set values etc.
> return b;
> }
>
> Of course the f.T1 notation is my fiction, but it gives the idea of what is
> needed -- is there a means to extract and use template parameters in this way? I
> assume something from std.traits but it's not entirely clear what or how ...
Ideally this solution would work for non-identical lists of template parameters. E.g. for
Foo(T1, T2, T3, T4)
{
}
Bar(X1, X2)
{
}
I'd like to be able to instantiate something like: Bar!(f.T2, f.T4) [again, using my fictional notation].
|
November 06, 2012 Re: Extracting template parameters | ||||
---|---|---|---|---|
| ||||
On 11/06/2012 04:25 PM, Joseph Rushton Wakeling wrote: Look at the is() expression in the language spec. I didn't get it to work with a template constraint, because the pattern matched parameter are out of scope in the function body. ---- struct A(T1, T2) { } struct B(B1, B2) {} void foo(T)(T x) { static if(is(T Dummy : A!(P), P...)) { pragma(msg, P); } } void main() { A!(int, float) a; foo(a); } |
November 06, 2012 Re: Extracting template parameters | ||||
---|---|---|---|---|
| ||||
On 2012-11-06, 16:20, Joseph Rushton Wakeling wrote: > Suppose that I have two struct templates which take identical parameter lists: > > struct Foo(T1, T2, T3) > { > ... > } > > struct Bar(T1, T2, T3) > { > ... > } > > Now suppose that I have a Foo which has been instantiated with a given set of parameters. Is there any way for me to say, "now instantiate a Bar with the same parameters?" > > The use-case I'm thinking of is a function something like this (somewhat pseudo-code-y): > > auto fooToBar(FooInstance f) > { > Bar!(f.T1, f.T2, f.T3) b; > // set values etc. > return b; > } > > Of course the f.T1 notation is my fiction, but it gives the idea of what is needed -- is there a means to extract and use template parameters in this way? I assume something from std.traits but it's not entirely clear what or how ... In addition to Dan's answer, let me present a general solution: template InstantiationInfo( T ) { static if ( is( T t == U!V, alias U, V... ) ) { alias U Template; alias V Parameters; } else { static assert(false, T.stringof ~ " is not a template type instantiation."); } } With this, you can extract the parameters to a template (InstantiationInfo!Foo.Parameters) or the template used (InstantiationInfo!Foo.Template). -- Simen |
November 06, 2012 Re: Extracting template parameters | ||||
---|---|---|---|---|
| ||||
On Tue, Nov 06, 2012 at 04:20:34PM +0100, Joseph Rushton Wakeling wrote: > Suppose that I have two struct templates which take identical parameter lists: > > struct Foo(T1, T2, T3) > { > ... > } > > struct Bar(T1, T2, T3) > { > ... > } > > Now suppose that I have a Foo which has been instantiated with a given set of parameters. Is there any way for me to say, "now instantiate a Bar with the same parameters?" You could alias the parameters so that they're accessible from outside: struct Foo(T1, T2, T3) { alias T1 t1; alias T2 t2; alias T3 t3; ... } struct Bar(X1, X2) { ... } auto fooToBar(FooInstance)(FooInstance f) { return Bar!(f.t2, f.t3)(); } This works if T1, T2, T3 are types. If they're values, you'll need to use enums in Foo instead. T -- There are three kinds of people in the world: those who can count, and those who can't. |
November 06, 2012 Re: Extracting template parameters | ||||
---|---|---|---|---|
| ||||
On 11/6/12, Simen Kjaeraas <simen.kjaras@gmail.com> wrote:
> In addition to Dan's answer, let me present a general solution:
>
> template InstantiationInfo( T ) {
> static if ( is( T t == U!V, alias U, V... ) ) {
> alias U Template;
> alias V Parameters;
> } else {
> static assert(false, T.stringof ~ " is not a template type
> instantiation.");
> }
> }
I think Kenji fixed this recently because it didn't work several releases ago. You can now do cool things with template constraints. For example if you want to limit a template to only allow types that are instances of a specific template you can do:
struct Foo(T...) { }
struct Bar(T)
if (is(T x == Foo!X, X...)) // T must be a Foo instance
{
}
struct Other(T...) { }
void main()
{
alias Bar!(Foo!int) A; // ok
alias Bar!(Other!int) B; // fail
}
|
Copyright © 1999-2021 by the D Language Foundation