Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
27 kB
2
Indexable
Never
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "algorithm.h"

static void swap(void *a, void *b, size_t size) {
    // Using a stack-allocated buffer for small elements
    
    unsigned char temp[size];
    memcpy(temp, a, size);
    memcpy(a, b, size);
    memcpy(b, temp, size);
}

static void reverse(void *first, void *last, size_t size) {
    char *a = (char *)first;
    char *b = (char *)last - size;

    while (a < b) {
        swap(a, b, size);
        a += size;
        b -= size;
    }
}

static void quickSortInternal(void *base, size_t low, size_t high, size_t size, CompareFunc comp, void *temp) {
    if (low < high) {
        char* pivot = (char*)base + high * size;
        size_t i = low;

        for (size_t j = low; j < high; j++) {
            if (comp((char*)base + j * size, pivot) < 0) {
                memcpy(temp, (char*)base + j * size, size);
                memcpy((char*)base + j * size, (char*)base + i * size, size);
                memcpy((char*)base + i * size, temp, size);
                i++;
            }
        }

        memcpy(temp, (char*)base + i * size, size);
        memcpy((char*)base + i * size, pivot, size);
        memcpy(pivot, temp, size);

        if (i > 0) 
            quickSortInternal(base, low, i - 1, size, comp, temp);
        quickSortInternal(base, i + 1, high, size, comp, temp);
    }
}

static void merge(void *base, size_t low, size_t mid, size_t high, size_t size, CompareFunc comp, void *temp) {
    size_t i = low, j = mid, k = 0;

    while (i < mid && j < high) {
        if (comp((char*)base + i * size, (char*)base + j * size) <= 0) {
            memcpy((char*)temp + k * size, (char*)base + i * size, size);
            i++;
        } else {
            memcpy((char*)temp + k * size, (char*)base + j * size, size);
            j++;
        }
        k++;
    }

    while (i < mid) {
        memcpy((char*)temp + k * size, (char*)base + i * size, size);
        i++; k++;
    }

    while (j < high) {
        memcpy((char*)temp + k * size, (char*)base + j * size, size);
        j++; k++;
    }

    memcpy((char*)base + low * size, temp, k * size);
}

static void mergeSortInternal(void *base, size_t low, size_t high, size_t size, CompareFunc comp, void *temp) {
    if (high - low > 1) {
        size_t mid = low + (high - low) / 2;
        mergeSortInternal(base, low, mid, size, comp, temp);
        mergeSortInternal(base, mid, high, size, comp, temp);
        merge(base, low, mid, high, size, comp, temp);
    }
}

void algorithm_stable_sort(void *base, size_t num, size_t size, CompareFunc comp) {
    if (num > 1) {
        void* temp = malloc(num * size);
        if (temp) {
            mergeSortInternal(base, 0, num, size, comp, temp);
            free(temp);
        } else {
            perror("Failed to allocate memory for stable sorting");
            exit(EXIT_FAILURE);
        }
    }
}

void algorithm_sort(void *base, size_t num, size_t size, CompareFunc comp) {
    if (num > 1) {
        void* temp = malloc(size);
        if (temp) {
            quickSortInternal(base, 0, num - 1, size, comp, temp);
            free(temp);
        } 
        else {
            perror("Failed to allocate memory for sorting");
            exit(EXIT_FAILURE);
        }
    }
}

void *algorithm_find(const void *base, size_t num, size_t size, const void *val, CompareFunc comp) {
    const char *ptr = (const char*)base;

    for (size_t i = 0; i < num; i++) {
        if (comp(ptr + i * size, val) == 0) {
            return (void *)(ptr + i * size);
        }
    }

    return NULL;
}

void *algorithm_find_if(const void *base, size_t num, size_t size, BoolPredicateFunc pred) {
    const char *ptr = (const char*)base;

    for (size_t i = 0; i < num; i++) {
        if (pred(ptr + i * size)) {
            return (void *)(ptr + i * size);
        }
    }

    return NULL;
}

void *algorithm_find_if_not(const void *base, size_t num, size_t size, BoolPredicateFunc pred) {
    const char *ptr = (const char*)base;

    for (size_t i = 0; i < num; i++) {
        if (!pred(ptr + i * size)) {
            return (void *)(ptr + i * size);
        }
    }

    return NULL;
}

void *algorithm_find_end(const void *base1, size_t num1, size_t size1, const void *base2, size_t num2, size_t size2, CompareFunc comp) {
    if (num2 == 0) {
        return (void*)((char*)base1 + num1 * size1);
    }

    void *ret = NULL;
    const char *ptr1 = (const char*)base1;
    const char *ptr2 = (const char*)base2;

    for (size_t i = 0; i <= num1 - num2; ++i) {
        bool found = true;
        for (size_t j = 0; j < num2; ++j) {
            if (!comp(ptr1 + (i + j) * size1, ptr2 + j * size2)) {
                found = false;
                break;
            }
        }
        if (found) {
            ret = (void *)(ptr1 + i * size1);
        }
    }
    return ret;
}

void *algorithm_find_first_of(const void *base1, size_t num1, size_t size1, const void *base2, size_t num2, size_t size2, CompareFunc comp) {
    const char *ptr1 = (const char*)base1;
    const char *ptr2 = (const char*)base2;

    for (size_t i = 0; i < num1; ++i) {
        for (size_t j = 0; j < num2; ++j) {
            if (comp(ptr1 + i * size1, ptr2 + j * size2) == 0) {
                return (void *)(ptr1 + i * size1);
            }
        }
    }

    return NULL;
}

size_t algorithm_binary_search(const void *base, size_t num, size_t size, const void *val, CompareFunc comp) {
    size_t low = 0;
    size_t high = num;

    while (low < high) {
        size_t mid = low + (high - low) / 2;
        const void *mid_elem = (const char *)base + mid * size;

        int result = comp(mid_elem, val);
        if (result < 0) {
            low = mid + 1;
        } 
        else if (result > 0) {
            high = mid;
        } 
        else {
            return (size_t)mid; // Element found, return index
        }
    }
    return (size_t)-1; // Element not found
}

void *algorithm_max_element(const void *base, size_t num, size_t size, CompareFunc comp) {
    if (num == 0) {
        return NULL;
    }

    const char *max_element = (const char *)base;
    for (size_t i = 1; i < num; ++i) {
        const char *element = (const char *)base + i * size;
        if (comp(max_element, element) < 0) {
            max_element = element;
        }
    }
    return (void *)max_element;
}

void *algorithm_min_element(const void *base, size_t num, size_t size, CompareFunc comp) {
    if (num == 0) { 
        return NULL;
    }

    const char *min_element = (const char *)base;
    for (size_t i = 1; i < num; ++i) {
        const char *element = (const char *)base + i * size;
        if (comp(min_element, element) > 0) {
            min_element = element;
        }
    }
    return (void *)min_element;
}

void algorithm_for_each(void *base, size_t num, size_t size, ForEachOpFunc op) {
    char *ptr = (char *)base;
    for (size_t i = 0; i < num; ++i) {
        op(ptr + i * size);
    }
}

void algorithm_copy(const void *source, size_t num, size_t size, void *dest) {
    const char *src_ptr = (const char *)source;
    char *dest_ptr = (char *)dest;

    for (size_t i = 0; i < num; ++i) {
        memcpy(dest_ptr + i * size, src_ptr + i * size, size);
    }
}

void *algorithm_accumulate(const void *base, size_t num, size_t size, void *init, AccumulateOpFunc op) {
    char *result = (char *)init;
    const char *ptr = (const char *)base;

    for (size_t i = 0; i < num; ++i) {
        op(result, ptr + i * size);
    }
    return result;
}

bool algorithm_all_of(const void *base, size_t num, size_t size, BoolPredicateFunc pred) {
    const char *ptr = (const char *)base;

    for (size_t i = 0; i < num; ++i) {
        if (!pred(ptr + i * size)) {
            return false;
        }
    }

    return true;
}

bool algorithm_any_of(const void *base, size_t num, size_t size, BoolPredicateFunc pred) {
    const char *ptr = (const char *)base;

    for (size_t i = 0; i < num; ++i) {
        if (pred(ptr + i * size)) {
            return true;
        }
    }

    return false;
}

bool algorithm_none_of(const void *base, size_t num, size_t size, BoolPredicateFunc pred) {
    const char *ptr = (const char *)base;

    for (size_t i = 0; i < num; ++i) {
        if (pred(ptr + i * size)) {
            return false;
        }
    }

    return true;
}

void algorithm_fill(void *first, void *last, size_t size, const void *val) {
    for (char *ptr = first; ptr != last; ptr += size) {
        memcpy(ptr, val, size);
    }
}

void algorithm_fill_n(void *first, size_t n, size_t size, const void *val) {
    for (char *ptr = first; n > 0; ptr += size, n--) {
        memcpy(ptr, val, size);
    }
}

size_t algorithm_count(const void *base, size_t num, size_t size, const void *val, CompareFunc comp) {
    size_t count = 0;
    const char *ptr = (const char *)base;

    for (size_t i = 0; i < num; ++i) {
        if (comp(ptr + i * size, val) == 0) {
            ++count;
        }
    }

    return count;
}

size_t algorithm_count_if(const void *base, size_t num, size_t size, BoolPredicateFunc pred) {
    size_t count = 0;
    const char *ptr = (const char *)base;

    for (size_t i = 0; i < num; ++i) {
        if (pred(ptr + i * size)) {
            ++count;
        }
    }

    return count;
}

void algorithm_shuffle(void *base, size_t num, size_t size, UniformRandomNumberGenerator rng) {
    if (num > 1) {
        char *arr = (char *)base;
        char *temp = malloc(size);
        if (!temp) {
            perror("Failed to allocate memory for shuffle");
            exit(EXIT_FAILURE);
        }

        for (size_t i = num - 1; i > 0; i--) {
            size_t j = rng() % (i + 1);

            // Swap arr[i] and arr[j]
            memcpy(temp, arr + i * size, size);
            memcpy(arr + i * size, arr + j * size, size);
            memcpy(arr + j * size, temp, size);
        }

        free(temp);
    }
}

void *algorithm_lower_bound(const void *base, size_t num, size_t size, const void *val, CompareFunc comp) {
    size_t low = 0;
    size_t high = num;

    while (low < high) {
        size_t mid = low + (high - low) / 2;
        const void *mid_elem = (const char *)base + mid * size;

        if (comp(mid_elem, val) < 0) {
            low = mid + 1;
        } 
        else {
            high = mid;
        }
    }
    return (void *)((const char *)base + low * size);
}

void *algorithm_upper_bound(const void *base, size_t num, size_t size, const void *val, CompareFunc comp) {
    size_t low = 0;
    size_t high = num;

    while (low < high) {
        size_t mid = low + (high - low) / 2;
        const void *mid_elem = (const char *)base + mid * size;

        if (comp(mid_elem, val) <= 0) {
            low = mid + 1;
        } 
        else {
            high = mid;
        }
    }
    return (void *)((const char *)base + low * size);
}

void algorithm_transform(const void *base, size_t num, size_t size, void *result, TransformFunc op) {
    const char *input_ptr = (const char *)base;
    char *output_ptr = (char *)result;

    for (size_t i = 0; i < num; ++i) {
        op(output_ptr + i * size, input_ptr + i * size);
    }
}

void *algorithm_reduce(const void *base, size_t num, size_t size, void *init, ReduceFunc op) {
    const char *ptr = (const char *)base;
    char *result = (char *)init;

    for (size_t i = 0; i < num; ++i) {
        op(result, ptr + i * size);
    }
    return result;
}

size_t algorithm_unique(void *base, size_t num, size_t size, CompareFunc comp) {
    if (num == 0) {
        return 0;
    }

    size_t uniqueCount = 1; // First element is always unique
    char *array = (char *)base;

    for (size_t i = 1; i < num; ++i) {
        // Compare current element with the last unique element
        if (comp(array + (uniqueCount - 1) * size, array + i * size) != 0) {
            // If different, move it to the next unique position
            if (uniqueCount != i) {
                memcpy(array + uniqueCount * size, array + i * size, size);
            }
            uniqueCount++;
        }
    }
    return uniqueCount;
}

bool algorithm_equal(const void *base1, size_t num1, size_t size1, const void *base2, size_t num2, size_t size2, 
                     CompareFunc comp) {
    // If the number of elements or sizes differ, the ranges are not equal
    if (num1 != num2 || size1 != size2) {
        return false;
    }

    const char *ptr1 = (const char *)base1;
    const char *ptr2 = (const char *)base2;

    for (size_t i = 0; i < num1; ++i) {
        if (comp(ptr1 + i * size1, ptr2 + i * size2) != 0) {
            return false;
        }
    }

    return true;
}

bool algorithm_next_permutation(void *first, void *last, size_t size, CompareFuncBool comp) {
    if (first == last) {
        return false;
    }

    char *i = (char *)last - size;
    while (i != (char *)first) {
        char *j = i;
        i -= size;

        if (comp(i, j)) {
            char *k = (char *)last - size;
            while (!comp(i, k)) {
                k -= size;
            }
            swap(i, k, size);
            reverse(j, last, size);

            return true;
        }

        if (i == (char *)first) {
            reverse(first, last, size);
            return false;
        }
    }
    return false; // This should not be reached
}

bool algorithm_prev_permutation(void *first, void *last, size_t size, CompareFuncBool comp) {
    if (first == last) {
        return false;
    }

    char *i = (char *)last - size;
    while (i != (char *)first) {
        char *j = i;
        i -= size;

        if (comp(j, i)) {
            char *k = (char *)last - size;
            while (!comp(k, i)) {
                k -= size;
            }
            swap(i, k, size);
            reverse(j, last, size);
            return true;
        }

        if (i == (char *)first) {
            reverse(first, last, size);
            return false;
        }
    }
    return false;
}

void *algorithm_partition(void *base, size_t num, size_t size, BoolPredicateFunc pred) {
    char *first = (char *)base;
    char *last = first + num * size;

    while (first != last) {
        while (first != last && pred(first)) {
            first += size;
        }
        do {
            last -= size;
            if (first == last) 
                break;
        } while (!pred(last));

        if (first != last) {
            swap(first, last, size);
            first += size;
        }
    }
    return first;
}

void algorithm_generate(void *first, void *last, size_t size, GeneratorFunc gen) {
    char *current = (char *)first;
    while (current != last) {
        gen(current);
        current += size;
    }
}

void algorithm_generate_n(void *first, size_t n, size_t size, GeneratorFunc gen) {
    char *current = (char *)first;
    for (size_t i = 0; i < n; ++i) {
        gen(current);
        current += size;
    }
}

void algorithm_copy_backward(const void *first, const void *last, size_t size, void *result) {
    const char *src = (const char *)last;
    char *dest = (char *)result;

    while (src != (const char *)first) {
        src -= size;  // Move source pointer backwards
        dest -= size; // Move destination pointer backwards
        memcpy(dest, src, size); // Copy element
    }
}

void algorithm_copy_if(const void *first, const void *last, size_t size, void *result, UnaryPredicateFunc pred) {
    const char *src = (const char *)first;
    char *dest = (char *)result;

    while (src != (const char *)last) {
        if (pred(src)) {
            memcpy(dest, src, size);
            dest += size;
        }
        src += size;
    }
}

void algorithm_copy_n(const void *first, size_t n, size_t size, void *result) {
    const char *src = (const char *)first;
    char *dest = (char *)result;

    for (size_t i = 0; i < n; ++i) {
        memcpy(dest, src, size);
        src += size;
        dest += size;
    }
}

Pair algorithm_equal_range(const void *base, size_t num, size_t size, const void *val, CompareFunc comp) {
    Pair range;
    range.first = algorithm_lower_bound(base, num, size, val, comp);
    range.second = algorithm_upper_bound(range.first, num, size, val, comp);
    return range;
}

bool algorithm_includes(const void *first1, size_t num1, size_t size1, const void *first2, size_t num2, size_t size2, 
                        CompareFunc comp) {
    const char *ptr1 = (const char *)first1;
    const char *ptr2 = (const char *)first2;
    const char *last1 = ptr1 + num1 * size1;
    const char *last2 = ptr2 + num2 * size2;

    while (ptr2 != last2) {
        if ((ptr1 == last1) || comp(ptr2, ptr1) < 0) {
            return false;
        }
        if (!comp(ptr1, ptr2)) {
            ptr2 += size2;
        }
        ptr1 += size1;
    }
    return true;
}

size_t algorithm_unique_copy(const void *first, size_t num, size_t size, void *result, CompareFunc comp) {
    if (num == 0) {
        return 0;
    }

    const char *src = (const char *)first;
    char *dst = (char *)result;
    memcpy(dst, src, size); // Copy first element
    size_t count = 1;

    for (size_t i = 1; i < num; ++i) {
        if (comp(dst + (count - 1) * size, src + i * size) != 0) {
            memcpy(dst + count * size, src + i * size, size);
            ++count;
        }
    }
    return count;
}

void algorithm_swap(void *a, void *b, size_t size) {
    void *temp = malloc(size);
    if (!temp) {
        perror("Failed to allocate memory for swap");
        exit(EXIT_FAILURE);
    }

    memcpy(temp, a, size);
    memcpy(a, b, size);
    memcpy(b, temp, size);

    free(temp);
}

void algorithm_swap_ranges(void *first1, void *first2, size_t num, size_t size) {
    char *ptr1 = (char *)first1;
    char *ptr2 = (char *)first2;

    for (size_t i = 0; i < num; ++i) {
        algorithm_swap(ptr1 + i * size, ptr2 + i * size, size);
    }
}

bool algorithm_is_sorted(const void *base, size_t num, size_t size, CompareFunc comp) {
    if (num < 2) {
        return true; // A range with less than two elements is always sorted.
    }

    const char *ptr = (const char *)base;
    for (size_t i = 0; i < num - 1; ++i) {
        if (comp(ptr + i * size, ptr + (i + 1) * size) > 0) {
            return false; // Found an element that is greater than the next element.
        }
    }
    return true; // All elements are in sorted order.
}

void *algorithm_is_sorted_until(const void *base, size_t num, size_t size, CompareFunc comp) {
    if (num < 2) {
        return (void *)((char *)base + num * size); // Entire range is sorted
    }

    const char *ptr = (const char *)base;
    for (size_t i = 0; i < num - 1; ++i) {
        if (comp(ptr + i * size, ptr + (i + 1) * size) > 0) {
            return (void *)(ptr + (i + 1) * size); // Found unsorted element
        }
    }
    return (void *)((char *)base + num * size); // Entire range is sorted
}

void algorithm_rotate(void *first, void *middle, void *last, size_t size) {
    char *next = (char *)middle;

    while ((char *)first != next) {
        swap(first, next, size);
        first = (char *)first + size;
        next = (char *)next + size;

        if (next == (char *)last) {
            next = (char *)middle;
        } 
        else if (first == (char *)middle) {
            middle = next;
        }
    }
}

void algorithm_rotate_copy(const void *first, const void *middle, const void *last, size_t size, void *result) {
    const char *first_ptr = (const char *)first;
    const char *middle_ptr = (const char *)middle;
    const char *last_ptr = (const char *)last;
    char *result_ptr = (char *)result;

    // Copy from middle to last into result
    while (middle_ptr != last_ptr) {
        memcpy(result_ptr, middle_ptr, size);
        result_ptr += size;
        middle_ptr += size;
    }

    // Copy from first to middle into result
    while (first_ptr != (const char *)middle) {
        memcpy(result_ptr, first_ptr, size);
        result_ptr += size;
        first_ptr += size;
    }
}

void algorithm_merge(const void *base1, size_t num1, const void *base2, size_t num2, size_t size, void *result, CompareFunc comp) {
    size_t i = 0, j = 0, k = 0;
    const char *a = (const char *)base1;
    const char *b = (const char *)base2;
    char *res = (char *)result;

    while (i < num1 && j < num2) {
        if (comp(a + i * size, b + j * size) <= 0) {
            memcpy(res + k * size, a + i * size, size);
            i++;
        } 
        else {
            memcpy(res + k * size, b + j * size, size);
            j++;
        }
        k++;
    }

    while (i < num1) {
        memcpy(res + k * size, a + i * size, size);
        i++;
        k++;
    }

    while (j < num2) {
        memcpy(res + k * size, b + j * size, size);
        j++;
        k++;
    }
}

void algorithm_inplace_merge(void *base, size_t middle, size_t num, size_t size, CompareFunc comp) {
    size_t i = 0, j = middle, k;
    char *arr = (char *)base;
    char temp[size];

    while (i < middle && j < num) {
        if (comp(arr + i * size, arr + j * size) <= 0) {
            i++;
        } else {
            memcpy(temp, arr + j * size, size);
            for (k = j; k > i; k--) {
                memcpy(arr + k * size, arr + (k - 1) * size, size);
            }
            memcpy(arr + i * size, temp, size);

            i++;
            middle++;
            j++;
        }
    }
}

void *algorithm_adjacent_find(const void *base, size_t num, size_t size, CompareFunc comp) {
    const char *ptr = (const char *)base;
    for (size_t i = 0; i < num - 1; ++i) {
        if (comp(ptr + i * size, ptr + (i + 1) * size) == 0) {
            return (void *)(ptr + i * size);
        }
    }
    return NULL;
}

Pair algorithm_mismatch(const void *base1, size_t num1, size_t size1, const void *base2, size_t num2, size_t size2, CompareFuncBool comp) {
    const char *ptr1 = (const char *)base1;
    const char *ptr2 = (const char *)base2;

    size_t min_num = num1 < num2 ? num1 : num2;

    for (size_t i = 0; i < min_num; i++) {
        if (comp(ptr1 + i * size1, ptr2 + i * size2) != 0) {
            Pair mismatch;
            mismatch.first = (void *)(ptr1 + i * size1);
            mismatch.second = (void *)(ptr2 + i * size2);
            return mismatch;
        }
    }

    Pair mismatch = {NULL, NULL};
    return mismatch;
}

bool algorithm_is_permutation(const void *base1, size_t num1, size_t size1, const void *base2, size_t num2, size_t size2, CompareFunc comp) {
    // Check if both arrays have the same number of elements
    if (num1 != num2 || size1 != size2) {
        return false;
    }

    // Temporary arrays to mark elements as found
    bool found1[num1], found2[num2];
    memset(found1, 0, sizeof(found1));
    memset(found2, 0, sizeof(found2));

    for (size_t i = 0; i < num1; ++i) {
        for (size_t j = 0; j < num2; ++j) {
            // Check if elements match and neither has been paired before
            if (!found1[i] && !found2[j] && comp((char *)base1 + i * size1, (char *)base2 + j * size2)) {
                found1[i] = true;
                found2[j] = true;
                break;
            }
        }
        // If an element in base1 does not have a match in base2
        if (!found1[i]) {
            return false;
        }
    }

    return true;
}

const void* algorithm_search(const void* first1, const void* last1, size_t size1,const void* first2, const void* last2, size_t size2, CompareFuncBool comp) {
    const char* ptr1 = (const char*)first1;
    const char* ptr2 = (const char*)first2;
    const char* end1 = (const char*)last1;

    if (ptr2 == last2) {
        return first1; // If the second sequence is empty, return the start of the first
    }

    while (ptr1 != end1) {
        const char* it1 = ptr1;
        const char* it2 = ptr2;

        while (comp(it1, it2)) { // Compare elements
            it1 += size1;
            it2 += size2;
            if (it2 == last2) {
                return ptr1; // Found a match
            }
            if (it1 == end1) {
                return last1; // Reached the end of the first sequence
            }
        }
        ptr1 += size1;
    }
    return last1; // No match found
}

const void *algorithm_search_n(const void *first, const void* last, size_t size, size_t count, const void *val, CompareFuncBool comp) {
    const char* ptr = (const char*)first;
    const char* end = (const char*)last;

    while (ptr + size * count <= end) { // Ensure there's enough room for 'count' elements
        size_t matched = 0;
        for (size_t i = 0; i < count; ++i) {
            if (comp(ptr + i * size, val)) {
                matched++;
            } 
            else {
                break;
            }
        }

        if (matched == count) {
            return ptr; // Found the subsequence
        }
        ptr += size; // Move to the next element
    }
    return last; // Subsequence not found
}

void *algorithm_remove(void *base, size_t num, size_t size, const void *val, CompareFunc comp) {
    char *ptr = (char *)base;
    size_t new_num = 0;

    for (size_t i = 0; i < num; ++i) {
        if (comp(ptr + i * size, val) != 0) {
            if (i != new_num) {
                memcpy(ptr + new_num * size, ptr + i * size, size);
            }
            ++new_num;
        }
    }
    return ptr + new_num * size; // Pointer to the new end of the array
}

void algorithm_remove_copy(const void *source, size_t num, size_t size, void *result, const void *val, CompareFunc comp) {
    const char *src = (const char *)source;
    char *dst = (char *)result;

    for (size_t i = 0; i < num; ++i) {
        if (comp(src + i * size, val) != 0) {
            memcpy(dst, src + i * size, size);
            dst += size;
        }
    }
}
Leave a Comment