I wonder if there is a better way of doing this. I don't lik the repetetive code in sorted_asc and sorted_desc.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>


bool sorted_asc(void *data, size_t size, size_t datasize, 
                int (*compare)(const void *a, const void* b))
{
    unsigned char *p = data;
    for (int i = 0; i < size - 1 ; i++)
    {
        if(compare(p + i * datasize, p + ((i + 1) * datasize)) > 0)
            return false; 
    }
    return true;
}


bool sorted_desc(void *data, size_t size, size_t datasize, 
                int (*compare)(const void *a, const void* b))
{
    unsigned char *p = data;
    for (int i = 0; i < size - 1 ; i++)
    {
        if(compare(p + i * datasize, p + ((i + 1) * datasize)) < 0)
            return false; 
    }
    return true;
}

/* sorted - check if an array is sorted - either in descending or  
 * ascending order
 *
 * Possible use:
 * assert(sorted(...));
 * qsort(...)
 * or
 * assert(!sorted(...))
 * qsort(...)
 */
bool sorted(void *data, size_t size, size_t datasize, 
                   int (*compare)(const void *a, const void* b))
{
    return sorted_asc(data, size, datasize, compare) ||
              sorted_desc(data, size, datasize, compare);
    
}


int compare_int(const void *a, const void *b)
{
    const int *i1 = a;
    const int *i2 = b;
    
    return *i1 - *i2;
}


int main(int argc, char **argv)
{
    int a1[] = {1,2,3,4,5};
    int a2[] = {5,4,3,2,1};
    int a3[] = {3,2,1,4,5};
    
    assert(sorted_asc(a1, 5, sizeof(int), compare_int));
    assert(sorted_desc(a2, 5, sizeof(int), compare_int));
    assert(!sorted(a3, 5, sizeof(int), compare_int));
    assert(sorted(a1, 5, sizeof(int), compare_int));
    assert(sorted(a2, 5, sizeof(int), compare_int));
    
    printf("ALL TESTS PASSED\n");
    return EXIT_SUCCESS;
}