Jump to page: 1 2 3
Thread overview
Simplify some C-style code
Dec 25
sfp
Dec 25
monkyyy
Dec 25
sfp
Dec 25
user1234
Dec 25
sfp
Dec 25
monkyyy
Dec 25
sfp
Dec 25
monkyyy
Dec 25
monkyyy
Dec 25
monkyyy
Dec 28
monkyyy
Dec 29
monkyyy
9 hours ago
Nick Treleaven
Dec 25
sfp
Dec 26
bauss
Dec 26
sfp
10 hours ago
sfp
December 25

I have some code like this:

enum DomainType {
  Ball,
  Box,
  CsgDiff
}

struct Domain(int Dim) {
  DomainType type;
  union {
    Ball!Dim ball;
    Box!Dim box;
    CsgDiff!Dim csgDiff;
  }

  this(Ball!Dim ball) {
    this.type = DomainType.Ball;
    this.ball = ball;
  }

  this(Box!Dim box) {
    this.type = DomainType.Box;
    this.box = box;
  }

  this(CsgDiff!Dim csgDiff) {
    this.type = DomainType.CsgDiff;
    this.csgDiff = csgDiff;
  }

  void doSomething() {
    switch (type) {
    case DomainType.Ball:
      ...
      break;
    case DomainType.Box:
      ...
      break;
    case DomainType.CsgDiff:
      ...
      break;
    }
  }
}

Is there some way I can reduce the amount of boilerplate using D, i.e. generate most of this code at compile time?

For what it's worth, I had checked out SumType as an alternative to this mess, but it doesn't play nicely with recursively defined types.

December 25

On Wednesday, 25 December 2024 at 07:49:28 UTC, sfp wrote:

>

I have some code like this:

enum DomainType {
  Ball,
  Box,
  CsgDiff
}

struct Domain(int Dim) {
  DomainType type;
  union {
    Ball!Dim ball;
    Box!Dim box;
    CsgDiff!Dim csgDiff;
  }

  this(Ball!Dim ball) {
    this.type = DomainType.Ball;
    this.ball = ball;
  }

  this(Box!Dim box) {
    this.type = DomainType.Box;
    this.box = box;
  }

  this(CsgDiff!Dim csgDiff) {
    this.type = DomainType.CsgDiff;
    this.csgDiff = csgDiff;
  }

  void doSomething() {
    switch (type) {
    case DomainType.Ball:
      ...
      break;
    case DomainType.Box:
      ...
      break;
    case DomainType.CsgDiff:
      ...
      break;
    }
  }
}

Is there some way I can reduce the amount of boilerplate using D, i.e. generate most of this code at compile time?

For what it's worth, I had checked out SumType as an alternative to this mess, but it doesn't play nicely with recursively defined types.

static foreach, traits and mixin

December 25

On Wednesday, 25 December 2024 at 07:57:04 UTC, monkyyy wrote:

>

static foreach, traits and mixin

I was looking into this but I think I need some help getting off the ground...

This doesn't compile:

enum Test { mixin("A, B, C") }
December 25

On Wednesday, 25 December 2024 at 16:41:05 UTC, sfp wrote:

>

On Wednesday, 25 December 2024 at 07:57:04 UTC, monkyyy wrote:

>

static foreach, traits and mixin

I was looking into this but I think I need some help getting off the ground...

This doesn't compile:

enum Test { mixin("A, B, C") }

Mixins can only introduce certain type of nodes: Type, Declaration, Expression, and Statement. Honestly I dont see how would they help here... What you can do however is to use https://dlang.org/phobos/std_sumtype.html. instead of a the manually defined tagged union.

December 25

On Wednesday, 25 December 2024 at 17:20:01 UTC, user1234 wrote:

>

On Wednesday, 25 December 2024 at 16:41:05 UTC, sfp wrote:

>

On Wednesday, 25 December 2024 at 07:57:04 UTC, monkyyy wrote:

>

static foreach, traits and mixin

I was looking into this but I think I need some help getting off the ground...

This doesn't compile:

enum Test { mixin("A, B, C") }

Mixins can only introduce certain type of nodes: Type, Declaration, Expression, and Statement. Honestly I dont see how would they help here... What you can do however is to use https://dlang.org/phobos/std_sumtype.html. instead of a the manually defined tagged union.

Unfortunately, std.sumtype doesn't seem to work for my case. I want to be able to define several mutually recursive types. It seems the only way to define a recursive type using std.sumtype is the This parameter. For instance, this doesn't work:

alias Blah = SumType!(A);
struct A { Blah *b; }

Throws an error about recursive template expansion or something.

December 25

On Wednesday, 25 December 2024 at 16:41:05 UTC, sfp wrote:

>

On Wednesday, 25 December 2024 at 07:57:04 UTC, monkyyy wrote:

>

static foreach, traits and mixin

I was looking into this but I think I need some help getting off the ground...

This doesn't compile:

enum Test { mixin("A, B, C") }

import std;
enum string[] domains=["Ball","Box","CsgDiff"];//could be from traits but I think traits when strings will do is bad
enum string[] lowerdomains=["ball","box","csgDiff"];//could be ctfe but... eh

mixin("enum DomainType{"~domains.joiner(",").array~"}");//array makes allot of range code simpler to work with, at costs of speed
string makeunion(){
	string o;
	o~="union{";
	foreach(i;0..domains.length){
	 o~=domains[i]~"!Dim ";
		o~=lowerdomains[i]~";";
	}
	o~="}";
	return o;
}
string makeconstructor(int i){
	string o;
	o~="this("~domains[i]~"!Dim "~lowerdomains[i]~"){\n";
	o~="this.type=DomainType."~domains[i]~";\n";
	o~="this."~lowerdomains[i]~"="~lowerdomains[i]~";}";
	return o;
}
unittest{
	//makeconstructor(1).writeln;
}
struct Ball(int i){}
struct Box(int i){}
struct CsgDiff(int i){}
struct Domain(int Dim){
	DomainType type;
	mixin(makeunion);
	static foreach(i;0..domains.length){
		mixin(makeconstructor(i));
	}
	void doSomething(){
		lable:switch(type){
			static foreach(E;DomainType.min..DomainType.max){
				case E: E.stringof.writeln; break lable;
			}
		default:
	}}
}
unittest{
	auto foo=Domain!1(Ball!1());
	foo.doSomething;
}
December 25

On Wednesday, 25 December 2024 at 17:20:01 UTC, user1234 wrote:

>

What you can do however is to use https://dlang.org/phobos/std_sumtype.html. instead of a the manually defined tagged union.

If he's struggling to define a enum with a mixin I assume he's very new and to get this code to work with sumtype would require a template map, which would make you a highly competent template wizard

December 25

On Wednesday, 25 December 2024 at 17:46:01 UTC, monkyyy wrote:

>

On Wednesday, 25 December 2024 at 17:20:01 UTC, user1234 wrote:

>

What you can do however is to use https://dlang.org/phobos/std_sumtype.html. instead of a the manually defined tagged union.

If he's struggling to define a enum with a mixin I assume he's very new and to get this code to work with sumtype would require a template map, which would make you a highly competent template wizard

Thanks for fleshing out an example for me. That's a big help. Understanding that mixin only works for certain AST nodes is useful... but kind of weird that it doesn't work inside enum. Seems like an obvious application...

I'm an experienced programmer but new to D. I've done a decent amount of template metaprogramming in C++, but not really a wizard there either. Just enough to be dangerous (mostly to myself).

What is a template map? I'd be interested in seeing this pattern and whether it's worth it to try to salvage std.sumtype.

I also saw a thread about a language level (possibly?) sumtype. Is this feature going to resolve the This parameter grossness?

December 25

On Wednesday, 25 December 2024 at 18:25:57 UTC, sfp wrote:

>

What is a template map? I'd be interested in seeing this pattern and whether it's worth it to try to salvage std.sumtype.

import std;
struct Ball(int i){}
struct Box(int i){}
struct CsgDiff(int i){}
alias dimlist(int dim)=AliasSeq!(Ball!dim,Box!dim,CsgDiff!dim);
alias dimedsumtype(int dim)=SumType!(dimlist!dim);
alias genfunction(T)=(T t)=>t.writeln;
void doSomething(int dim)(dimedsumtype!dim st){
    st.match!(
        staticMap!(genfunction,dimlist!dim)
    );
}
unittest{
    dimedsumtype!1 foo;
    foo.doSomething!1;
}

You will need to read the template book to even begin to understand, I had to work around what seems to me to be a compiler bug to get it to compile, and the number of people who can help you drop to like 5

https://github.com/PhilippeSigaud/D-templates-tutorial

December 25

On Wednesday, 25 December 2024 at 16:41:05 UTC, sfp wrote:

>

On Wednesday, 25 December 2024 at 07:57:04 UTC, monkyyy wrote:

>

static foreach, traits and mixin

I was looking into this but I think I need some help getting off the ground...

This doesn't compile:

enum Test { mixin("A, B, C") }

No, but mixin("enum Test {", "A, B, C", "}"); does. There are mixin statements, which that is, and there are mixin expressions, which you tried, but you can't put an expression there and A, B, C isn't one. I suggest reading the spec rather than just trying random things.

« First   ‹ Prev
1 2 3