== Quote from Philippe Sigaud (philippe.sig...@gmail.com)'s article > std.typecons is full of good stuff. I learnt quite a lot reading it. The Any > code gave many hours of reading, compiling the resulting code in my head, so > to say. Then I went a little mad ;) > My initial suggestion for your OP was a mixin to put in a class/struct to > make it extensible: using opDispatch to transform a method call > a.foo(args...) into the free function foo(a, args). That way a library > author makes her class extensible, and I, as a user, add free > functions-passing-as-methods as I see fit. > template MakeExtensible() > { > auto opDispatch(string s, Args...)(Args args) > if(is(typeof(mixin(s~"(this, args)")))) > { > mixin("return "~s~"(this, args);"); > } > } > It's a 3-line mixin, but it suffers from a nasty problem: opDispatch only > sees the symbols defined in the class modules, which forces the user to > define the free functions in the class module and that rather defeats the > point :( > The only solution I found was to make a wrapper template: struct (or class) > Extend!Type that will act as a Type in most cases and uses an opDispatch to > remain open. Note that 'alias this' has priority on opDispatch, so I > couldn't use alias this in this case: the free-functions-as-method calls > would be propagated to the wrapped struct/class and create an error there, > without being rerouted through opDispatch. > Anyway... > To solve the symbol-visibility problem, I made the whole machinery a > template, which should be mixed in the main module. > For the user, it's trivial, add: > mixin Extensible; > in your main module (or in any module you'll use free functions, but symbol > visibility will be affected ). You can then use extend(value) to get an > extensible version of a class or struct. > I have to complete to code to forward all operator calls to the wrapped > value, since I cannot use alias this. In the end, I project to extract this > part to make a generic ParallelType!Type wrapper that is not a subtype of > Type (as alias this would). Indeed ExtendType is just a parallel type wich > forward unknown methods to free functions. > Another proposal I have is a mixin that creates a string enum, Names, > containing the local scope qualified name. > module pack.mod; > mixin(ScopeName); // Names is "pack.mod" > int foo(int j) > { > mixin(ScopeName); // Names is "pack.mod.foo" > } > class C(A,B) > { > struct S > { > void method() > { > mixin(ScopeName); // Once C is instantiated Names is > "pack.mod.C!(type1, type2).S.method" > } > } > }
Isn't this a core language feature that's in the spec but is only currently implemented for arrays? I thought eventually uniform function call syntax was coming for classes and structs, too.