1 interface PackageSupplier 2 { 3 int foo(); 4 int bar(); 5 } 6 7 static abstract class AbstractFallbackPackageSupplier : PackageSupplier 8 { 9 protected PackageSupplier default_, fallback; 10 11 this(PackageSupplier default_, PackageSupplier fallback) 12 { 13 this.default_ = default_; 14 this.fallback = fallback; 15 } 16 17 abstract int foo(); 18 abstract int bar(); 19 } 20 21 template fallback(T, alias func) 22 { 23 import std.format : format; 24 // for all implemented methods: 25 // - try default first 26 // - only on a failure run & return fallback 27 enum fallback = q{ 28 scope (failure) return fallback.%1$s(args); 29 return default_.%1$s(args); 30 }.format(__traits(identifier, func)); 31 } 32 33 // combines two classes and use the second one as fallback 34 alias FallbackPackageSupplier = AutoImplement!(AbstractFallbackPackageSupplier, fallback); 35 36 class FailingPackageSupplier : PackageSupplier 37 { 38 int foo(){ throw new Exception("failure"); } 39 int bar(){ return 2;} 40 } 41 42 class BackupPackageSupplier : PackageSupplier 43 { 44 int foo(){ return -1; } 45 int bar(){ return -1;} 46 } 47 48 auto registry = new FallbackPackageSupplier(new FailingPackageSupplier(), new BackupPackageSupplier()); 49 50 assert(registry.foo() == -1); 51 assert(registry.bar() == 2);
AutoImplement automatically implements (by default) all abstract member functions in the class or interface Base in specified way.
The second version of AutoImplement automatically implements Interface, while deriving from BaseClass.