100 lines
1.9 KiB
C
100 lines
1.9 KiB
C
|
#pragma once
|
||
|
#include <stdint.h>
|
||
|
#include <stddef.h>
|
||
|
|
||
|
void *memcpy(void *restrict dest, const void *restrict src, size_t n)
|
||
|
{
|
||
|
unsigned char *d = dest;
|
||
|
const unsigned char *s = src;
|
||
|
for (; n; n--) *d++ = *s++;
|
||
|
return dest;
|
||
|
}
|
||
|
|
||
|
void *memset(void *dest, int c, size_t n)
|
||
|
{
|
||
|
unsigned char *s = dest;
|
||
|
size_t k;
|
||
|
|
||
|
/* Fill head and tail with minimal branching. Each
|
||
|
* conditional ensures that all the subsequently used
|
||
|
* offsets are well-defined and in the dest region. */
|
||
|
|
||
|
if (!n) return dest;
|
||
|
s[0] = c;
|
||
|
s[n-1] = c;
|
||
|
if (n <= 2) return dest;
|
||
|
s[1] = c;
|
||
|
s[2] = c;
|
||
|
s[n-2] = c;
|
||
|
s[n-3] = c;
|
||
|
if (n <= 6) return dest;
|
||
|
s[3] = c;
|
||
|
s[n-4] = c;
|
||
|
if (n <= 8) return dest;
|
||
|
|
||
|
/* Advance pointer to align it at a 4-byte boundary,
|
||
|
* and truncate n to a multiple of 4. The previous code
|
||
|
* already took care of any head/tail that get cut off
|
||
|
* by the alignment. */
|
||
|
|
||
|
k = -(uintptr_t)s & 3;
|
||
|
s += k;
|
||
|
n -= k;
|
||
|
n &= -4;
|
||
|
|
||
|
/* Pure C fallback with no aliasing violations. */
|
||
|
for (; n; n--, s++) *s = c;
|
||
|
|
||
|
return dest;
|
||
|
}
|
||
|
|
||
|
size_t strlen(const char *s)
|
||
|
{
|
||
|
const char *a = s;
|
||
|
for (; *s; s++);
|
||
|
return s-a;
|
||
|
}
|
||
|
|
||
|
int memcmp(const void *vl, const void *vr, size_t n)
|
||
|
{
|
||
|
const unsigned char *l=vl, *r=vr;
|
||
|
for (; n && *l == *r; n--, l++, r++);
|
||
|
return n ? *l-*r : 0;
|
||
|
}
|
||
|
|
||
|
char *strncpy(char *restrict d, const char *restrict s, size_t n)
|
||
|
{
|
||
|
for (; n && (*d=*s); n--, s++, d++);
|
||
|
memset(d, 0, n);
|
||
|
return d;
|
||
|
}
|
||
|
|
||
|
char *strcpy(char *restrict dest, const char *restrict src)
|
||
|
{
|
||
|
char *restrict d = dest;
|
||
|
const char *restrict s = src;
|
||
|
for (; (*d=*s); s++, d++);
|
||
|
|
||
|
return d;
|
||
|
}
|
||
|
|
||
|
int strcmp(const char *l, const char *r)
|
||
|
{
|
||
|
for (; *l==*r && *l; l++, r++);
|
||
|
return *(unsigned char *)l - *(unsigned char *)r;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* STDLIB DIV FUNCTIONS */
|
||
|
typedef struct { int quot, rem; } div_t;
|
||
|
typedef struct { long quot, rem; } ldiv_t;
|
||
|
div_t div(int num, int den)
|
||
|
{
|
||
|
return (div_t){ num/den, num%den };
|
||
|
}
|
||
|
ldiv_t ldiv(long num, long den)
|
||
|
{
|
||
|
return (ldiv_t){ num/den, num%den };
|
||
|
}
|
||
|
|