aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2018-11-24 01:48:25 +0100
committerMattias Andrée <maandree@kth.se>2018-11-24 01:48:25 +0100
commit1ebef0a393ddbc27a1e6071d8364b43a42277c77 (patch)
tree3d43f20ab0c3c9903b11b06a14d693ee2ea17ea0
parentAdd tests (diff)
downloadlibsimple-1ebef0a393ddbc27a1e6071d8364b43a42277c77.tar.gz
libsimple-1ebef0a393ddbc27a1e6071d8364b43a42277c77.tar.bz2
libsimple-1ebef0a393ddbc27a1e6071d8364b43a42277c77.tar.xz
Add [raw]memelem{cpy,move}
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile4
-rw-r--r--libsimple/mem.h30
-rw-r--r--libsimple/memelem.h78
-rw-r--r--libsimple/str.h20
-rw-r--r--libsimple/strn.h26
-rw-r--r--memelemcpy.c94
-rw-r--r--memelemmove.c124
-rw-r--r--rawmemelem.c2
-rw-r--r--rawmemelemcpy.c158
-rw-r--r--rawmemelemmove.c340
-rw-r--r--vmemalloc.c6
11 files changed, 839 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index 047cc45..6937830 100644
--- a/Makefile
+++ b/Makefile
@@ -74,6 +74,8 @@ OBJ =\
memdup.o\
memelem.o\
memelem_inv.o\
+ memelemcpy.o\
+ memelemmove.o\
memelemscan.o\
memelemscan_inv.o\
memends.o\
@@ -106,6 +108,8 @@ OBJ =\
rawmemchr_inv.o\
rawmemelem.o\
rawmemelem_inv.o\
+ rawmemelemcpy.o\
+ rawmemelemmove.o\
rawmemrcasechr.o\
rawmemrcasechr_inv.o\
rawmemrchr.o\
diff --git a/libsimple/mem.h b/libsimple/mem.h
index e6fb310..5ec8f9e 100644
--- a/libsimple/mem.h
+++ b/libsimple/mem.h
@@ -607,10 +607,10 @@ static inline void *libsimple_mempset(void *__s, int __c, size_t __n)
* occurence of the specified byte value in the specified byte
* array, its behaviour is undefined
*
- * @param d The location the byt array shall be copied to
- * @param s The byte array to copy
- * @param c The byte that stops the copying
- * @param `&rawmemchr(d, c)[1]` (after copying)
+ * @param d The location the byte array shall be copied to
+ * @param s The byte array to copy
+ * @param c The byte that stops the copying
+ * @return `&rawmemchr(d, c)[1]` (after copying)
*/
static inline void *
libsimple_rawmemccpy(void *restrict __d_, const void *restrict __s_, int __c_) /* TODO man */
@@ -628,13 +628,13 @@ libsimple_rawmemccpy(void *restrict __d_, const void *restrict __s_, int __c_) /
/**
* Move a string, but stop after a specific character
*
- * @param d The location the byt array shall be copied to
- * @param s The byte array to copy
- * @param c The byte that stops the copying
- * @param n The length of `s`
- * @param `&rawmemchr(d, c)[1]` (after copying) if `c` can
- * be found within the first `n` bytes of `s` (before
- * copying), `NULL` otherwise
+ * @param d The location the byte array shall be copied to
+ * @param s The byte array to copy
+ * @param c The byte that stops the copying
+ * @param n The length of `s`
+ * @return `&rawmemchr(d, c)[1]` (after copying) if `c` can
+ * be found within the first `n` bytes of `s` (before
+ * copying), `NULL` otherwise
*/
void *libsimple_memcmove(void *__d_, const void *__s_, int __c_, size_t __n);
#ifndef memcmove
@@ -650,10 +650,10 @@ void *libsimple_memcmove(void *__d_, const void *__s_, int __c_, size_t __n);
* occurence of the specified byte value in the specified byte
* array, its behaviour is undefined
*
- * @param d The location the byt array shall be copied to
- * @param s The byte array to copy
- * @param c The byte that stops the copying
- * @param `&rawmemchr(d, c)[1]` (after copying)
+ * @param d The location the byte array shall be copied to
+ * @param s The byte array to copy
+ * @param c The byte that stops the copying
+ * @return `&rawmemchr(d, c)[1]` (after copying)
*/
static inline void *
libsimple_rawmemcmove(void *__d_, const void *__s_, int __c_) /* TODO man */
diff --git a/libsimple/memelem.h b/libsimple/memelem.h
index bce3e0c..4533db8 100644
--- a/libsimple/memelem.h
+++ b/libsimple/memelem.h
@@ -36,7 +36,7 @@ void *libsimple_memelem(const void *, size_t, const void *, size_t);
* returned pointer and such that `(r - haystack) % nneedle == 0`
*/
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __returns_nonnull__, __warn_unused_result__)))
-void *libsimple_rawmemelem(const void *, const void *, size_t); /* TODO man */
+void *libsimple_rawmemelem(const void *, const void *, size_t);
#ifndef rawmemelem
# define rawmemelem libsimple_rawmemelem
#endif
@@ -246,6 +246,82 @@ static inline void *libsimple_memsetelem(void *__buf, const void *__item, size_t
/**
+ * Copy elements in an array to another array, but stop after a specific element
+ *
+ * @param d The location the array shall be copied to
+ * @param s The array to copy
+ * @param elem The element that stops the copying
+ * @param size The size of each element
+ * @param n The maximum number of elements to copy
+ * @return `&rawmemelem(d, c, size)[size]` (after copying) if `elem`
+ * can be found within the first `n` elements of `s` (before
+ * copying), `NULL` otherwise
+ */
+void *libsimple_memelemcpy(void *restrict __d, const void *restrict __s, const void *restrict __elem, size_t __size, size_t __n);
+#ifndef memelemcpy
+# define memelemcpy libsimple_memelemcpy
+#endif
+
+
+/**
+ * Move elements in an array, but stop after a specific element
+ *
+ * @param d The location the array shall be copied to
+ * @param s The array to copy
+ * @param elem The element that stops the copying
+ * @param size The size of each element
+ * @param n The maximum number of elements to copy
+ * @return `&rawmemelem(d, c, size)[size]` (after copying) if `elem`
+ * can be found within the first `n` elements of `s` (before
+ * copying), `NULL` otherwise
+ */
+void *libsimple_memelemmove(void *__d, const void *__s, const void *restrict __elem, size_t __size, size_t __n);
+#ifndef memelemmove
+# define memelemmove libsimple_memelemmove
+#endif
+
+
+/**
+ * Copy elements in an array to another array, but stop after a specific element
+ *
+ * This function is optimised for instances where it is already
+ * known that there is at least one occurence; if there is no
+ * occurence of the specified value in the specified array, its
+ * behaviour is undefined
+ *
+ * @param d The location the array shall be copied to
+ * @param s The array to copy
+ * @param elem The element that stops the copying
+ * @param size The size of each element
+ * @return `&rawmemelem(d, c, size)[size]` (after copying)
+ */
+void *libsimple_rawmemelemcpy(void *restrict __d, const void *restrict __s, const void *restrict __elem, size_t __size);
+#ifndef rawmemelemcpy
+# define rawmemelemcpy libsimple_rawmemelemcpy
+#endif
+
+
+/**
+ * Move elements in an array, but stop after a specific element
+ *
+ * This function is optimised for instances where it is already
+ * known that there is at least one occurence; if there is no
+ * occurence of the specified value in the specified array, its
+ * behaviour is undefined
+ *
+ * @param d The location the array shall be copied to
+ * @param s The array to copy
+ * @param elem The element that stops the copying
+ * @param size The size of each element
+ * @return `&rawmemelem(d, c, size)[size]` (after copying)
+ */
+void *libsimple_rawmemelemmove(void *__d, const void *__s, const void *restrict __elem, size_t __size);
+#ifndef rawmemelemmove
+# define rawmemelemmove libsimple_rawmemelemmove
+#endif
+
+
+/**
* Replace all instances of an element in an array of
* elements with another element
*
diff --git a/libsimple/str.h b/libsimple/str.h
index 48d3aa9..5a5c146 100644
--- a/libsimple/str.h
+++ b/libsimple/str.h
@@ -546,11 +546,11 @@ libsimple_stpset(char *__s, int __c_) /* TODO man */
* Copy a string, but stop after a specific character,
* the new string will be NUL-terminated
*
- * @param d The location the string shall be copied to
- * @param s The string to copy
- * @param c The character that stops the copying
- * @param `&strchr(d, c)[1]` (after copying) if `c` can be
- * found in `s`, `NULL` otherwise
+ * @param d The location the string shall be copied to
+ * @param s The string to copy
+ * @param c The character that stops the copying
+ * @return `&strchr(d, c)[1]` (after copying) if `c` can be
+ * found in `s`, `NULL` otherwise
*/
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline char *
@@ -571,11 +571,11 @@ libsimple_strccpy(char *restrict __d, const char *restrict __s, int __c_) /* TOD
/**
* Move a string, but stop after a specific character
*
- * @param d The location the string shall be moved to
- * @param s The string to copy
- * @param c The character that stops the copying
- * @param `&strchr(d, c)[1]` (after copying) if `c` can be
- * found in `s` (before copying), `NULL` otherwise
+ * @param d The location the string shall be moved to
+ * @param s The string to copy
+ * @param c The character that stops the copying
+ * @return `&strchr(d, c)[1]` (after copying) if `c` can be
+ * found in `s` (before copying), `NULL` otherwise
*/
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
char *libsimple_strcmove(char *, const char *, int);
diff --git a/libsimple/strn.h b/libsimple/strn.h
index eaff234..59539e1 100644
--- a/libsimple/strn.h
+++ b/libsimple/strn.h
@@ -621,12 +621,12 @@ libsimple_stpnset(char *__s, int __c_, size_t __n) /* TODO man */
* the new string will be NUL-terminated if it is
* shorter than `n` bytes
*
- * @param d The location the string shall be copied to
- * @param s The string to copy
- * @param c The character that stops the copying
- * @param n The maximum number of bytes to copy
- * @param `&strchr(d, c)[1]` (after copying) if `c` can be
- * found in `s`, `NULL` otherwise
+ * @param d The location the string shall be copied to
+ * @param s The string to copy
+ * @param c The character that stops the copying
+ * @param n The maximum number of bytes to copy
+ * @return `&strchr(d, c)[1]` (after copying) if `c` can be
+ * found in `s`, `NULL` otherwise
*/
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline char *
@@ -653,13 +653,13 @@ libsimple_strnccpy(char *restrict __d, const char *restrict __s, int __c_, size_
/**
* Move a string, but stop after a specific character
*
- * @param d The location the string shall be moved to
- * @param s The string to copy
- * @param c The character that stops the copying
- * @param n The maximum number of bytes to move
- * @param `&strchr(d, c)[1]` (after copying) if `c` can be
- * found within the first `n` bytes of `s` (before
- * copying), `NULL` otherwise
+ * @param d The location the string shall be moved to
+ * @param s The string to copy
+ * @param c The character that stops the copying
+ * @param n The maximum number of bytes to move
+ * @return `&strchr(d, c)[1]` (after copying) if `c` can be
+ * found within the first `n` bytes of `s` (before
+ * copying), `NULL` otherwise
*/
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
char *libsimple_strncmove(char *, const char *, int, size_t);
diff --git a/memelemcpy.c b/memelemcpy.c
new file mode 100644
index 0000000..da32946
--- /dev/null
+++ b/memelemcpy.c
@@ -0,0 +1,94 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+static inline uint8_t *
+memelemcpy8(uint8_t *restrict d, const uint8_t *restrict s, uint8_t elem, size_t n)
+{
+ for (; n; s++, n--)
+ if ((*d++ = *s) == elem)
+ return d;
+ return NULL;
+}
+
+
+static inline uint16_t *
+memelemcpy16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem, size_t n)
+{
+ for (; n; s++, n--)
+ if ((*d++ = *s) == elem)
+ return d;
+ return NULL;
+}
+
+
+static inline uint32_t *
+memelemcpy32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem, size_t n)
+{
+ for (; n; s++, n--)
+ if ((*d++ = *s) == elem)
+ return d;
+ return NULL;
+}
+
+
+static inline uint64_t *
+memelemcpy64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem, size_t n)
+{
+ for (; n; s++, n--)
+ if ((*d++ = *s) == elem)
+ return d;
+ return NULL;
+}
+
+
+static inline char *
+memelemcpyx(char *restrict d, const char *restrict s, const char *restrict elem, size_t size, size_t n)
+{
+ size_t i;
+ for (; n; s += size, n--) {
+ for (i = 0; i < size; i++)
+ d[i] = s[i];
+ for (i = 0; i < size; i++)
+ if (d[i] != elem[i])
+ goto next;
+ d += size;
+ return d;
+ next:
+ d += size;
+ }
+ return NULL;
+}
+
+
+void *
+libsimple_memelemcpy(void *restrict d, const void *restrict s, const void *restrict elem, size_t size, size_t n) /* TODO test, man */
+{
+ switch (size) {
+ case 0:
+ return d;
+ case 1:
+ return memelemcpy8(d, s, *(const uint8_t *)elem, n);
+ case 2:
+ return memelemcpy16(d, s, *(const uint16_t *)elem, n);
+ case 4:
+ return memelemcpy32(d, s, *(const uint32_t *)elem, n);
+ case 8:
+ return memelemcpy64(d, s, *(const uint64_t *)elem, n);
+ default:
+ return memelemcpyx(d, s, elem, size, n);
+ }
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/memelemmove.c b/memelemmove.c
new file mode 100644
index 0000000..2a90e26
--- /dev/null
+++ b/memelemmove.c
@@ -0,0 +1,124 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+#define MEMELEMMOVE(TYPE)\
+ do {\
+ TYPE *p;\
+ if (d <= s) {\
+ for (; n; n--, s++)\
+ if ((*d++ = *s) == elem)\
+ return d;\
+ } else {\
+ for (p = *(TYPE **)(void *)&s; n; n--, p++) {\
+ if (*p == elem) {\
+ n = (size_t)(p - s);\
+ p = &d[n + 1];\
+ do { d[n] = s[n]; } while (n--);\
+ return p;\
+ }\
+ }\
+ for (n = (size_t)(p - s); n;) {\
+ n--;\
+ d[n] = s[n];\
+ }\
+ }\
+ return NULL;\
+ } while (0)
+
+
+static uint16_t *
+memelemmove16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem, size_t n)
+{
+ MEMELEMMOVE(uint16_t);
+}
+
+
+static uint32_t *
+memelemmove32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem, size_t n)
+{
+ MEMELEMMOVE(uint32_t);
+}
+
+
+static uint64_t *
+memelemmove64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem, size_t n)
+{
+ MEMELEMMOVE(uint64_t);
+}
+
+
+static char *
+memelemmovex(char *restrict d, const char *restrict s, const char *restrict elem, size_t size, size_t n)
+{
+ char *p;
+ size_t i;
+ if (d <= s) {
+ for (; n; s += size, n--) {
+ for (i = 0; i < size; i++)
+ d[i] = s[i];
+ for (i = 0; i < size; i++)
+ if (d[i] != elem[i])
+ goto next_forwards;
+ d += size;
+ return d;
+ next_forwards:
+ d += size;
+ }
+ return NULL;
+ } else {
+ for (p = *(char **)(void *)&s; n; n--) {
+ for (i = 0; i < size; i++)
+ if (p[i] != elem[i])
+ goto next_backwards;
+
+ p += size;
+ n = (size_t)(p - s);
+ p = &d[n];
+ goto out_backwards;
+ next_backwards:
+ p += size;
+ }
+ n = (size_t)(p - s);
+ p = NULL;
+ out_backwards:
+ while (n) {
+ n--;
+ d[n] = s[n];
+ }
+ return p;
+ }
+}
+
+
+void *
+libsimple_memelemmove(void *d, const void *s, const void *restrict elem, size_t size, size_t n) /* TODO test, man */
+{
+ switch (size) {
+ case 0:
+ return d;
+ case 1:
+ return memcmove(d, s, *(const char *)elem, n);
+ case 2:
+ return memelemmove16(d, s, *(const uint16_t *)elem, n);
+ case 4:
+ return memelemmove32(d, s, *(const uint32_t *)elem, n);
+ case 8:
+ return memelemmove64(d, s, *(const uint64_t *)elem, n);
+ default:
+ return memelemmovex(d, s, elem, size, n);
+ }
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/rawmemelem.c b/rawmemelem.c
index d2d743a..92beedb 100644
--- a/rawmemelem.c
+++ b/rawmemelem.c
@@ -4,7 +4,7 @@
void *
-libsimple_rawmemelem(const void *hay_, const void *sub_, size_t subn)
+libsimple_rawmemelem(const void *hay_, const void *sub_, size_t subn) /* TODO man */
{
switch (subn) {
case 0:
diff --git a/rawmemelemcpy.c b/rawmemelemcpy.c
new file mode 100644
index 0000000..2f0f9f0
--- /dev/null
+++ b/rawmemelemcpy.c
@@ -0,0 +1,158 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+static inline uint8_t *
+rawmemelemcpy8(uint8_t *restrict d, const uint8_t *restrict s, uint16_t elem)
+{
+ for (; (*d++ = *s) != elem; s++);
+ return d;
+}
+
+
+static inline uint16_t *
+rawmemelemcpy16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem)
+{
+ for (; (*d++ = *s) != elem; s++);
+ return d;
+}
+
+
+static inline uint32_t *
+rawmemelemcpy32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem)
+{
+ for (; (*d++ = *s) != elem; s++);
+ return d;
+}
+
+
+static inline uint64_t *
+rawmemelemcpy64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem)
+{
+ for (; (*d++ = *s) != elem; s++);
+ return d;
+}
+
+
+static inline char *
+rawmemelemcpyx(char *restrict d, const char *restrict s, const char *restrict elem, size_t size)
+{
+ size_t i;
+ for (;; s += size) {
+ for (i = 0; i < size; i++)
+ d[i] = s[i];
+ for (i = 0; i < size; i++)
+ if (d[i] != elem[i])
+ goto next;
+ d += size;
+ return d;
+ next:
+ d += size;
+ }
+}
+
+
+void *
+libsimple_rawmemelemcpy(void *restrict d, const void *restrict s, const void *restrict elem, size_t size) /* TODO man */
+{
+ switch (size) {
+ case 0:
+ return d;
+ case 1:
+ return rawmemelemcpy8(d, s, *(const uint8_t *)elem);
+ case 2:
+ return rawmemelemcpy16(d, s, *(const uint16_t *)elem);
+ case 4:
+ return rawmemelemcpy32(d, s, *(const uint32_t *)elem);
+ case 8:
+ return rawmemelemcpy64(d, s, *(const uint64_t *)elem);
+ default:
+ return rawmemelemcpyx(d, s, elem, size);
+ }
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ char buf[1024];
+
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "hello", "o", 0) == &buf[0]);
+ assert(!strncmp(buf, "x", 1));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "hello", "l", 0) == &buf[0]);
+ assert(!strncmp(buf, "x", 1));
+
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "hello", "o", 1) == &buf[5]);
+ assert(!strncmp(buf, "hellox", 6));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "hello", "l", 1) == &buf[3]);
+ assert(!strncmp(buf, "helx", 4));
+
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, ".h.e.l.l.o", ".o", 2) == &buf[5 * 2]);
+ assert(!strncmp(buf, ".h.e.l.l.ox", 11));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, ".h.e.l.l.o", ".l", 2) == &buf[3 * 2]);
+ assert(!strncmp(buf, ".h.e.lx", 7));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, ".h.l.ll..o", "l.", 2) == &buf[4 * 2]);
+ assert(!strncmp(buf, ".h.l.ll.x", 9));
+
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "..h..e..l..l..o", "..o", 3) == &buf[5 * 3]);
+ assert(!strncmp(buf, "..h..e..l..l..ox", 16));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "..h..e..l..l..o", "..l", 3) == &buf[3 * 3]);
+ assert(!strncmp(buf, "..h..e..lx", 10));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "..h..l..ll....o", "l..", 3) == &buf[4 * 3]);
+ assert(!strncmp(buf, "..h..l..ll..x", 13));
+
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "...h...e...l...l...o", "...o", 4) == &buf[5 * 4]);
+ assert(!strncmp(buf, "...h...e...l...l...ox", 21));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "...h...e...l...l...o", "...l", 4) == &buf[3 * 4]);
+ assert(!strncmp(buf, "...h...e...lx", 13));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, "...h...l...ll......o", "l...", 4) == &buf[4 * 4]);
+ assert(!strncmp(buf, "...h...l...ll...x", 17));
+
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, ".......h.......e.......l.......l.......o", ".......o", 8) == &buf[5 * 8]);
+ assert(!strncmp(buf, ".......h.......e.......l.......l.......ox", 21));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, ".......h.......e.......l.......l.......o", ".......l", 8) == &buf[3 * 8]);
+ assert(!strncmp(buf, ".......h.......e.......lx", 13));
+
+ memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ assert(libsimple_rawmemelemcpy(buf, ".......h.......l.......ll..............o", "l.......", 8) == &buf[4 * 8]);
+ assert(!strncmp(buf, ".......h.......l.......ll.......x", 21));
+
+
+ return 0;
+}
+
+#endif
diff --git a/rawmemelemmove.c b/rawmemelemmove.c
new file mode 100644
index 0000000..c663219
--- /dev/null
+++ b/rawmemelemmove.c
@@ -0,0 +1,340 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+#define RAWMEMELEMMOVE(TYPE)\
+ do {\
+ TYPE *p;\
+ size_t n;\
+ if (d <= s) {\
+ for (; (*d++ = *s) != elem; s++);\
+ return d;\
+ } else {\
+ for (p = *(TYPE **)(void *)&s; *p++ != elem;);\
+ n = (size_t)(p - s);\
+ p = &d[n];\
+ while (n) {\
+ n--;\
+ d[n] = s[n];\
+ }\
+ return p;\
+ }\
+ } while (0)
+
+
+static uint16_t *
+rawmemelemmove16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem)
+{
+ RAWMEMELEMMOVE(uint16_t);
+}
+
+
+static uint32_t *
+rawmemelemmove32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem)
+{
+ RAWMEMELEMMOVE(uint32_t);
+}
+
+
+static uint64_t *
+rawmemelemmove64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem)
+{
+ RAWMEMELEMMOVE(uint64_t);
+}
+
+
+static char *
+rawmemelemmovex(char *restrict d, const char *restrict s, const char *restrict elem, size_t size)
+{
+ char *p;
+ size_t i, n;
+ if (d <= s) {
+ for (;; s += size) {
+ for (i = 0; i < size; i++)
+ d[i] = s[i];
+ for (i = 0; i < size; i++)
+ if (d[i] != elem[i])
+ goto next_forwards;
+ d += size;
+ return d;
+ next_forwards:
+ d += size;
+ }
+ } else {
+ for (p = *(char **)(void *)&s;;) {
+ for (i = 0; i < size; i++)
+ if (p[i] != elem[i])
+ goto next_backwards;
+ p += size;
+ break;
+ next_backwards:
+ p += size;
+ }
+ n = (size_t)(p - s);
+ p = &d[n];
+ while (n) {
+ n--;
+ d[n] = s[n];
+ }
+ return p;
+ }
+}
+
+
+void *
+libsimple_rawmemelemmove(void *d, const void *s, const void *restrict elem, size_t size) /* TODO man */
+{
+ switch (size) {
+ case 0:
+ return d;
+ case 1:
+ return rawmemcmove(d, s, *(const char *)elem);
+ case 2:
+ return rawmemelemmove16(d, s, *(const uint16_t *)elem);
+ case 4:
+ return rawmemelemmove32(d, s, *(const uint32_t *)elem);
+ case 8:
+ return rawmemelemmove64(d, s, *(const uint64_t *)elem);
+ default:
+ return rawmemelemmovex(d, s, elem, size);
+ }
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ char buf[1024];
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "", 0) == &buf[5]);
+ assert(!strncmp(buf, "-----hello-", 11));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "", 0) == &buf[3]);
+ assert(!strncmp(buf, "-----hello-", 11));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[3], "", 0) == &buf[5]);
+ assert(!strncmp(buf, "-----hello-", 11));
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "o", 1) == &buf[5 + 5]);
+ assert(!strncmp(buf, "-----hello-", 11));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';;
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "l", 1) == &buf[5 + 3]);
+ assert(!strncmp(buf, "-----hello-", 11));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "o", 1) == &buf[3 + 5]);
+ assert(!strncmp(buf, "---hellolo-", 11));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "l", 1) == &buf[3 + 3]);
+ assert(!strncmp(buf, "---helello-", 11));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "o", 1) == &buf[8 + 5]);
+ assert(!strncmp(buf, "-----helhello-", 14));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "hello")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "l", 1) == &buf[8 + 3]);
+ assert(!strncmp(buf, "-----helhel-", 12));
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".o", 2) == &buf[5 + 5 * 2]);
+ assert(!strncmp(buf, "-----.h.e.l.l.o-", 16));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-';;
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".l", 2) == &buf[5 + 3 * 2]);
+ assert(!strncmp(buf, "-----.h.e.l.l.o-", 16));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".o", 2) == &buf[3 + 5 * 2]);
+ assert(!strncmp(buf, "---.h.e.l.l.o.o-", 16));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".l", 2) == &buf[3 + 3 * 2]);
+ assert(!strncmp(buf, "---.h.e.l.l.l.o-", 16));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".o", 2) == &buf[8 + 5 * 2]);
+ assert(!strncmp(buf, "-----.h..h.e.l.l.o-", 19));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".l", 2) == &buf[8 + 3 * 2]);
+ assert(!strncmp(buf, "-----.h..h.e.lo-", 16));
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "..o", 3) == &buf[5 + 5 * 3]);
+ assert(!strncmp(buf, "-----..h..e..l..l..o-", 21));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-';;
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "..l", 3) == &buf[5 + 3 * 3]);
+ assert(!strncmp(buf, "-----..h..e..l..l..o-", 21));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "..o", 3) == &buf[3 + 5 * 3]);
+ assert(!strncmp(buf, "---..h..e..l..l..o.o-", 21));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "..l", 3) == &buf[3 + 3 * 3]);
+ assert(!strncmp(buf, "---..h..e..l.l..l..o-", 21));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "..o", 3) == &buf[8 + 5 * 3]);
+ assert(!strncmp(buf, "-----..h..h..e..l..l..o-", 24));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "..l", 3) == &buf[8 + 3 * 3]);
+ assert(!strncmp(buf, "-----..h..h..e..l..o-", 21));
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "...o", 4) == &buf[5 + 5 * 4]);
+ assert(!strncmp(buf, "-----...h...e...l...l...o-", 26));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-';;
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "...l", 4) == &buf[5 + 3 * 4]);
+ assert(!strncmp(buf, "-----...h...e...l...l...o-", 26));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "...o", 4) == &buf[3 + 5 * 4]);
+ assert(!strncmp(buf, "---...h...e...l...l...o.o-", 26));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "...l", 4) == &buf[3 + 3 * 4]);
+ assert(!strncmp(buf, "---...h...e...l.l...l...o-", 26));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "...o", 4) == &buf[8 + 5 * 4]);
+ assert(!strncmp(buf, "-----......h...e...l...l...o-", 29));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "...l", 4) == &buf[8 + 3 * 4]);
+ assert(!strncmp(buf, "-----......h...e...ll...o-", 26));
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".......o", 8) == &buf[5 + 5 * 8]);
+ assert(!strncmp(buf, "-----.......h.......e.......l.......l.......o-", 46));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-';;
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".......l", 8) == &buf[5 + 3 * 8]);
+ assert(!strncmp(buf, "-----.......h.......e.......l.......l.......o-", 46));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".......o", 8) == &buf[3 + 5 * 8]);
+ assert(!strncmp(buf, "---.......h.......e.......l.......l.......o.o-", 46));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".......l", 8) == &buf[3 + 3 * 8]);
+ assert(!strncmp(buf, "---.......h.......e.......l.l.......l.......o-", 46));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".......o", 8) == &buf[8 + 5 * 8]);
+ assert(!strncmp(buf, "-----..........h.......e.......l.......l.......o-", 49));
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".......l", 8) == &buf[8 + 3 * 8]);
+ assert(!strncmp(buf, "-----..........h.......e.......l....l.......o-", 46));
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".a.a.aa..a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a.", 2) == &buf[5 + 4 * 2]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".a.a.aa..a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a.", 2) == &buf[3 + 4 * 2]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".a.a.aa..a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a.", 2) == &buf[8 + 4 * 2]);
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..a..a..aa....a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a..", 3) == &buf[5 + 4 * 3]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..a..a..aa....a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a..", 3) == &buf[3 + 4 * 3]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "..a..a..aa....a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a..", 3) == &buf[8 + 4 * 3]);
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...a...a...aa......a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a...", 4) == &buf[5 + 4 * 4]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...a...a...aa......a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a...", 4) == &buf[3 + 4 * 4]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], "...a...a...aa......a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a...", 4) == &buf[8 + 4 * 4]);
+
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......a.......a.......aa..............a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a.......", 8) == &buf[5 + 4 * 8]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......a.......a.......aa..............a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a.......", 8) == &buf[3 + 4 * 8]);
+
+ memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0';
+ stpcpy(&buf[5], ".......a.......a.......aa..............a")[0] = '-';
+ assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a.......", 8) == &buf[8 + 4 * 8]);
+
+
+ return 0;
+}
+
+#endif
diff --git a/vmemalloc.c b/vmemalloc.c
index f79ebb0..8d92035 100644
--- a/vmemalloc.c
+++ b/vmemalloc.c
@@ -183,7 +183,7 @@ void *
libsimple_vmemalloc(size_t n, va_list ap) /* TODO test ([v]{mem,array}alloc) */
{
struct memalloc_state state;
- size_t misalignment, size, cacheline, min, max;
+ size_t misalignment, size, cacheline = 64, min, max;
void *ptr = NULL;
int saved_errno;
long int tmp;
@@ -225,10 +225,10 @@ libsimple_vmemalloc(size_t n, va_list ap) /* TODO test ([v]{mem,array}alloc) */
if (state.cache_align || !state.cache_split) {
#ifdef _SC_LEVEL1_DCACHE_LINESIZE
tmp = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
- cacheline = (size_t)(tmp < 1 ? 64L : tmp);
+ if (tmp >= 1)
+ cacheline = (size_t)tmp;
#else
(void) tmp;
- cacheline = 64;
#endif
}