Rich Felker | 0b44a03 | 2011-02-12 00:22:29 -0500 | [diff] [blame] | 1 | #include <string.h> |
Rich Felker | 1701e4f | 2012-09-10 18:16:11 -0400 | [diff] [blame] | 2 | #include <stdint.h> |
| 3 | |
| 4 | #define WT size_t |
| 5 | #define WS (sizeof(WT)) |
Rich Felker | 0b44a03 | 2011-02-12 00:22:29 -0500 | [diff] [blame] | 6 | |
| 7 | void *memmove(void *dest, const void *src, size_t n) |
| 8 | { |
| 9 | char *d = dest; |
| 10 | const char *s = src; |
Rich Felker | 1701e4f | 2012-09-10 18:16:11 -0400 | [diff] [blame] | 11 | |
Rich Felker | 0b44a03 | 2011-02-12 00:22:29 -0500 | [diff] [blame] | 12 | if (d==s) return d; |
Rich Felker | 1701e4f | 2012-09-10 18:16:11 -0400 | [diff] [blame] | 13 | if (s+n <= d || d+n <= s) return memcpy(d, s, n); |
| 14 | |
| 15 | if (d<s) { |
| 16 | if ((uintptr_t)s % WS == (uintptr_t)d % WS) { |
| 17 | while ((uintptr_t)d % WS) { |
| 18 | if (!n--) return dest; |
| 19 | *d++ = *s++; |
| 20 | } |
| 21 | for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s; |
| 22 | } |
| 23 | for (; n; n--) *d++ = *s++; |
| 24 | } else { |
| 25 | if ((uintptr_t)s % WS == (uintptr_t)d % WS) { |
| 26 | while ((uintptr_t)(d+n) % WS) { |
| 27 | if (!n--) return dest; |
| 28 | d[n] = s[n]; |
| 29 | } |
| 30 | while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n); |
| 31 | } |
| 32 | while (n) n--, d[n] = s[n]; |
| 33 | } |
| 34 | |
Rich Felker | 594318f | 2012-09-06 20:25:48 -0400 | [diff] [blame] | 35 | return dest; |
Rich Felker | 0b44a03 | 2011-02-12 00:22:29 -0500 | [diff] [blame] | 36 | } |