@@ -54,7 +54,7 @@ public static bool HasFlag(uint value, int n)
5454 /// decrement the input parameter <paramref name="x"/> to ensure that the range of accepted
5555 /// values fits within the available 32 bits of the lookup table in use.
5656 /// For more info on this optimization technique, see <see href="https://egorbo.com/llvm-range-checks.html"/>.
57- /// Here is how the code from the lik above would be implemented using this method:
57+ /// Here is how the code from the link above would be implemented using this method:
5858 /// <code>
5959 /// bool IsReservedCharacter(char c)
6060 /// {
@@ -103,6 +103,68 @@ public static bool HasLookupFlag(uint table, int x, int min = 0)
103103 return valid ;
104104 }
105105
106+ /// <summary>
107+ /// Checks whether the given value has any bytes that are set to 0.
108+ /// That is, given a <see cref="uint"/> value, which has a total of 4 bytes,
109+ /// it checks whether any of those have all the bits set to 0.
110+ /// </summary>
111+ /// <param name="value">The input value to check.</param>
112+ /// <returns>Whether <paramref name="value"/> has any bytes set to 0.</returns>
113+ /// <remarks>
114+ /// This method contains no branches.
115+ /// For more background on this subject, see <see href="https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord"/>.
116+ /// </remarks>
117+ [ Pure ]
118+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
119+ public static bool HasZeroByte ( uint value )
120+ {
121+ return ( ( value - 0x0101_0101u ) & ~ value & 0x8080_8080u ) != 0 ;
122+ }
123+
124+ /// <summary>
125+ /// Checks whether the given value has any bytes that are set to 0.
126+ /// This method mirrors <see cref="HasZeroByte(uint)"/>, but with <see cref="ulong"/> values.
127+ /// </summary>
128+ /// <param name="value">The input value to check.</param>
129+ /// <returns>Whether <paramref name="value"/> has any bytes set to 0.</returns>
130+ [ Pure ]
131+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
132+ public static bool HasZeroByte ( ulong value )
133+ {
134+ return ( ( value - 0x0101_0101_0101_0101ul ) & ~ value & 0x8080_8080_8080_8080ul ) != 0 ;
135+ }
136+
137+ /// <summary>
138+ /// Checks whether a byte in the input <see cref="uint"/> value matches a target value.
139+ /// </summary>
140+ /// <param name="value">The input value to check.</param>
141+ /// <param name="target">The target byte to look for.</param>
142+ /// <returns>Whether <paramref name="value"/> has any bytes set to <paramref name="target"/>.</returns>
143+ /// <remarks>
144+ /// This method contains no branches.
145+ /// For more info, see <see href="https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord"/>.
146+ /// </remarks>
147+ [ Pure ]
148+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
149+ public static bool HasByteEqualTo ( uint value , byte target )
150+ {
151+ return HasZeroByte ( value ^ ( 0x0101_0101u * target ) ) ;
152+ }
153+
154+ /// <summary>
155+ /// Checks whether a byte in the input <see cref="uint"/> value matches a target value.
156+ /// This method mirrors <see cref="HasByteEqualTo(uint,byte)"/>, but with <see cref="ulong"/> values.
157+ /// </summary>
158+ /// <param name="value">The input value to check.</param>
159+ /// <param name="target">The target byte to look for.</param>
160+ /// <returns>Whether <paramref name="value"/> has any bytes set to <paramref name="target"/>.</returns>
161+ [ Pure ]
162+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
163+ public static bool HasByteEqualTo ( ulong value , byte target )
164+ {
165+ return HasZeroByte ( value ^ ( 0x0101_0101_0101_0101u * target ) ) ;
166+ }
167+
106168 /// <summary>
107169 /// Sets a bit to a specified value.
108170 /// </summary>
0 commit comments