1 /**
2     Capture variables with value semantics, useful in nogc code
3 */
4 module ddash.lang.capture;
5 
6 ///
7 @nogc unittest {
8 	import std.range: only;
9     import std.algorithm: map;
10     auto xs = only(1, 2, 3);
11     int a = 2, b = 3;
12     xs.capture(a, b).map!(unpack!((x, a, b) => x * a * b));
13 }
14 
15 /**
16     The capture function takes a range as the first argument and a list of arguments you
17     want to capture by value to pass along to another range
18 
19     Since:
20         - 0.0.1
21 */
22 auto capture(Range, Captures...)(auto ref Range range, auto ref Captures captures) {
23     string mix() {
24         import std.conv: to;
25         string s = "zip(range, ";
26         static foreach (i; 0 .. Captures.length) {
27             s ~= "repeat(captures[" ~ i.to!string ~ "]),";
28         }
29         s ~= ")";
30         return s;
31     }
32     import std.range: repeat, zip, only;
33     return mixin(mix());
34 }
35 
36 /**
37     Complements the `capture` function by allowing you to unpack a capture tuple in the function
38     you want to call it from.
39 
40     Since:
41         - 0.0.1
42 */
43 template unpack(alias func) {
44     import std.typecons: isTuple;
45     auto unpack(TupleType)(TupleType tup) if (isTuple!TupleType) {
46         return func(tup.expand);
47     }
48 }