Thread overview
tuple parameter fwd
Aug 05, 2013
kdmult
Aug 06, 2013
kdmult
Aug 06, 2013
Ali Çehreli
Aug 06, 2013
kdmult
Aug 06, 2013
Ali Çehreli
Aug 06, 2013
kdmult
Aug 10, 2013
Artur Skawina
August 05, 2013
Hi,

I would like to use a tuple template parameter in the default value of another template parameter in the same class declaration as follows.

class A(P...) {}

class B(R = A!P, P...) {}

P... should be rightmost, so how can I use it in the preceding parameter?

Thanks.
August 06, 2013
On Monday, 5 August 2013 at 18:45:49 UTC, kdmult wrote:
> class A(P...) {}
>
> class B(R = A!P, P...) {}
>
> P... should be rightmost, so how can I use it in the preceding parameter?

The default parameter value doesn't make sense as it's shown above.
Actually I want to port C++ code which looks like below.

template <typename P1>
class A1 {};
template <typename P1, typename R=A1<P1> >
class B1 {}

template <typename P1, typename P2>
class A2 {};
template <typename P1, typename P2, typename R=A2<P1,P2> >
class B2 {}

and so on.

I would use the variadic template parameters. However, I have no idea how it can be done. Please advise.

Thanks.
August 06, 2013
On 08/05/2013 09:51 PM, kdmult wrote:
> On Monday, 5 August 2013 at 18:45:49 UTC, kdmult wrote:
>> class A(P...) {}
>>
>> class B(R = A!P, P...) {}
>>
>> P... should be rightmost, so how can I use it in the preceding parameter?
>
> The default parameter value doesn't make sense as it's shown above.
> Actually I want to port C++ code which looks like below.
>
> template <typename P1>
> class A1 {};
> template <typename P1, typename R=A1<P1> >
> class B1 {}
>
> template <typename P1, typename P2>
> class A2 {};
> template <typename P1, typename P2, typename R=A2<P1,P2> >
> class B2 {}
>
> and so on.
>
> I would use the variadic template parameters. However, I have no idea
> how it can be done. Please advise.
>
> Thanks.

Direct translation seems to work:

class A1(P1) {}
class B1(P1, R = A1!P1) {}

class A2(P1, P2) {}
class B2(P1, P2, R = A2!(P1, P2)) {}

void main()
{
    auto a1 = new A1!int;
    auto b1d = new B1!int;
    auto b1 = new B1!(int, A1!double);
    auto a2 = new A2!(int, double);
    auto b2d = new B2!(int, double);
    auto b2 = new B2!(int, double, A2!(char, short));
}

Ali

August 06, 2013
On Tuesday, 6 August 2013 at 05:07:51 UTC, Ali Çehreli wrote:
> On 08/05/2013 09:51 PM, kdmult wrote:
>> On Monday, 5 August 2013 at 18:45:49 UTC, kdmult wrote:
>>> class A(P...) {}
>>>
>>> class B(R = A!P, P...) {}
>>>
>>> P... should be rightmost, so how can I use it in the preceding parameter?
>>
>> The default parameter value doesn't make sense as it's shown above.
>> Actually I want to port C++ code which looks like below.
>>
>> template <typename P1>
>> class A1 {};
>> template <typename P1, typename R=A1<P1> >
>> class B1 {}
>>
>> template <typename P1, typename P2>
>> class A2 {};
>> template <typename P1, typename P2, typename R=A2<P1,P2> >
>> class B2 {}
>>
>> and so on.
>>
>> I would use the variadic template parameters. However, I have no idea
>> how it can be done. Please advise.
>>
>> Thanks.
>
> Direct translation seems to work:
>
> class A1(P1) {}
> class B1(P1, R = A1!P1) {}
>
> class A2(P1, P2) {}
> class B2(P1, P2, R = A2!(P1, P2)) {}
>
> void main()
> {
>     auto a1 = new A1!int;
>     auto b1d = new B1!int;
>     auto b1 = new B1!(int, A1!double);
>     auto a2 = new A2!(int, double);
>     auto b2d = new B2!(int, double);
>     auto b2 = new B2!(int, double, A2!(char, short));
> }
>
> Ali

Is there a way to use variadic template/class parameter instead
of P1, P2, ..., PN ? If it is I could create 2 templated classes
instead of all that copy/pasted classes with P1, P2, etc
parameters.

Thanks.
August 06, 2013
On 08/05/2013 11:45 AM, kdmult wrote:

> Hi,
>
> I would like to use a tuple template parameter in the default value of
> another template parameter in the same class declaration as follows.
>
> class A(P...) {}
>
> class B(R = A!P, P...) {}
>
> P... should be rightmost, so how can I use it in the preceding parameter?
>
> Thanks.

Do you mean that when P[0] is already an instance of A, then R should be P[0]. Otherwise, R should be A!P? If so, the following works:

class A(P...)
{
    pragma(msg, "\nA: " ~ P.stringof);
}

class BImpl(R, P...)
{
    pragma(msg, "R: " ~ R.stringof ~ ", P: " ~ P.stringof);
}

template B(P...)
{
    static if (is (P[0] == A!U, U)) {
        /* The first type is already an A instance. Accept the types as is. */
        alias B = BImpl!P;

    } else {
        /* The first type is not an A instance. Inject one. */
        alias B = BImpl!(A!P, P);
    }
}

void main()
{
    auto b0 = new B!(int, double, char);
    auto b1 = new B!(A!long, int, double);
}

Ali

August 06, 2013
On Tuesday, 6 August 2013 at 09:53:33 UTC, Ali Çehreli wrote:
> Do you mean that when P[0] is already an instance of A, then R should be P[0]. Otherwise, R should be A!P? If so, the following works:
>
> class A(P...)
> {
>     pragma(msg, "\nA: " ~ P.stringof);
> }
>
> class BImpl(R, P...)
> {
>     pragma(msg, "R: " ~ R.stringof ~ ", P: " ~ P.stringof);
> }
>
> template B(P...)
> {
>     static if (is (P[0] == A!U, U)) {
>         /* The first type is already an A instance. Accept the types as is. */
>         alias B = BImpl!P;
>
>     } else {
>         /* The first type is not an A instance. Inject one. */
>         alias B = BImpl!(A!P, P);
>     }
> }
>
> void main()
> {
>     auto b0 = new B!(int, double, char);
>     auto b1 = new B!(A!long, int, double);
> }
>
> Ali

Great! Thanks Ali.
August 10, 2013
On 08/05/13 20:45, kdmult wrote:
> Hi,
> 
> I would like to use a tuple template parameter in the default value of another template parameter in the same class declaration as follows.
> 
> class A(P...) {}
> 
> class B(R = A!P, P...) {}
> 
> P... should be rightmost, so how can I use it in the preceding parameter?

If you don't need to specify R explicitly just add an

    alias R = A!P;

inside B. Otherwise, you'll have to manually determine whether
R was given - it's not possible to automatically tell if the
first B parm is: a) R, or b) the first element of P. For example:

   class B(_P...) {
      static if (is(_P[0] _ == A!TP, TP...)) {
         alias R = _P[0];
         alias P = _P[1..$];
      }
      else {
         alias R = A!P;
         alias P = _P;
      }
      //...
   }

artur