On Monday, 15 April 2019 at 08:39:24 UTC, Anton Fediushin wrote:
Hello! I am currently trying to add a custom `toString` method to an enum so that: 1. Enum members would still have numeric values and can be easily compared (things like `enum a { foo = "FOO", bar = "BAR”}` won't do, I want `a.foo < a.bar)`)
2. More custom methods can be implemented in the future

Obvious solution is to wrap an enum in a structure and utilize 'alias this' for subtyping like this:
```
struct Enum {
  private {
    enum internal {
      foo,
      bar
    }
    internal m_enum;
  }
  this(internal i) { m_enum = i; }
  alias m_enum this;
  string toString() {
    // custom implementation of toString
  }
}
```

This seems to work just fine for assigning and comparisons but passing Enum as a function argument does not work:
```
void fun(Enum e) {}

fun(Enum.foo);
---
Error: function fun(Enum e) is not callable using argument types (internal)
Cannot pass argument foo of type internal to parameter Enum e.
```

Of course, I could just define a bunch of functions that accept my enum as the first argument and call them using UFCS but it'd require to explicitly specify functions instead of D taking care of that (toString() for structures is called automagically by functions like writeln) and those functions would hang around here and there totally unorganized. I prefer to keep functions inside of structures and classes.

If there are other ways of achieving the same *and* keeping code clean and organized, please share.

Thank you in advance,
Anton.


Should have been

struct _Enum(T)
{
        T value;
        alias value this;
        static foreach(e, v; EnumMembers!T)
mixin("static T "~to!string(v)~" = cast(_Enum)(T."~to!string(v)~");");
}

Reply via email to