• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

neon-sunset / U8String / 6005208900

28 Aug 2023 09:36PM UTC coverage: 18.096% (-0.2%) from 18.326%
6005208900

push

github

neon-sunset
feat: Extend NativeU8String and restructure solution to account for increased line count, add roadmap draft

134 of 1050 branches covered (0.0%)

Branch coverage included in aggregate %.

1058 of 1058 new or added lines in 25 files covered. (100.0%)

478 of 2332 relevant lines covered (20.5%)

35305.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

18.99
/src/Implementations/Shared/U8Enumeration.cs
1
using System.Runtime.InteropServices;
2

3
using U8Primitives.Abstractions;
4

5
namespace U8Primitives;
6

7
// TODO: Unsafe opt. strided broadcast / scatter byte[] reference onto U8String[]
8
// in a SIMD way (is there a way to make it not explode and not be a total UB?)
9
internal static class U8Enumeration
10
{
11
    internal static void CopyTo<T, E, U>(this ref T source, Span<U> destination)
12
        where T : struct, IEnumerable<U, E>, ICollection<U>
13
        where E : struct, IEnumerator<U>
14
        where U : struct
15
    {
16
        var count = source.Count;
×
17
        if (count is not 0)
×
18
        {
19
            source.FillUnchecked<T, E, U>(destination[..count]);
×
20
        }
21
    }
×
22

23
    // TODO: Optimize? Maybe a dedicated split type or similar? Would be really nice to have const generics for this
24
    // Perhaps a U8SplitPair-like struct with byte[] and U8Range[] (or inline array) indices?
25
    // TODO 2: Consider making out Us nullable? Alternatively, consider throwing?
26
    internal static void Deconstruct<T, E, U>(this T source, out U first, out U second)
27
        where T : struct, IEnumerable<U, E>
28
        where E : struct, IEnumerator<U>
29
        where U : struct
30
    {
31
        // TODO: Should we throw on not match?
32
        (first, second) = (default, default);
×
33

34
        var enumerator = source.GetEnumerator();
×
35
        if (enumerator.MoveNext())
×
36
        {
37
            first = enumerator.Current;
×
38
            if (enumerator.MoveNext())
×
39
            {
40
                second = enumerator.Current;
×
41
            }
42
        }
43
    }
×
44

45
    internal static void Deconstruct<T, E, U>(this T source, out U first, out U second, out U third)
46
        where T : struct, IEnumerable<U, E>
47
        where E : struct, IEnumerator<U>
48
        where U : struct
49
    {
50
        (first, second, third) = (default, default, default);
×
51

52
        var enumerator = source.GetEnumerator();
×
53
        if (enumerator.MoveNext())
×
54
        {
55
            first = enumerator.Current;
×
56
            if (enumerator.MoveNext())
×
57
            {
58
                second = enumerator.Current;
×
59
                if (enumerator.MoveNext())
×
60
                {
61
                    third = enumerator.Current;
×
62
                }
63
            }
64
        }
65
    }
×
66

67
    internal static U ElementAt<T, E, U>(this T source, int index)
68
        where T : struct, IEnumerable<U, E>
69
        where E : struct, IEnumerator<U>
70
        where U : struct
71
    {
72
        if (index < 0)
×
73
        {
74
            ThrowHelpers.ArgumentOutOfRange();
×
75
        }
76

77
        foreach (var item in source)
×
78
        {
79
            if (index-- is 0)
×
80
            {
81
                return item;
×
82
            }
83
        }
84

85
        return ThrowHelpers.ArgumentOutOfRange<U>();
×
86
    }
×
87

88
    internal static U ElementAtOrDefault<T, E, U>(this T source, int index)
89
        where T : struct, IEnumerable<U, E>
90
        where E : struct, IEnumerator<U>
91
        where U : struct
92
    {
93
        if (index < 0)
×
94
        {
95
            return default;
×
96
        }
97

98
        foreach (var item in source)
×
99
        {
100
            if (index-- is 0)
×
101
            {
102
                return item;
×
103
            }
104
        }
105

106
        return default;
×
107
    }
×
108

109
    // internal static U First<T, E, U>(this T source)
110
    //     where T : struct, IEnumerable<U, E>
111
    //     where E : struct, IEnumerator<U>
112
    //     where U : struct
113
    // {
114
    //     var enumerator = source.GetEnumerator();
115
    //     if (enumerator.MoveNext())
116
    //     {
117
    //         return enumerator.Current;
118
    //     }
119

120
    //     return ThrowHelpers.SequenceIsEmpty<U>();
121
    // }
122

123
    // internal static U FirstOrDefault<T, E, U>(this T source)
124
    //     where T : struct, IEnumerable<U, E>
125
    //     where E : struct, IEnumerator<U>
126
    //     where U : struct
127
    // {
128
    //     var enumerator = source.GetEnumerator();
129
    //     if (enumerator.MoveNext())
130
    //     {
131
    //         return enumerator.Current;
132
    //     }
133

134
    //     return default;
135
    // }
136

137
    // internal static U Last<T, E, U>(this T source)
138
    //     where T : struct, IEnumerable<U, E>
139
    //     where E : struct, IEnumerator<U>
140
    //     where U : struct
141
    // {
142
    //     // TODO: Use LastIndexOf on splits? Replace this with analyzer to use SplitFirst/Last?
143
    //     var enumerator = source.GetEnumerator();
144
    //     if (enumerator.MoveNext())
145
    //     {
146
    //         var result = enumerator.Current;
147
    //         while (enumerator.MoveNext())
148
    //         {
149
    //             result = enumerator.Current;
150
    //         }
151

152
    //         return result;
153
    //     }
154

155
    //     return ThrowHelpers.SequenceIsEmpty<U>();
156
    // }
157

158
    internal static U[] ToArray<T, E, U>(this ref T source)
159
        where T : struct, IEnumerable<U, E>, ICollection<U>
160
        where E : struct, IEnumerator<U>
161
        where U : struct
162
    {
163
        var count = source.Count;
6✔
164
        if (count is not 0)
6✔
165
        {
166
            var result = new U[count];
5✔
167
            source.FillUnchecked<T, E, U>(result);
5✔
168

169
            return result;
5✔
170
        }
171

172
        return Array.Empty<U>();
1✔
173
    }
174

175
    internal static List<U> ToList<T, E, U>(this ref T source)
176
        where T : struct, IEnumerable<U, E>, ICollection<U>
177
        where E : struct, IEnumerator<U>
178
        where U : struct
179
    {
180
        var count = source.Count;
×
181
        var result = new List<U>(count);
×
182

183
        CollectionsMarshal.SetCount(result, count);
×
184
        var span = CollectionsMarshal.AsSpan(result);
×
185
        source.FillUnchecked<T, E, U>(span);
×
186

187
        return result;
×
188
    }
189

190
    private static void FillUnchecked<T, E, U>(this ref T source, Span<U> destination)
191
        where T : struct, IEnumerable<U, E>
192
        where E : struct, IEnumerator<U>
193
        where U : struct
194
    {
195
        var i = 0;
5✔
196
        ref var ptr = ref destination.AsRef();
5✔
197
        foreach (var item in source)
1,294✔
198
        {
199
            ptr.Add(i++) = item;
642✔
200
        }
201
    }
5✔
202
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc