1 module carbon.utils;
2 
3 import std.algorithm;
4 import std.container;
5 import std.traits;
6 
7 
8 string toLiteral(string str)
9 {
10     import std.string : format;
11 
12     return format("%s", [str])[1 .. $-1];
13 }
14 
15 unittest
16 {
17     assert("123".toLiteral == `"123"`);
18     assert("12\"3".toLiteral == `"12\"3"`);
19 }
20 
21 
22 struct Cache(AA)
23 if(isAssociativeArray!AA)
24 {
25     alias KeyType = typeof(AA.init.keys[0]);
26     alias ValueType = typeof(AA.init.values[0]);
27 
28     ValueType opCall(KeyType key, lazy ValueType value)
29     {
30         if(auto p = key in _aa)
31             return *p;
32         else{
33             ValueType v = value();
34             _aa[key] = v;
35             return v;
36         }
37     }
38 
39   private:
40     AA _aa;
41 }
42 
43 unittest
44 {
45     Cache!(int[string]) c;
46     assert(c("foo", 1) == 1);
47     assert(c("bar", 2) == 2);
48     assert(c("foo", 3) == 1);
49     assert(c("bar", 4) == 2);
50 }
51 
52 
53 auto maybeModified(K, V)(V[K] aa)
54 {
55     static struct Result()
56     {
57         this(V[K] aa)
58         {
59             _keys = typeof(_keys)(aa.byKey);
60 
61             _aa = aa;
62         }
63 
64 
65         int opApply(int delegate(K, ref V) dg)
66         {
67             foreach(k; _keys)
68                 if(k in _aa)
69                     if(auto res = dg(k, _aa[k]))
70                         return res;
71 
72             return 0;
73         }
74 
75       private:
76         Array!K _keys;
77         V[K] _aa;
78     }
79 
80     return Result!()(aa);
81 }
82 
83 unittest
84 {
85     auto aa = ["a": 1, "b": 2, "c": 3];
86 
87     foreach(k, ref v; aa.maybeModified){
88         aa[k ~ k] = v;
89     }
90 
91     assert(aa.length == 6);
92 }
93 
94 
95 auto maybeModified(E)(E[] arr)
96 {
97     static struct Result()
98     {
99         this(E[] arr)
100         {
101             _dup = Array!E(arr);
102         }
103 
104 
105         int opApply(int delegate(E) dg)
106         {
107             foreach(e; _dup)
108                 if(auto res = dg(e))
109                     return res;
110 
111             return 0;
112         }
113 
114       private:
115         Array!E _dup;
116     }
117 
118 
119     return Result!()(arr);
120 }
121 
122 unittest
123 {
124     auto arr = [1, 2, 3];
125 
126     foreach(v; arr.maybeModified){
127         arr ~= v;
128     }
129 
130     assert(arr.length == 6);
131     assert(arr == [1, 2, 3, 1, 2, 3]);
132 }
133