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 }