iris: Refactor code to share 3DSTATE_URB_* packet
[mesa.git] / src / util / u_dynarray.h
index 7b7a093d824aa29febcf893f21db3460996a9fb2..9bed2b9c25c879672e222e6767564bb0b8bd0890 100644 (file)
 #ifndef U_DYNARRAY_H
 #define U_DYNARRAY_H
 
-#include "pipe/p_compiler.h"
-#include "util/u_memory.h"
+#include <stdlib.h>
+#include <string.h>
+#include "ralloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* A zero-initialized version of this is guaranteed to represent an
  * empty array.
  */
 struct util_dynarray
 {
+   void *mem_ctx;
    void *data;
    unsigned size;
    unsigned capacity;
 };
 
 static inline void
-util_dynarray_init(struct util_dynarray *buf)
+util_dynarray_init(struct util_dynarray *buf, void *mem_ctx)
 {
    memset(buf, 0, sizeof(*buf));
+   buf->mem_ctx = mem_ctx;
 }
 
 static inline void
 util_dynarray_fini(struct util_dynarray *buf)
 {
-   if(buf->data)
-   {
-      FREE(buf->data);
-      util_dynarray_init(buf);
+   if (buf->data) {
+      if (buf->mem_ctx) {
+         ralloc_free(buf->data);
+      } else {
+         free(buf->data);
+      }
+      util_dynarray_init(buf, buf->mem_ctx);
    }
 }
 
+static inline void
+util_dynarray_clear(struct util_dynarray *buf)
+{
+       buf->size = 0;
+}
+
+#define DYN_ARRAY_INITIAL_SIZE 64
+
 /* use util_dynarray_trim to reduce the allocated storage */
 static inline void *
 util_dynarray_resize(struct util_dynarray *buf, unsigned newsize)
 {
-   char *p;
-   if(newsize > buf->capacity)
-   {
-      unsigned newcap = buf->capacity << 1;
-      if(newsize > newcap)
-             newcap = newsize;
-      buf->data = REALLOC(buf->data, buf->capacity, newcap);
-      buf->capacity = newcap;
+   void *p;
+   if (newsize > buf->capacity) {
+      if (buf->capacity == 0)
+         buf->capacity = DYN_ARRAY_INITIAL_SIZE;
+
+      while (newsize > buf->capacity)
+         buf->capacity *= 2;
+
+      if (buf->mem_ctx) {
+         buf->data = reralloc_size(buf->mem_ctx, buf->data, buf->capacity);
+      } else {
+         buf->data = realloc(buf->data, buf->capacity);
+      }
    }
 
-   p = (char *)buf->data + buf->size;
+   p = (void *)((char *)buf->data + buf->size);
    buf->size = newsize;
+
    return p;
 }
 
+static inline void
+util_dynarray_clone(struct util_dynarray *buf, void *mem_ctx,
+                    struct util_dynarray *from_buf)
+{
+   util_dynarray_init(buf, mem_ctx);
+   util_dynarray_resize(buf, from_buf->size);
+   memcpy(buf->data, from_buf->data, from_buf->size);
+}
+
 static inline void *
 util_dynarray_grow(struct util_dynarray *buf, int diff)
 {
@@ -89,12 +122,19 @@ util_dynarray_trim(struct util_dynarray *buf)
 {
    if (buf->size != buf->capacity) {
       if (buf->size) {
-         buf->data = REALLOC(buf->data, buf->capacity, buf->size);
+         if (buf->mem_ctx) {
+            buf->data = reralloc_size(buf->mem_ctx, buf->data, buf->size);
+         } else {
+            buf->data = realloc(buf->data, buf->size);
+         }
          buf->capacity = buf->size;
-      }
-      else {
-         FREE(buf->data);
-         buf->data = 0;
+      } else {
+         if (buf->mem_ctx) {
+            ralloc_free(buf->data);
+         } else {
+            free(buf->data);
+         }
+         buf->data = NULL;
          buf->capacity = 0;
       }
    }
@@ -109,6 +149,35 @@ util_dynarray_trim(struct util_dynarray *buf)
 #define util_dynarray_element(buf, type, idx) ((type*)(buf)->data + (idx))
 #define util_dynarray_begin(buf) ((buf)->data)
 #define util_dynarray_end(buf) ((void*)util_dynarray_element((buf), char, (buf)->size))
+#define util_dynarray_num_elements(buf, type) ((buf)->size / sizeof(type))
+
+#define util_dynarray_foreach(buf, type, elem) \
+   for (type *elem = (type *)(buf)->data; \
+        elem < (type *)((char *)(buf)->data + (buf)->size); elem++)
+
+#define util_dynarray_foreach_reverse(buf, type, elem)          \
+   if ((buf)->size > 0)                                         \
+      for (type *elem = util_dynarray_top_ptr(buf, type);       \
+           elem;                                                \
+           elem = elem > (type *)(buf)->data ? elem - 1 : NULL)
+
+#define util_dynarray_delete_unordered(buf, type, v)                    \
+   do {                                                                 \
+      unsigned num_elements = (buf)->size / sizeof(type);               \
+      unsigned i;                                                       \
+      for (i = 0; i < num_elements; i++) {                              \
+         type __v = *util_dynarray_element((buf), type, (i));           \
+         if (v == __v) {                                                \
+            memcpy(util_dynarray_element((buf), type, (i)),             \
+                   util_dynarray_pop_ptr((buf), type), sizeof(type));   \
+            break;                                                      \
+         }                                                              \
+      }                                                                 \
+   } while (0)
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* U_DYNARRAY_H */