Thread overview
Initializing defaults based on type.
Mar 06, 2015
anon
Mar 06, 2015
Benjamin Thaut
Mar 06, 2015
Ali Çehreli
Mar 06, 2015
ketmar
Mar 06, 2015
Kagamin
Mar 06, 2015
Artur Skawina
Mar 06, 2015
Artur Skawina
Mar 07, 2015
anon
March 06, 2015
Hi,

I can't figure this out.

struct Pair(T)
{
   T x;
   T y;

   alias x c;
   alias y r;
}

What would like is that the x and y to be initialized to different values depending on type eg:

struct Container
{
  Pair!double sample1; // This will initialize sample1 with 0 for both x and y
  Pair!int    sample2; // This will initialize sample2 with 1 for both x and y
}

currently I'm using two different struct one with doubles and the other with ints and initialized with default value but was wondering if its possible to do the above.

anon



March 06, 2015
On Friday, 6 March 2015 at 15:36:47 UTC, anon wrote:
> Hi,
>
> I can't figure this out.
>
> struct Pair(T)
> {
>    T x;
>    T y;
>
>    alias x c;
>    alias y r;
> }
>
> What would like is that the x and y to be initialized to different values depending on type eg:
>
> struct Container
> {
>   Pair!double sample1; // This will initialize sample1 with 0 for both x and y
>   Pair!int    sample2; // This will initialize sample2 with 1 for both x and y
> }
>
> currently I'm using two different struct one with doubles and the other with ints and initialized with default value but was wondering if its possible to do the above.
>
> anon

struct Pair(T)
{
 static if(is(T == int))
   enum int initValue = 1;
 else
   enum T initValue = 0;

   T x = initValue;
   T y = initValue;

   alias x c;
   alias y r;
}
March 06, 2015
On 03/06/2015 08:04 AM, Benjamin Thaut wrote:
> On Friday, 6 March 2015 at 15:36:47 UTC, anon wrote:
>> Hi,
>>
>> I can't figure this out.
>>
>> struct Pair(T)
>> {
>>    T x;
>>    T y;
>>
>>    alias x c;
>>    alias y r;
>> }
>>
>> What would like is that the x and y to be initialized to different
>> values depending on type eg:
>>
>> struct Container
>> {
>>   Pair!double sample1; // This will initialize sample1 with 0 for both
>> x and y
>>   Pair!int    sample2; // This will initialize sample2 with 1 for both
>> x and y
>> }
>>
>> currently I'm using two different struct one with doubles and the
>> other with ints and initialized with default value but was wondering
>> if its possible to do the above.
>>
>> anon
>
> struct Pair(T)
> {
>   static if(is(T == int))
>     enum int initValue = 1;
>   else
>     enum T initValue = 0;
>
>     T x = initValue;
>     T y = initValue;
>
>     alias x c;
>     alias y r;
> }

Perhaps less cluttered:

enum PairInitValue(T : int) = 1;
enum PairInitValue(T : double) = 0;

struct Pair(T)
{
   T x = PairInitValue!T;
   T y = PairInitValue!T;

   alias x c;
   alias y r;
}

And an overengineered solution: :p

import std.typetuple;

alias PairInitValues = TypeTuple!(
    int, 1,
    double, 0,
);

string makePairInitValueDefinitions()
{
    import std.string;

    string result;

    foreach (i, e; PairInitValues) {
        static if (i % 2 == 0) {
            // This is a type
            result ~= format(`enum PairInitValue(T : %s) = `, e.stringof);

        } else {
            // this is a value
            result ~= format(`%s;`, e);
        }
    }

    return result;
}

mixin (makePairInitValueDefinitions());

struct Pair(T)
{
   T x = PairInitValue!T;
   T y = PairInitValue!T;

   alias x c;
   alias y r;
}

unittest
{
    auto p = Pair!int();
    assert(p.x == 1);
    assert(p.y == 1);
}

unittest
{
    auto p = Pair!double();
    assert(p.x == 0);
    assert(p.y == 0);
}

void main()
{}

Ali

March 06, 2015
On Fri, 06 Mar 2015 08:39:55 -0800, Ali Çehreli wrote:

> And an overengineered solution: :p

this is definitely the best.

March 06, 2015
On Friday, 6 March 2015 at 16:39:56 UTC, Ali Çehreli wrote:
> mixin (makePairInitValueDefinitions());

Oh, so that's how you do static foreach.
March 06, 2015
On 03/06/15 19:27, Kagamin via Digitalmars-d-learn wrote:
> On Friday, 6 March 2015 at 16:39:56 UTC, Ali Çehreli wrote:
>> mixin (makePairInitValueDefinitions());
> 
> Oh, so that's how you do static foreach.

No, you implement it using CTFE magic, and then that code becomes:

   import std.typetuple;

   alias PairInitValues = TypeTuple!(
       int, 1,
       double, 0,
   );

   #foreach (N; 0..PairInitValues.length/2) {
      enum PairInitValue(T:PairInitValues[$N*2]) = PairInitValues[$N*2+1];
   }

   struct Pair(T)
   {
      T x = PairInitValue!T;
      T y = PairInitValue!T;

      alias x c;
      alias y r;
   }


Seriously though, avoid using `.stringof` when generating code - it will break if the symbol is not available at the string-mixin scope.

artur
March 06, 2015
On 03/06/15 22:29, Artur Skawina wrote:
> No, you implement it using CTFE magic, and then that code becomes:

>    #foreach (N; 0..PairInitValues.length/2) {
>       enum PairInitValue(T:PairInitValues[$N*2]) = PairInitValues[$N*2+1];
>    }

> Seriously though, avoid using `.stringof` when generating code - it will break if the symbol is not available at the string-mixin scope.

Ie try to access the types/parms/etc directly; eg `PairInitValues[i]` will usually work, when `i` is a constant or a static-foreach variable.

[The code above obviously isn't plain D and won't work as-is w/o a magic
 ctfe preprocessor.]

artur
March 07, 2015
On Friday, 6 March 2015 at 16:04:33 UTC, Benjamin Thaut wrote:
> On Friday, 6 March 2015 at 15:36:47 UTC, anon wrote:
>> Hi,
>>
>> I can't figure this out.
>>
>> struct Pair(T)
>> {
>>   T x;
>>   T y;
>>
>>   alias x c;
>>   alias y r;
>> }
>>
>> What would like is that the x and y to be initialized to different values depending on type eg:
>>
>> struct Container
>> {
>>  Pair!double sample1; // This will initialize sample1 with 0 for both x and y
>>  Pair!int    sample2; // This will initialize sample2 with 1 for both x and y
>> }
>>
>> currently I'm using two different struct one with doubles and the other with ints and initialized with default value but was wondering if its possible to do the above.
>>
>> anon
>
> struct Pair(T)
> {
>  static if(is(T == int))
>    enum int initValue = 1;
>  else
>    enum T initValue = 0;
>
>    T x = initValue;
>    T y = initValue;
>
>    alias x c;
>    alias y r;
> }

Thanks