zig/lib/std
Lucas Santos 509639717a std.equalRange: Compute lower and upper bounds simultaneously
The current implementation of `equalRange` just calls `lowerRange` and `upperRange`, but a lot of
the work done by these two functions can be shared. Specifically, each iteration gives information about whether the lower bound or the upper bound can be tightened. This leads to fewer iterations and, since there is one comparison per iteration, fewer comparisons.
Implementation adapted from [GCC](519ec1cfe9/libstdc%2B%2B-v3/include/bits/stl_algo.h (L2063)).
This sample demonstrates the difference between the current implementation and mine:

```zig
fn S(comptime T: type) type {
    return struct {
        needle: T,
        count: *usize,

        pub fn order(context: @This(), item: T) std.math.Order {
            context.count.* += 1;
            return std.math.order(item, context.needle);
        }
        pub fn orderLength(context: @This(), item: []const u8) std.math.Order {
            context.count.* += 1;
            return std.math.order(item.len, context.needle);
        }
    };
}
pub fn main() !void {
    var count: usize = 0;

    try std.testing.expectEqual(.{ 0, 0 }, equalRange(i32, &[_]i32{}, S(i32){ .needle = 0, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 0, 0 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, S(i32){ .needle = 0, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 0, 1 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, S(i32){ .needle = 2, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 2, 2 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, S(i32){ .needle = 5, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 2, 3 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, S(i32){ .needle = 8, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 5, 6 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, S(i32){ .needle = 64, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 6, 6 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, S(i32){ .needle = 100, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 2, 6 }, equalRange(i32, &[_]i32{ 2, 4, 8, 8, 8, 8, 15, 22 }, S(i32){ .needle = 8, .count = &count }, S(i32).order));
    try std.testing.expectEqual(.{ 2, 2 }, equalRange(u32, &[_]u32{ 2, 4, 8, 16, 32, 64 }, S(u32){ .needle = 5, .count = &count }, S(u32).order));
    try std.testing.expectEqual(.{ 1, 1 }, equalRange(f32, &[_]f32{ -54.2, -26.7, 0.0, 56.55, 100.1, 322.0 }, S(f32){ .needle = -33.4, .count = &count }, S(f32).order));
    try std.testing.expectEqual(.{ 3, 5 }, equalRange(
        []const u8,
        &[_][]const u8{ "Mars", "Venus", "Earth", "Saturn", "Uranus", "Mercury", "Jupiter", "Neptune" },
        S(usize){ .needle = 6, .count = &count },
        S(usize).orderLength,
    ));

    std.debug.print("Count: {}\n", .{count});
}
```
For each comparison, we bump the count. With the current implementation, we get 57 comparisons. With mine, we get 43.

With contributions from @Olvilock.
This is my second attempt at this, since I messed up the [first one](https://github.com/ziglang/zig/pull/21290).
2024-09-23 13:03:06 -07:00
..
Build Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
c std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
compress std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
crypto Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
debug std: Restore conventional compareFn behavior for binarySearch 2024-09-16 14:04:18 -07:00
dwarf Dwarf: fix and test allowzero pointers 2024-08-17 05:57:45 -04:00
fmt std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
fs Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
hash Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
heap std: deprecate some incorrect default initializations 2024-09-01 17:34:07 +01:00
http disable failing test 2024-09-19 18:20:22 -07:00
io std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
json Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
math test: Skip some floating point tests that fail on arm-linux-(gnu,musl)eabi. 2024-09-10 08:53:30 +02:00
mem std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
meta std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
net std.net, std.http: simplify 2024-02-23 02:37:11 -07:00
os std.os.linux: Fix tc_oflag_t for PowerPC 2024-09-19 16:55:00 -07:00
posix std.posix: Skip a couple of tests that use fstat()/fstatat() on riscv32. 2024-09-06 20:03:15 +02:00
process Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
Random add std.testing.random_seed 2024-07-23 11:43:12 -07:00
sort compiler,lib,test,langref: migrate @setCold to @branchHint 2024-08-27 00:44:35 +01:00
tar std.tar: add writer (#19603) 2024-08-15 22:05:53 -07:00
Target std.Target: Update CPU models/features for LLVM 19.1.0. 2024-09-19 18:20:22 -07:00
testing std: enable FailingAllocator to fail on resize 2023-09-06 19:06:32 +03:00
Thread thread: don't leak the thread in spawnManager (#21379) 2024-09-11 01:04:59 +00:00
time std.time.epoch: Fix comments referring to epoch as 1970-10-01 2024-08-15 17:54:27 -07:00
tz Support legacy TZ format, expose header struct to a potential writer 2022-01-01 12:47:08 +00:00
unicode all: migrate code to new cast builtin syntax 2023-06-24 16:56:39 -07:00
valgrind port cachegrind.h to zig (#19241) 2024-08-23 22:59:30 -07:00
zig std.zig.system.darwin.macos: Enable Apple M4 CPU detection. 2024-09-19 18:20:21 -07:00
zip std: Convert deprecated aliases to compile errors and fix usages 2024-06-13 10:18:59 -04:00
array_hash_map.zig Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
array_list.zig Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
ascii.zig std.ascii: make toLower toUpper branchless (#21369) 2024-09-13 17:22:19 -07:00
atomic.zig Merge pull request #20870 from alexrp/target-cleanup-3 2024-08-01 01:32:32 -07:00
base64.zig stdlib : base64 encode to writer (#20961) 2024-09-04 08:10:12 +00:00
bit_set.zig std.DynamicBitSet: remove wrong and useless comments (#21418) 2024-09-19 17:06:23 -07:00
BitStack.zig std: fix typos (#20560) 2024-07-09 14:25:42 -07:00
bounded_array.zig Revert "Smaller memory footprint for BoundedArray (#16299)" 2024-08-23 22:30:10 -07:00
buf_map.zig lib: correct unnecessary uses of 'var' 2023-11-19 09:55:07 +00:00
buf_set.zig Change many test blocks to doctests/decltests 2024-02-26 15:18:31 -08:00
Build.zig std.Build: allow packages to expose arbitrary LazyPaths by name 2024-09-15 17:24:44 -07:00
builtin.zig Merge pull request #21173 from mrjbq7/writeStackTrace 2024-08-31 20:57:27 -07:00
c.zig std.c: fix pthread_mutex_t size for x86_64-linux-gnu 2024-09-01 00:44:09 -07:00
coff.zig std.{coff,elf}: Remove the {MachineType,EM}.toTargetCpuArch() functions. 2024-08-23 19:56:24 +02:00
compress.zig improve documentation in std 2024-03-10 18:13:30 -07:00
crypto.zig Rename the namespace for ml_kem variants of Kyber to nist 2024-08-22 07:54:12 +02:00
debug.zig std: make debug.dumpStackPointerAddr compile 2024-09-01 00:45:31 -07:00
dwarf.zig Dwarf: cleanup emitted debug info 2024-08-22 08:44:08 +02:00
dynamic_library.zig std.DynLib: Prefer std.fs.File.stat() over posix.fstat(). 2024-09-06 20:03:15 +02:00
elf.zig std.elf: Bring the EM enum up to date. 2024-09-03 17:44:01 -07:00
enums.zig std: avoid field/decl name conflicts 2024-08-29 20:39:11 +01:00
fifo.zig std: promote tests to doctests 2024-03-21 14:11:46 -07:00
fmt.zig std.fmt: Update casing of a few functions to match naming style guide 2024-09-08 11:30:20 -07:00
fs.zig std.fs.Dir: Refactor atomicSymLink from std.fs 2024-07-28 20:08:52 -07:00
gpu.zig std: add gpu namespace 2024-02-05 11:55:14 +03:30
hash_map.zig Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
hash.zig XXH3 Implementation for Zig STD (#17530) 2023-10-17 13:55:01 -05:00
heap.zig std.c reorganization 2024-07-19 00:30:32 -07:00
http.zig add std.http.WebSocket 2024-08-07 00:48:32 -07:00
io.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
json.zig Delete compile errors for deprecated decls 2024-05-03 13:27:30 -07:00
leb128.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
linked_list.zig Revert "std.SinglyLinkedList: add sort function" 2023-11-24 22:33:50 -07:00
log.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
macho.zig remove hard tabs from source code 2024-07-31 16:57:42 -07:00
math.zig std.math: rename make_f80 to F80.toFloat and break_f80 to F80.fromFloat 2024-09-02 00:10:22 +03:00
mem.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
meta.zig std: avoid field/decl name conflicts 2024-08-29 20:39:11 +01:00
multi_array_list.zig Dwarf: implement and test multi array list 2024-09-10 12:27:57 -04:00
net.zig std.c reorganization 2024-07-19 00:30:32 -07:00
once.zig compiler,lib,test,langref: migrate @setCold to @branchHint 2024-08-27 00:44:35 +01:00
os.zig std.c reorganization 2024-07-19 00:30:32 -07:00
packed_int_array.zig chore: correct non-standard comments. 2024-07-28 21:34:14 -07:00
pdb.zig std.pdb: obey naming conventions 2024-08-29 23:43:52 +01:00
posix.zig remove length assertion from mprotect 2024-08-31 20:59:47 -07:00
priority_dequeue.zig add std.testing.random_seed 2024-07-23 11:43:12 -07:00
priority_queue.zig std: fix typos (#20560) 2024-07-09 14:25:42 -07:00
process.zig move std.zig.fatal to std.process.fatal 2024-07-20 01:06:28 -07:00
Progress.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
Random.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
RingBuffer.zig std.RingBuffer: use sliceAt/sliceFirst in read*AssumeLength 2024-03-10 18:17:23 +11:00
segmented_list.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
SemanticVersion.zig Change many test blocks to doctests/decltests 2024-02-26 15:18:31 -08:00
simd.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
sort.zig std.equalRange: Compute lower and upper bounds simultaneously 2024-09-23 13:03:06 -07:00
start.zig start: Rewrite arm code to work for thumb1 too. 2024-09-12 20:10:45 -07:00
static_string_map.zig std.static_string_map: Cast length of input for runtime initialization 2024-06-20 23:22:39 +00:00
std.zig std: Convert deprecated aliases to compile errors and fix usages 2024-06-13 10:18:59 -04:00
tar.zig Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
Target.zig std.Target: Add bridgeos tag to Os. 2024-09-19 18:20:21 -07:00
testing.zig Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
Thread.zig std: Fix assembler comment syntax for sparc. 2024-09-07 13:16:22 -07:00
time.zig std.time: Use clock_nanosleep() to implement sleep() on Linux. 2024-09-06 20:03:12 +02:00
treap.zig Condense and extend std.Treap's traversal functionalities. (#20002) 2024-07-28 19:47:55 -07:00
tz.zig std.builtin.Endian: make the tags lower case 2023-10-31 21:37:35 -04:00
unicode.zig std: update eval branch quotas after bdbc485 2024-08-21 01:30:46 +01:00
Uri.zig std.http.Client: always omit port when it matches default 2024-04-12 22:37:07 -07:00
valgrind.zig port cachegrind.h to zig (#19241) 2024-08-23 22:59:30 -07:00
wasm.zig Remove redundant test name prefixes now that test names are fully qualified 2024-02-26 15:18:31 -08:00
zig.zig std: update std.builtin.Type fields to follow naming conventions 2024-08-28 08:39:59 +01:00
zip.zig std.zip: Fix typo in doc comments 2024-06-17 16:12:19 -04:00