On Sunday, 25 October 2020 at 12:02:10 UTC, Ali Çehreli wrote:
On 10/25/20 4:30 AM, frame wrote:
Is there a possibility to write templated code / custom trait pattern with usage like a delegate?

I have a try-catch block with different types and don't want to repeat myself in every method again. It's always the same, just what's tried changes, eg.:

pseudo code:

template myStuff(mixin code)
{
     try {
         code();
     }
     catch (X e) {
         ...
     }
     catch (Y e) {
         ...
     }
     ...
}

static myStuff!({
    writeln("...");
});


That's one of my DConf Onlide slides but for a limited use case! :)

int tried(Func, string functionName = __FUNCTION__, string file = __FILE__, size_t line = __LINE__)(Func func) {
  static if (!is (ReturnType!Func == int)) {
pragma(msg, format!"\n%s(%s): Error: %s must return int error code"(file, line, functionName));
    static assert(false);
  }

  void printError(T)(T err) {
stderr.writefln!"\n%s(%s): Failed to execute %s: %s"(file, line, functionName, err);
  }

  try {
    return func();

  } catch (Exception exc) {
    printError(exc.msg);
    return 1;

  } catch (Error err) {
    printError(err);
    import core.stdc.stdlib : abort;
    abort();
  }

  assert(false);
}

Then, all extern(C) functions would be written the same way:

extern(C) int foo() {
  return tried({
    // ...
    return 0;
  });
}

Ali

I see that your approach can handle functions and delegates but isn't that not equivalent like this template for a function?

auto myStuff(T)(T function() fn) {
    try {
        return fn();
    }
    catch (Exception e) {
        //
    }
}

I wonder if I could use such a template as static variant and the compiler just expands the code? Just thinking that using a function or delegate is an overhead. Maybe not a function but a delegate will allocate GC memory I think.

Reply via email to