1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.util.Functional;
13 
14 import std.functional;
15 import std.traits;
16 import std.typecons;
17 import std.typetuple;
18 
19 pragma(inline) auto bind(T, Args...)(T fun, Args args) if (isCallable!(T)) {
20     alias FUNTYPE = Parameters!(fun);
21     static if (is(Args == void)) {
22         static if (isDelegate!T)
23             return fun;
24         else
25             return toDelegate(fun);
26     } else static if (FUNTYPE.length > args.length) {
27         alias DTYPE = FUNTYPE[args.length .. $];
28         return delegate(DTYPE ars) {
29             TypeTuple!(FUNTYPE) value;
30             value[0 .. args.length] = args[];
31             value[args.length .. $] = ars[];
32             return fun(value);
33         };
34     } else {
35         return delegate() { return fun(args); };
36     }
37 }
38 
39 unittest {
40 
41     import std.stdio;
42     import core.thread;
43 
44     class AA {
45         void show(int i) {
46             writeln("i = ", i); // the value is not(0,1,2,3), it all is 2.
47         }
48 
49         void show(int i, int b) {
50             b += i * 10;
51             writeln("b = ", b); // the value is not(0,1,2,3), it all is 2.
52         }
53 
54         void aa() {
55             writeln("aaaaaaaa ");
56         }
57 
58         void dshow(int i, string str, double t) {
59             writeln("i = ", i, "   str = ", str, "   t = ", t);
60         }
61     }
62 
63     void listRun(int i) {
64         writeln("i = ", i);
65     }
66 
67     void listRun2(int i, int b) {
68         writeln("i = ", i, "  b = ", b);
69     }
70 
71     void list() {
72         writeln("bbbbbbbbbbbb");
73     }
74 
75     void dooo(Thread[] t1, Thread[] t2, AA a) {
76         foreach (i; 0 .. 4) {
77             auto th = new Thread(bind!(void delegate(int, int))(&a.show, i, i));
78             t1[i] = th;
79             auto th2 = new Thread(bind(&listRun, (i + 10)));
80             t2[i] = th2;
81         }
82     }
83 
84     //  void main()
85     {
86         auto tdel = bind(&listRun);
87         tdel(9);
88         bind(&listRun2, 4)(5);
89         bind(&listRun2, 40, 50)();
90 
91         AA a = new AA();
92         bind(&a.dshow, 5, "hahah")(20.05);
93 
94         Thread[4] _thread;
95         Thread[4] _thread2;
96         // AA a = new AA();
97 
98         dooo(_thread, _thread2, a);
99 
100         foreach (i; 0 .. 4) {
101             _thread[i].start();
102         }
103 
104         foreach (i; 0 .. 4) {
105             _thread2[i].start();
106         }
107 
108     }
109 }