diff options
| -rw-r--r-- | src/string/memmove.c | 31 | 
1 files changed, 27 insertions, 4 deletions
| diff --git a/src/string/memmove.c b/src/string/memmove.c index 9153a644..27f670e1 100644 --- a/src/string/memmove.c +++ b/src/string/memmove.c @@ -1,13 +1,36 @@  #include <string.h> +#include <stdint.h> + +#define WT size_t +#define WS (sizeof(WT))  void *memmove(void *dest, const void *src, size_t n)  {  	char *d = dest;  	const char *s = src; +  	if (d==s) return d; -	if ((size_t)(d-s) < n) -		while (n--) d[n] = s[n]; -	else -		while (n--) *d++ = *s++; +	if (s+n <= d || d+n <= s) return memcpy(d, s, n); + +	if (d<s) { +		if ((uintptr_t)s % WS == (uintptr_t)d % WS) { +			while ((uintptr_t)d % WS) { +				if (!n--) return dest; +				*d++ = *s++; +			} +			for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s; +		} +		for (; n; n--) *d++ = *s++; +	} else { +		if ((uintptr_t)s % WS == (uintptr_t)d % WS) { +			while ((uintptr_t)(d+n) % WS) { +				if (!n--) return dest; +				d[n] = s[n]; +			} +			while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n); +		} +		while (n) n--, d[n] = s[n]; +	} +  	return dest;  } | 
