1 module tagion.betterC.utils.Miscellaneous;
2 
3 import std.range.primitives : isInputRange;
4 import tagion.basic.Types : Buffer, isBufferType;
5 import tagion.betterC.utils.Memory;
6 
7 // import std.algorithm : map;
8 // import std.array : array;
9 import std.algorithm.iteration : cumulativeFold, fold;
10 import tagion.betterC.utils.BinBuffer;
11 
12 void gene_xor(ref scope ulong[] result, scope const(ubyte[]) a, scope const(ubyte[]) b)
13 in {
14     assert(a.length == b.length);
15     assert(result.length == b.length);
16 }
17 do {
18     foreach (i, ref r; result) {
19         r = a[i] ^ b[i];
20     }
21 }
22 
23 protected Buffer _xor(const(ubyte[]) a, const(ubyte[]) b)
24 in {
25     assert(a.length == b.length);
26     assert(a.length % ulong.sizeof == 0);
27 }
28 do {
29     ulong[] res;
30     res.create(a.length);
31     gene_xor(res, a, b);
32     return cast(Buffer) res;
33 }
34 
35 @trusted
36 const(Buffer) xor(scope const(ubyte[]) a, scope const(ubyte[]) b)
37 in {
38     assert(a.length == b.length);
39     assert(a.length % ulong.sizeof == 0);
40 }
41 do {
42     ulong[] res;
43     res.create(a.length);
44     gene_xor(res, a, b);
45     return cast(Buffer) res;
46 }
47 
48 @trusted
49 const(Buffer) xor(BinBuffer a, BinBuffer b)
50 in {
51     assert(a.length == b.length);
52     assert(a.length % ulong.sizeof == 0);
53 }
54 do {
55     return xor(a.serialize, b.serialize);
56 }
57 
58 @trusted
59 Buffer xor(ref scope ubyte[] result, scope const(ubyte[]) a, scope const(ubyte[]) b)
60 in {
61     assert(a.length == b.length);
62     assert(a.length % ulong.sizeof == 0);
63 }
64 do {
65     ulong[] res;
66     res.create(a.length);
67     gene_xor(res, a, b);
68 
69     return cast(Buffer) res;
70 }
71 
72 @trusted
73 Buffer xor(Range)(scope Range range) if (isInputRange!Range) {
74     import std.array : array;
75     import std.range : tail;
76 
77     return range
78         .cumulativeFold!((a, b) => _xor(a, b))
79         .tail(1)
80         .front;
81 }