libmir / mir-algorithm

Compare 08da19a ... +2 ... 330a682

No flags found

Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.

e.g., #unittest #integration

#production #enterprise

#frontend #backend

Learn more about Codecov Flags here.

Showing 2 of 2 files from the diff.

@@ -1301,10 +1301,13 @@
Loading
1301 1301
        {
1302 1302
            import mir.parse: fromString, parse;
1303 1303
1304 +
            if (str.length < 4)
1305 +
                return false;
1306 +
1304 1307
            static if (ext)
1305 -
                auto isOnlyTime = str.length >= 3 && ((str[0] == 'T' || (yaml && (str[0] == 't' || str[0] == ' ' || str[0] == '\t'))) || str[2] == ':');
1308 +
                auto isOnlyTime = (str[0] == 'T' || yaml && (str[0] == 't')) || str[2] == ':';
1306 1309
            else
1307 -
                auto isOnlyTime = str.length >= 3 && (str[0] == 'T' || (yaml && (str[0] == 't' || str[0] == ' ' || str[0] == '\t')));
1310 +
                auto isOnlyTime = str[0] == 'T' || yaml && (str[0] == 't');
1308 1311
1309 1312
            if (!isOnlyTime)
1310 1313
            {

@@ -0,0 +1,314 @@
Loading
1 +
/++
2 +
$(H1 String routines)
3 +
4 +
The module contains SIMD-accelerated string routines.
5 +
6 +
Copyright: 2022 Ilia Ki, Symmetry Investments
7 +
8 +
Authors: Ilia Ki
9 +
+/
10 +
module mir.string;
11 +
12 +
import std.traits: isSomeChar;
13 +
14 +
private alias Representation(T :  char) = byte;
15 +
private alias Representation(T : wchar) = short;
16 +
private alias Representation(T : dchar) = int;
17 +
18 +
private enum size_t ScanVecSize = 16;
19 +
20 +
///
21 +
bool containsAny(C, size_t L)
22 +
    (scope const(C)[] str, const C[L] chars...)
23 +
    @trusted pure nothrow @nogc
24 +
    if (isSomeChar!C && L)
25 +
{
26 +
    enum size_t N = ScanVecSize / C.sizeof;
27 +
28 +
    alias U = Representation!C;
29 +
30 +
    // version(none)
31 +
    version (LittleEndian)
32 +
    version (LDC)
33 +
    static if (N <= 8)
34 +
    static if (is(__vector(U[N])))
35 +
    {
36 +
        alias V = __vector(U[N]);
37 +
        pragma(msg, V);
38 +
        V[L] charsv;
39 +
        static foreach (i; 0 .. L)
40 +
            charsv[i] = chars[i];
41 +
42 +
        while (str.length >= N)
43 +
        {
44 +
            auto a = cast(V) *cast(const U[N]*) str.ptr;
45 +
46 +
            import ldc.simd: mask = equalMask;
47 +
48 +
            V[L] masked;
49 +
            static foreach (i; 0 .. L)
50 +
                masked[i] = mask!(__vector(U[N]))(a, charsv[i]);
51 +
52 +
            static foreach (i; 0 .. L)
53 +
                static if (i == 0)
54 +
                    V m = masked[i];
55 +
                else
56 +
                    m |= masked[i];
57 +
58 +
            if (m != V.init)
59 +
                return true;
60 +
61 +
            str = str[N .. $];
62 +
        }
63 +
    }
64 +
65 +
    foreach (C c; str)
66 +
        static foreach (i; 0 .. L)
67 +
            if (c == chars[i])
68 +
                return true;
69 +
    return false;
70 +
}
71 +
72 +
///
73 +
version(mir_test)
74 +
@safe pure nothrow @nogc
75 +
unittest
76 +
{
77 +
    import mir.test: should;
78 +
79 +
    assert("     hello world     ".containsAny('w'));
80 +
    assert(!"     hello world     ".containsAny('W'));
81 +
    assert("     hello world     ".containsAny('W', 'e'));
82 +
    assert("     hello world     ".containsAny("We"));
83 +
}
84 +
85 +
///
86 +
template scanLeftAny(string op = "==")
87 +
    if (op == "==" || op == "!=")
88 +
{
89 +
    ///
90 +
    inout(C)[]
91 +
        scanLeftAny(C, size_t L)
92 +
        (return scope inout(C)[] str, const C[L] chars...)
93 +
        @trusted pure nothrow @nogc
94 +
        if (isSomeChar!C && L)
95 +
    {
96 +
        enum size_t N = ScanVecSize / C.sizeof;
97 +
98 +
        alias U = Representation!C;
99 +
100 +
        // version(none)
101 +
        version (LittleEndian)
102 +
        version (LDC)
103 +
        static if (N <= 8)
104 +
        static if (is(__vector(U[N])))
105 +
        {
106 +
            import mir.bitop: cttz;
107 +
108 +
            alias V = __vector(U[N]);
109 +
            pragma(msg, V);
110 +
            V[L] charsv;
111 +
            static foreach (i; 0 .. L)
112 +
                charsv[i] = chars[i];
113 +
114 +
            while (str.length >= N)
115 +
            {
116 +
                auto a = cast(V) *cast(const U[N]*) str.ptr;
117 +
118 +
                import ldc.simd: mask = equalMask;
119 +
120 +
                V[L] masked;
121 +
                static foreach (i; 0 .. L)
122 +
                    masked[i] = mask!(__vector(U[N]))(a, charsv[i]);
123 +
124 +
                static foreach (i; 0 .. L)
125 +
                    static if (i == 0)
126 +
                        V m = masked[i];
127 +
                    else
128 +
                        m |= masked[i];
129 +
130 +
                static if (op == "!=")
131 +
                    m = ~m;
132 +
133 +
                auto words = (cast(__vector(size_t[U[N].sizeof / size_t.sizeof])) m).array;
134 +
135 +
                static foreach (i; 0 .. words.length)
136 +
                {
137 +
                    if (words[i])
138 +
                    {
139 +
                        enum p = i * size_t.sizeof / U.sizeof;
140 +
                        return str[p + (cttz(words[i]) / (U.sizeof * 8)) .. $];
141 +
                    }
142 +
                }
143 +
                str = str[N .. $];
144 +
            }
145 +
        }
146 +
147 +
        Loop: for (; str.length; str = str[1 .. $])
148 +
        {
149 +
            auto c = str[0];
150 +
            static foreach (i; 0 .. L)
151 +
            {
152 +
                if (c == chars[i])
153 +
                {
154 +
                    static if (op == "==")
155 +
                        break Loop;
156 +
                    else
157 +
                        continue Loop;
158 +
                }
159 +
            }
160 +
            static if (op == "==")
161 +
                continue Loop;
162 +
            else
163 +
                break Loop;
164 +
        }
165 +
        return str;
166 +
    }
167 +
}
168 +
169 +
///
170 +
alias stripLeft = scanLeftAny!"!=";
171 +
172 +
///
173 +
version(mir_test)
174 +
@safe pure nothrow @nogc
175 +
unittest
176 +
{
177 +
    import mir.test: should;
178 +
179 +
    "     hello world     ".stripLeft(' ').should == "hello world     ";
180 +
    "     hello world     ".scanLeftAny('w').should == "world     ";
181 +
    "     hello world     ".scanLeftAny('!').should == "";
182 +
    "\t\n\thello world\n\t___".stripLeft('\n', '\t').should == "hello world\n\t___";
183 +
    "hello world".stripLeft(' ').should == "hello world";
184 +
    "hello world           ".stripLeft(' ').should == "hello world           ";
185 +
186 +
    "        _____________              hello world     "
187 +
        .stripLeft(' ', '_').should == "hello world     ";
188 +
}
189 +
190 +
///
191 +
template scanRightAny(string op = "==")
192 +
    if (op == "==" || op == "!=")
193 +
{
194 +
    ///
195 +
    inout(C)[]
196 +
        scanRightAny(C, size_t L)
197 +
        (return scope inout(C)[] str, const C[L] chars...)
198 +
        @trusted pure nothrow @nogc
199 +
        if (isSomeChar!C && L)
200 +
    {
201 +
        enum size_t N = ScanVecSize / C.sizeof;
202 +
203 +
        alias U = Representation!C;
204 +
205 +
        // version(none)
206 +
        version (LittleEndian)
207 +
        version (LDC)
208 +
        static if (N <= 8)
209 +
        static if (is(__vector(U[N])))
210 +
        {
211 +
            import mir.bitop: ctlz;
212 +
213 +
            alias V = __vector(U[N]);
214 +
            pragma(msg, V);
215 +
            V[L] charsv;
216 +
            static foreach (i; 0 .. L)
217 +
                charsv[i] = chars[i];
218 +
219 +
            while (str.length >= N)
220 +
            {
221 +
                auto a = cast(V) *cast(const U[N]*) (str.ptr + str.length - N);
222 +
223 +
                import ldc.simd: mask = equalMask;
224 +
225 +
                V[L] masked;
226 +
                static foreach (i; 0 .. L)
227 +
                    masked[i] = mask!(__vector(U[N]))(a, charsv[i]);
228 +
229 +
                static foreach (i; 0 .. L)
230 +
                    static if (i == 0)
231 +
                        V m = masked[i];
232 +
                    else
233 +
                        m |= masked[i];
234 +
235 +
                static if (op == "!=")
236 +
                    m = ~m;
237 +
238 +
                auto words = (cast(__vector(size_t[U[N].sizeof / size_t.sizeof])) m).array;
239 +
240 +
                static foreach (i; 0 .. words.length)
241 +
                {
242 +
                    if (words[$ - 1 - i])
243 +
                    {
244 +
                        enum p = i * size_t.sizeof / U.sizeof;
245 +
                        return str[0 .. $ - (p + (ctlz(words[$ - 1 - i]) / (U.sizeof * 8)))];
246 +
                    }
247 +
                }
248 +
                str = str[0 .. $ - N];
249 +
            }
250 +
        }
251 +
252 +
        Loop: for (; str.length; str = str[0 .. $ - 1])
253 +
        {
254 +
            auto c = str[$ - 1];
255 +
            static foreach (i; 0 .. L)
256 +
            {
257 +
                if (c == chars[i])
258 +
                {
259 +
                    static if (op == "==")
260 +
                        break Loop;
261 +
                    else
262 +
                        continue Loop;
263 +
                }
264 +
            }
265 +
            static if (op == "==")
266 +
                continue Loop;
267 +
            else
268 +
                break Loop;
269 +
        }
270 +
        return str;
271 +
    }
272 +
}
273 +
274 +
///
275 +
alias stripRight = scanRightAny!"!=";
276 +
277 +
///
278 +
version(mir_test)
279 +
@safe pure nothrow @nogc
280 +
unittest
281 +
{
282 +
    import mir.test: should;
283 +
284 +
    "     hello world     ".stripRight(' ').should == "     hello world";
285 +
    "     hello world     ".scanRightAny('w').should == "     hello w";
286 +
    "     hello world     ".scanRightAny('!').should == "";
287 +
    "___\t\n\thello world\n\t".stripRight('\n', '\t').should == "___\t\n\thello world";
288 +
    "hello world".stripRight(' ').should == "hello world";
289 +
    "           hello world".stripRight(' ').should == "           hello world";
290 +
291 +
    "     hello world        _____________              "
292 +
        .stripRight(' ', '_').should == "     hello world";
293 +
}
294 +
295 +
///
296 +
inout(C)[]
297 +
    strip(C, size_t L)
298 +
    (return scope inout(C)[] str, const C[L] chars...)
299 +
    @trusted pure nothrow @nogc
300 +
    if (isSomeChar!C && L)
301 +
{
302 +
    return str.stripLeft(chars).stripRight(chars);
303 +
}
304 +
305 +
///
306 +
version(mir_test)
307 +
@safe pure nothrow @nogc
308 +
unittest
309 +
{
310 +
    import mir.test: should;
311 +
312 +
    "     hello world!     ".strip(' ')     .should == "hello world!";
313 +
    "     hello world!!!   ".strip(" !").should == "hello world";
314 +
}

Learn more Showing 1 files with coverage changes found.

New file source/mir/string.d
New
Loading file...
Files Coverage
source/mir 0.02% 91.67%
Project Totals (79 files) 91.67%
Loading