1 /** 2 * Method binding - using alias inference patch 3 * Currently dysfunctional. 4 * 5 * License: 6 * This Source Code Form is subject to the terms of 7 * the Mozilla Public License, v. 2.0. If a copy of 8 * the MPL was not distributed with this file, You 9 * can obtain one at http://mozilla.org/MPL/2.0/. 10 * 11 * Authors: 12 * Vladimir Panteleev <ae@cy.md> 13 */ 14 15 module ae.utils.meta.binding; 16 17 import ae.utils.meta : thisOf; 18 import ae.utils.meta.caps; 19 import ae.utils.meta.reference; 20 21 /// TODO: update to use the new __traits(child) 22 23 deprecated: 24 25 /// Create unbound functor of a method 26 template unboundFunctorOf(alias f) 27 { 28 static @property auto unboundFunctorOf() 29 { 30 UnboundFunctorOf!f r; 31 return r; 32 } 33 } 34 struct UnboundFunctorOf(alias f) 35 { 36 alias opCall = f; 37 38 alias R = RefType!(thisOf!f); 39 auto bind(R r) { return boundFunctorOf!f(r); } 40 } /// ditto 41 42 /// Create bound functor of a method 43 template boundFunctorOf(alias f) 44 { 45 static @property auto boundFunctorOf(T)(T context) 46 { 47 BoundFunctorOf!(T, f) r; 48 r.context = context; 49 return r; 50 } 51 } 52 53 /// ditto 54 @property auto boundFunctorOf(alias f)() 55 if (is(typeof(this))) // haveMethodAliasBinding 56 { 57 BoundFunctorOf!(RefType!(typeof(this)), f) r; 58 r.context = this.reference; 59 return r; 60 } 61 62 struct BoundFunctorOf(R, alias f) 63 { 64 R context; 65 template opCall(Args...) 66 { 67 alias Ret = typeof(__traits(child, context, f)(Args.init)); 68 Ret opCall(auto ref Args args) 69 { 70 return __traits(child, context, f)(args); 71 } 72 } 73 74 /// Ignore - BoundFunctors are already bound 75 auto bind(R)(R r) { return this; } 76 } 77 78 static if (haveChildTrait) 79 unittest 80 { 81 static struct Test 82 { 83 void caller(Func)(Func func) 84 { 85 func(); 86 } 87 88 int i = 0; 89 90 void callee() 91 { 92 i++; 93 } 94 95 void test() 96 { 97 caller(unboundFunctorOf!callee.bind(&this)); 98 assert(i == 1); 99 100 static if (haveMethodAliasBinding) // or is it haveAliasCtxInference ? 101 { 102 caller(unboundFunctorOf!callee); 103 caller( boundFunctorOf!callee); 104 105 assert(i == 3); 106 } 107 108 static struct S 109 { 110 int i = 0; 111 112 void callee() 113 { 114 i++; 115 } 116 } 117 S s; 118 caller(boundFunctorOf!(S.callee)(&s)); 119 120 assert(s.i == 1); 121 } 122 } 123 124 Test test; 125 test.test(); 126 }