1 module serialport.util;
2 
3 import std.range;
4 import std.algorithm;
5 
6 import std.datetime.stopwatch;
7 
8 void msleep(Duration dt) @nogc
9 {
10     import core.thread : Fiber, Thread;
11     if (Fiber.getThis is null) Thread.sleep(dt);
12     else
13     {
14         const tm = StopWatch(AutoStart.yes);
15         do Fiber.yield(); while (tm.peek < dt);
16     }
17 }
18 
19 package bool hasFlag(A,B)(A a, B b) @property { return (a & b) == b; }
20 
21 struct Pair(A,B) { A a; B b; }
22 auto pair(A,B)(A a, B b) { return Pair!(A,B)(a, b); }
23 
24 struct PairList(A,B)
25 {
26     Pair!(A,B)[] list;
27     this(Pair!(A,B)[] list) { this.list = list; }
28 
29     @safe pure @nogc nothrow const
30     {
31         size_t countA(A a) { return list.map!(a=>a.a).count(a); }
32         size_t countB(B b) { return list.map!(a=>a.b).count(b); }
33 
34         bool isUniqA() @property { return list.all!(v=>countA(v.a) == 1); }
35         bool isUniqB() @property { return list.all!(v=>countB(v.b) == 1); }
36 
37         B firstA2B(A a, B defalutValue)
38         {
39             auto f = list.find!(v=>v.a == a);
40             if (f.empty) return defalutValue;
41             else return f.front.b;
42         }
43 
44         A firstB2A(B b, A defalutValue)
45         {
46             auto f = list.find!(v=>v.b == b);
47             if (f.empty) return defalutValue;
48             else return f.front.a;
49         }
50     }
51 
52     @safe pure nothrow const
53     {
54         auto allA2B(A a) { return list.filter!(v=>v.a == a).map!(v=>v.b); }
55         auto allB2A(B b) { return list.filter!(v=>v.b == b).map!(v=>v.a); }
56     }
57 }
58 
59 auto pairList(A,B)(Pair!(A,B)[] list...) { return PairList!(A,B)(list); }
60 
61 unittest
62 {
63     auto pl = pairList(
64         pair(1, "hello"),
65         pair(1, "ololo"),
66         pair(2, "world"),
67         pair(3, "okda")
68     );
69 
70     assert(pl.countA(1) == 2);
71     assert(pl.firstA2B(1, "ok") == "hello");
72     assert(pl.countB("ok") == 0);
73     assert(pl.countB("okda") == 1);
74     assert(pl.firstB2A("okda", 0) == 3);
75     assert(pl.isUniqA == false);
76     assert(pl.isUniqB == true);
77 }
78 
79 unittest
80 {
81     static immutable pl = pairList(
82         pair(1, "hello"),
83         pair(2, "world"),
84         pair(3, "okda")
85     );
86 
87     static assert(pl.firstA2B(2, "ok") == "world");
88 }
89 
90 unittest
91 {
92     import std.algorithm : sum;
93     import std.string : join;
94 
95     immutable pl = pairList(
96         pair(1, "hello"),
97         pair(2, "okda"),
98         pair(1, "world"),
99         pair(3, "okda")
100     );
101 
102     assert(pl.allA2B(1).join(" ") == "hello world");
103     assert(pl.allB2A("okda").sum == 5);
104 }