# Comparison and Equality

> StringZilla for C

`#include <stringzilla/types.h>`

`#include <stringzilla/capabilities.h>`

`#include <stringzilla/compare.h>`

## sz_ordering_t

Describes the result of a comparison, like `std::strong_ordering` in C++20.

```c
enum sz_ordering_t
```

- `sz_less_k` = `-1`
- `sz_equal_k` = `0`
- `sz_greater_k` = `1`

See also: std::strong_ordering: [https://en.cppreference.com/w/cpp/utility/compare/strong_ordering](https://en.cppreference.com/w/cpp/utility/compare/strong_ordering)

## sz_kernel_equal_t

Signature of the [`sz_equal_best`](#sz_equal_best) kernels.

```c
typedef sz_status_t(*) sz_kernel_equal_t(sz_cptr_t, sz_cptr_t, sz_size_t, sz_bool_t *, sz_stream_t);
```

## sz_kernel_order_t

Signature of the [`sz_order_best`](#sz_order_best) kernels.

```c
typedef sz_status_t(*) sz_kernel_order_t(sz_cptr_t, sz_size_t, sz_cptr_t, sz_size_t, sz_ordering_t *, sz_stream_t);
```

## sz_equal_best

Checks if two strings are equal, like `memcmp(a, b, length) == 0`, or `a == b` in STL.

```c
sz_status_t sz_equal_best(
    sz_cptr_t a,
    sz_cptr_t b,
    sz_size_t length,
    sz_bool_t *equal,
    sz_capability_t capabilities,
    sz_stream_t stream);
```

- `sz_equal` backends: serial, westmere, haswell, skylake, neon, sve, rvv, v128, v128relaxed, loongsonasx, powervsx

Telling an equal pair from a different one:

```
#include 
int main() {
    sz_capability_t capabilities;
    sz_bool_t same, different;
    sz_capabilities_enabled_cpu(&capabilities);
    sz_equal_best("hello", "hello", 5, &same, capabilities, NULL);
    sz_equal_best("hello", "world", 5, &different, capabilities, NULL);
    return same && !different;
}
```

- `a` (in): First string to compare.
- `b` (in): Second string to compare.
- `length` (in): Number of bytes to compare in both strings.
- `equal` (out): [`sz_true_k`](https://www.unum.cloud/docs/stringzilla/c/types.md#sz_true_k) if the strings are equal, [`sz_false_k`](https://www.unum.cloud/docs/stringzilla/c/types.md#sz_false_k) if they differ.
- `capabilities` (in): One device's capabilities, like `sz_capabilities_enabled_cpu` reports.
- `stream` (in): Null on the CPU, or the GPU stream of that device to queue on.

See also: memcmp: [https://en.cppreference.com/w/c/string/byte/memcmp](https://en.cppreference.com/w/c/string/byte/memcmp)

See also: sz_equal_serial, sz_equal_westmere, sz_equal_haswell, sz_equal_skylake, sz_equal_neon, sz_equal_sve, sz_equal_v128, sz_equal_v128relaxed, sz_equal_rvv, sz_equal_loongsonasx, sz_equal_powervsx

Statuses: - [`sz_missing_kernel_k`](https://www.unum.cloud/docs/stringzilla/c/types.md#sz_missing_kernel_k) No capability in `capabilities` has it.

## sz_order_best

Compares two strings lexicographically, like `memcmp` in LibC.

```c
sz_status_t sz_order_best(
    sz_cptr_t a,
    sz_size_t a_length,
    sz_cptr_t b,
    sz_size_t b_length,
    sz_ordering_t *ordering,
    sz_capability_t capabilities,
    sz_stream_t stream);
```

- `sz_order` backends: serial, westmere, haswell, skylake, neon, sve, rvv, v128, v128relaxed, loongsonasx, powervsx

Mostly used in sorting and associative containers, and can be used for __UTF-8__ inputs. This function uses scalar code on most platforms, as in the majority of cases the strings that differ will have differences among the very first characters and fetching more than one cache line may not be justified.

Ordering three pairs of words:

```
#include 
int main() {
    sz_capability_t capabilities;
    sz_ordering_t first, second, third;
    sz_capabilities_enabled_cpu(&capabilities);
    sz_order_best("apple", 5, "banana", 6, &first, capabilities, NULL);
    sz_order_best("grape", 5, "grape", 5, &second, capabilities, NULL);
    sz_order_best("zebra", 5, "apple", 5, &third, capabilities, NULL);
    return first  0;
}
```

- `a` (in): First string to compare.
- `a_length` (in): Number of bytes in the first string.
- `b` (in): Second string to compare.
- `b_length` (in): Number of bytes in the second string.
- `ordering` (out): [`sz_less_k`](#sz_less_k) if `a` sorts before `b`, [`sz_greater_k`](#sz_greater_k) if after, or [`sz_equal_k`](#sz_equal_k) if the strings are identical.
- `capabilities` (in): One device's capabilities, like `sz_capabilities_enabled_cpu` reports.
- `stream` (in): Null on the CPU, or the GPU stream of that device to queue on.

See also: memcmp: [https://en.cppreference.com/w/c/string/byte/memcmp](https://en.cppreference.com/w/c/string/byte/memcmp)

See also: sz_order_serial, sz_order_westmere, sz_order_haswell, sz_order_skylake, sz_order_neon, sz_order_sve, sz_order_v128, sz_order_v128relaxed, sz_order_rvv, sz_order_loongsonasx, sz_order_powervsx

Statuses: - [`sz_missing_kernel_k`](https://www.unum.cloud/docs/stringzilla/c/types.md#sz_missing_kernel_k) No capability in `capabilities` has it.

## sz_compare_find_kernel

Finds the comparison kernel of `kind`, from the best of `capabilities`.

```c
sz_status_t sz_compare_find_kernel(
    sz_kernel_kind_t kind,
    sz_capability_t capabilities,
    sz_kernel_punned_t *kernel,
    sz_capability_t *capability);
```

- `kind` (in): The verb whose kernel to find.
- `capabilities` (in): The mask to pick the best capability from.
- `kernel` (out): The kernel, or null when none of `capabilities` has it.
- `capability` (out): The capability the kernel belongs to, or zero.

Statuses: - [`sz_missing_kernel_k`](https://www.unum.cloud/docs/stringzilla/c/types.md#sz_missing_kernel_k)
- [`sz_missing_library_k`](https://www.unum.cloud/docs/stringzilla/c/types.md#sz_missing_library_k) Header-only.

## Overview

Includes core APIs:

- [`sz_equal_best`](#sz_equal_best) - for equality comparison of two strings.
- [`sz_order_best`](#sz_order_best) - for the relative order of two strings, similar to `memcmp`.A valid suggestion may be to add an `sz_mismatch`, as the shared part of [`sz_order_best`](#sz_order_best) and [`sz_equal_best`](#sz_equal_best). That would be great for a general-purpose library, but string processing has little practical use for it.

The functions in this file can be used for both UTF-8 and other inputs. On platforms without masked loads they use interleaved prefix and suffix vector-loads to avoid scalar code, similar to the kernels in `memory.h`.

