indexOfScalarPos
Function parameters
Parameters
- T:type
- slice:[]const T
- start_index:usize
- value:T
Type definitions in this namespace
Types
- Alignment
- Stored as a power-of-two.
Detects and asserts if the std.mem.Allocator interface is violated by the caller
Functions
- ValidationAllocator
- Detects and asserts if the std.mem.Allocator interface is violated by the caller
- copyForwards
- Copy all of source into dest at position 0.
- copyBackwards
- Copy all of source into dest at position 0.
- zeroes
- Generally, Zig users are encouraged to explicitly initialize all fields of a struct explicitly rather than using this function.
- zeroInit
- Initializes all fields of the struct with their default value, or zero values if no default value is present.
- sortContext
- TODO: currently this just calls `insertionSortContext`.
- order
- Compares two slices of numbers lexicographically.
- orderZ
- Compares two many-item pointers with NUL-termination lexicographically.
- lessThan
- Returns true if lhs < rhs, false otherwise
- eql
- Returns true if and only if the slices have the same length and all elements
- indexOfDiff
- Compares two slices and returns the index of the first inequality.
- span
- Takes a sentinel-terminated pointer and returns a slice, iterating over the
- sliceTo
- Takes a pointer to an array, a sentinel-terminated pointer, or a slice and iterates searching for
- len
- Takes a sentinel-terminated pointer and iterates over the memory to find the
- allEqual
- Returns true if all elements in a slice are equal to the scalar value provided
- trimStart
- Remove a set of values from the beginning of a slice.
- trimLeft
- Deprecated: use `trimStart` instead.
- trimEnd
- Remove a set of values from the end of a slice.
- trimRight
- Deprecated: use `trimEnd` instead.
- trim
- Remove a set of values from the beginning and end of a slice.
- indexOfScalar
- Linear search for the index of a scalar value inside a slice.
- lastIndexOfScalar
- Linear search for the last index of a scalar value inside a slice.
- indexOfNone
- Find the first item in `slice` which is not contained in `values`.
- lastIndexOfNone
- Find the last item in `slice` which is not contained in `values`.
- indexOfNonePos
- Find the first item in `slice[start_index..]` which is not contained in `values`.
- lastIndexOfLinear
- Find the index in a slice of a sub-slice, searching from the end backwards.
- indexOfPosLinear
- Consider using `indexOfPos` instead of this, which will automatically use a
- lastIndexOf
- Find the index in a slice of a sub-slice, searching from the end backwards.
- indexOfPos
- Uses Boyer-Moore-Horspool algorithm on large inputs; `indexOfPosLinear` on small inputs.
- count
- Returns the number of needles inside the haystack
- containsAtLeast
- Returns true if the haystack contains expected_count or more needles
- containsAtLeastScalar
- Returns true if the haystack contains expected_count or more needles
- readVarInt
- Reads an integer from memory with size equal to bytes.len.
- readVarPackedInt
- Loads an integer from packed memory with provided bit_count, bit_offset, and signedness.
- readInt
- Reads an integer from memory with bit count specified by T.
- readPackedInt
- Loads an integer from packed memory.
- writeInt
- Writes an integer to memory, storing it in twos-complement.
- writePackedInt
- Stores an integer to packed memory.
- writeVarPackedInt
- Stores an integer to packed memory with provided bit_offset, bit_count, and signedness.
- byteSwapAllFields
- Swap the byte order of all the members of the fields of a struct
- tokenizeAny
- Returns an iterator that iterates over the slices of `buffer` that are not
- tokenizeSequence
- Returns an iterator that iterates over the slices of `buffer` that are not
- tokenizeScalar
- Returns an iterator that iterates over the slices of `buffer` that are not
- splitSequence
- Returns an iterator that iterates over the slices of `buffer` that
- splitAny
- Returns an iterator that iterates over the slices of `buffer` that
- splitScalar
- Returns an iterator that iterates over the slices of `buffer` that
- splitBackwardsSequence
- Returns an iterator that iterates backwards over the slices of `buffer` that
- splitBackwardsAny
- Returns an iterator that iterates backwards over the slices of `buffer` that
- splitBackwardsScalar
- Returns an iterator that iterates backwards over the slices of `buffer` that
- window
- Returns an iterator with a sliding window of slices for `buffer`.
- join
- Naively combines a series of slices with a separator.
- joinZ
- Naively combines a series of slices with a separator and null terminator.
- concat
- Copies each T from slices into a new slice that exactly holds all the elements.
- concatWithSentinel
- Copies each T from slices into a new slice that exactly holds all the elements.
- concatMaybeSentinel
- Copies each T from slices into a new slice that exactly holds all the elements as well as the sentinel.
- min
- Returns the smallest number in a slice.
- max
- Returns the largest number in a slice.
- minMax
- Finds the smallest and largest number in a slice.
- indexOfMin
- Returns the index of the smallest number in a slice.
- indexOfMax
- Returns the index of the largest number in a slice.
- indexOfMinMax
- Finds the indices of the smallest and largest number in a slice.
- reverse
- In-place order reversal of a slice
- reverseIterator
- Iterates over a slice in reverse.
- rotate
- In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
- replace
- Replace needle with replacement as many times as possible, writing to an output buffer which is assumed to be of
- replaceScalar
- Replace all occurrences of `match` with `replacement`.
- collapseRepeatsLen
- Collapse consecutive duplicate elements into one entry.
- collapseRepeats
- Collapse consecutive duplicate elements into one entry.
- replacementSize
- Calculate the size needed in an output buffer to perform a replacement.
- replaceOwned
- Perform a replacement on an allocated buffer of pre-determined size.
- littleToNative
- Converts a little-endian integer to host endianness.
- bigToNative
- Converts a big-endian integer to host endianness.
- toNative
- Converts an integer from specified endianness to host endianness.
- nativeTo
- Converts an integer which has host endianness to the desired endianness.
- nativeToLittle
- Converts an integer which has host endianness to little endian.
- nativeToBig
- Converts an integer which has host endianness to big endian.
- alignPointerOffset
- Returns the number of elements that, if added to the given pointer, align it
- alignPointer
- Aligns a given pointer value to a specified alignment factor.
- asBytes
- Given a pointer to a single item, returns a slice of the underlying bytes, preserving pointer attributes.
- toBytes
- Given any value, returns a copy of its bytes in an array.
- bytesAsValue
- Given a pointer to an array of bytes, returns a pointer to a value of the specified type
- bytesToValue
- Given a pointer to an array of bytes, returns a value of the specified type backed by a
- bytesAsSlice
- Given a slice of bytes, returns a slice of the specified type
- sliceAsBytes
- Given a slice, returns a slice of the underlying bytes, preserving pointer attributes.
- alignForwardAnyAlign
- Round an address down to the next (or current) aligned address.
- alignForward
- Round an address up to the next (or current) aligned address.
- doNotOptimizeAway
- Force an evaluation of the expression; this tries to prevent
- alignBackwardAnyAlign
- Round an address down to the previous (or current) aligned address.
- alignBackward
- Round an address down to the previous (or current) aligned address.
- isValidAlign
- Returns whether `alignment` is a valid alignment, meaning it is
- isValidAlignGeneric
- Returns whether `alignment` is a valid alignment, meaning it is
- isAligned
- Given an address and an alignment, return true if the address is a multiple of the alignment
- alignInBytes
- Returns the largest slice in the given bytes that conforms to the new alignment,
- alignInSlice
- Returns the largest sub-slice within the given slice that conforms to the new alignment,
The standard library currently thoroughly depends on byte size
Values
- byte_size_in_bits
- The standard library currently thoroughly depends on byte size
- readPackedIntNative
- = switch (native_endian) { .little => readPackedIntLittle, .big => readPackedIntBig, }
- readPackedIntForeign
- = switch (native_endian) { .little => readPackedIntBig, .big => readPackedIntLittle, }
- writePackedIntNative
- = switch (native_endian) { .little => writePackedIntLittle, .big => writePackedIntBig, }
- writePackedIntForeign
- = switch (native_endian) { .little => writePackedIntBig, .big => writePackedIntLittle, }
Source
Implementation
pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {
if (start_index >= slice.len) return null;
var i: usize = start_index;
if (use_vectors_for_comparison and
!std.debug.inValgrind() and // https://github.com/ziglang/zig/issues/17717
!@inComptime() and
(@typeInfo(T) == .int or @typeInfo(T) == .float) and std.math.isPowerOfTwo(@bitSizeOf(T)))
{
if (std.simd.suggestVectorLength(T)) |block_len| {
// For Intel Nehalem (2009) and AMD Bulldozer (2012) or later, unaligned loads on aligned data result
// in the same execution as aligned loads. We ignore older arch's here and don't bother pre-aligning.
//
// Use `std.simd.suggestVectorLength(T)` to get the same alignment as used in this function
// however this usually isn't necessary unless your arch has a performance penalty due to this.
//
// This may differ for other arch's. Arm for example costs a cycle when loading across a cache
// line so explicit alignment prologues may be worth exploration.
// Unrolling here is ~10% improvement. We can then do one bounds check every 2 blocks
// instead of one which adds up.
const Block = @Vector(block_len, T);
if (i + 2 * block_len < slice.len) {
const mask: Block = @splat(value);
while (true) {
inline for (0..2) |_| {
const block: Block = slice[i..][0..block_len].*;
const matches = block == mask;
if (@reduce(.Or, matches)) {
return i + std.simd.firstTrue(matches).?;
}
i += block_len;
}
if (i + 2 * block_len >= slice.len) break;
}
}
// {block_len, block_len / 2} check
inline for (0..2) |j| {
const block_x_len = block_len / (1 << j);
comptime if (block_x_len < 4) break;
const BlockX = @Vector(block_x_len, T);
if (i + block_x_len < slice.len) {
const mask: BlockX = @splat(value);
const block: BlockX = slice[i..][0..block_x_len].*;
const matches = block == mask;
if (@reduce(.Or, matches)) {
return i + std.simd.firstTrue(matches).?;
}
i += block_x_len;
}
}
}
}
for (slice[i..], i..) |c, j| {
if (c == value) return j;
}
return null;
}