Refactor array_utils out of BLI_array

BLI_array.h is for resizing array macros, where as array_utils can operate on any arrays.
This commit is contained in:
Campbell Barton
2015-02-14 07:28:15 +11:00
parent 2af905391d
commit 7a977df6d4
7 changed files with 172 additions and 90 deletions

View File

@@ -34,9 +34,10 @@
*/ */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* internal defines */ /** \name Internal defines
* \{ */
/* this returns the entire size of the array, including any buffering. */ /** this returns the entire size of the array, including any buffering. */
#define _bli_array_totalsize_dynamic(arr) ( \ #define _bli_array_totalsize_dynamic(arr) ( \
((arr) == NULL) ? \ ((arr) == NULL) ? \
0 : \ 0 : \
@@ -53,7 +54,10 @@
_bli_array_totalsize_dynamic(arr)) \ _bli_array_totalsize_dynamic(arr)) \
) )
/* BLI_array.c /** \} */
/** BLI_array.c
* *
* Doing the realloc in a macro isn't so simple, * Doing the realloc in a macro isn't so simple,
* so use a function the macros can use. * so use a function the macros can use.
@@ -64,23 +68,27 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* public defines */
/* use sizeof(*(arr)) to ensure the array exists and is an array */ /** \name Public defines
* \{ */
/** use ``sizeof(*(arr))`` to ensure the array exists and is an array */
#define BLI_array_declare(arr) \ #define BLI_array_declare(arr) \
int _##arr##_count = ((void)(sizeof(*(arr))), 0); \ int _##arr##_count = ((void)(sizeof(*(arr))), 0); \
void *_##arr##_static = NULL void *_##arr##_static = NULL
/* this will use stack space, up to maxstatic array elements, before /**
* this will use stack space, up to maxstatic array elements, before
* switching to dynamic heap allocation */ * switching to dynamic heap allocation */
#define BLI_array_staticdeclare(arr, maxstatic) \ #define BLI_array_staticdeclare(arr, maxstatic) \
int _##arr##_count = 0; \ int _##arr##_count = 0; \
char _##arr##_static[maxstatic * sizeof(*(arr))] char _##arr##_static[maxstatic * sizeof(*(arr))]
/* this returns the logical size of the array, not including buffering. */ /** returns the logical size of the array, not including buffering. */
#define BLI_array_count(arr) ((void)0, _##arr##_count) #define BLI_array_count(arr) ((void)0, _##arr##_count)
/* Grow the array by a fixed number of items. /**
* Grow the array by a fixed number of items.
* *
* Allow for a large 'num' value when the new size is more than double * Allow for a large 'num' value when the new size is more than double
* to allocate the exact sized array. */ * to allocate the exact sized array. */
@@ -101,22 +109,21 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
) )
/* returns length of array */ /** returns length of array */
#define BLI_array_grow_items(arr, num) \ #define BLI_array_grow_items(arr, num) \
(BLI_array_reserve(arr, num), (_##arr##_count += num)) (BLI_array_reserve(arr, num), (_##arr##_count += num))
#define BLI_array_grow_one(arr) \ #define BLI_array_grow_one(arr) \
BLI_array_grow_items(arr, 1) BLI_array_grow_items(arr, 1)
/** appends an item to the array. */
/* appends an item to the array. */
#define BLI_array_append(arr, item) ( \ #define BLI_array_append(arr, item) ( \
(void) BLI_array_grow_one(arr), \ (void) BLI_array_grow_one(arr), \
(void) (arr[_##arr##_count - 1] = item) \ (void) (arr[_##arr##_count - 1] = item) \
) )
/* appends an item to the array and returns a pointer to the item in the array. /**
* appends an item to the array and returns a pointer to the item in the array.
* item is not a pointer, but actual data value.*/ * item is not a pointer, but actual data value.*/
#define BLI_array_append_r(arr, item) ( \ #define BLI_array_append_r(arr, item) ( \
(void) BLI_array_grow_one(arr), \ (void) BLI_array_grow_one(arr), \
@@ -124,7 +131,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
(&arr[_##arr##_count - 1]) \ (&arr[_##arr##_count - 1]) \
) )
/* appends (grows) & returns a pointer to the uninitialized memory */ /** appends (grows) & returns a pointer to the uninitialized memory */
#define BLI_array_append_ret(arr) \ #define BLI_array_append_ret(arr) \
(BLI_array_reserve(arr, 1), &arr[(_##arr##_count++)]) (BLI_array_reserve(arr, 1), &arr[(_##arr##_count++)])
@@ -140,28 +147,37 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
NULL \ NULL \
) )
/* resets the logical size of an array to zero, but doesn't /**
* resets the logical size of an array to zero, but doesn't
* free the memory. */ * free the memory. */
#define BLI_array_empty(arr) \ #define BLI_array_empty(arr) \
{ _##arr##_count = 0; } (void)0 { _##arr##_count = 0; } (void)0
/* set the count of the array, doesn't actually increase the allocated array /**
* set the count of the array, doesn't actually increase the allocated array
* size. don't use this unless you know what you're doing. */ * size. don't use this unless you know what you're doing. */
#define BLI_array_count_set(arr, count) \ #define BLI_array_count_set(arr, count) \
{ _##arr##_count = (count); }(void)0 { _##arr##_count = (count); }(void)0
/* only to prevent unused warnings */ /** only to prevent unused warnings */
#define BLI_array_fake_user(arr) \ #define BLI_array_fake_user(arr) \
((void)_##arr##_count, \ ((void)_##arr##_count, \
(void)_##arr##_static) (void)_##arr##_static)
/** \} */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* other useful defines
* (unrelated to the main array macros) */
/* not part of the 'API' but handy funcs, /** \name Generic Array Utils
* same purpose as BLI_array_staticdeclare() * other useful defines
* (unrelated to the main array macros)
*
* \{ */
/**
* not part of the 'API' but handy funcs,
* same purpose as #BLI_array_staticdeclare()
* but use when the max size is known ahead of time */ * but use when the max size is known ahead of time */
#define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \ #define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \
char _##arr##_static[maxstatic * sizeof(*(arr))]; \ char _##arr##_static[maxstatic * sizeof(*(arr))]; \
@@ -176,17 +192,6 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
MEM_freeN(arr); \ MEM_freeN(arr); \
} (void)0 } (void)0
/** \} */
void _bli_array_reverse(void *arr, unsigned int arr_len, size_t arr_stride);
#define BLI_array_reverse(arr, arr_len) \
_bli_array_reverse(arr, arr_len, sizeof(*(arr)))
void _bli_array_wrap(void *arr, unsigned int arr_len, size_t arr_stride, int dir);
#define BLI_array_wrap(arr, arr_len, dir) \
_bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir)
int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p);
#define BLI_array_findindex(arr, arr_len, p) \
_bli_array_findindex(arr, arr_len, sizeof(*(arr)), p)
#endif /* __BLI_ARRAY_H__ */ #endif /* __BLI_ARRAY_H__ */

View File

@@ -0,0 +1,41 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __BLI_ARRAY_UTILS_H__
#define __BLI_ARRAY_UTILS_H__
/** \file BLI_array_utils.h
* \ingroup bli
* \brief Generic array manipulation API.
*/
void _bli_array_reverse(void *arr, unsigned int arr_len, size_t arr_stride);
#define BLI_array_reverse(arr, arr_len) \
_bli_array_reverse(arr, arr_len, sizeof(*(arr)))
void _bli_array_wrap(void *arr, unsigned int arr_len, size_t arr_stride, int dir);
#define BLI_array_wrap(arr, arr_len, dir) \
_bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir)
int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p);
#define BLI_array_findindex(arr, arr_len, p) \
_bli_array_findindex(arr, arr_len, sizeof(*(arr)), p)
#endif /* __BLI_ARRAY_UTILS_H__ */

View File

@@ -52,6 +52,7 @@ set(SRC
intern/BLI_memarena.c intern/BLI_memarena.c
intern/BLI_mempool.c intern/BLI_mempool.c
intern/DLRB_tree.c intern/DLRB_tree.c
intern/array_utils.c
intern/astar.c intern/astar.c
intern/boxpack2d.c intern/boxpack2d.c
intern/buffer.c intern/buffer.c
@@ -114,6 +115,7 @@ set(SRC
BLI_alloca.h BLI_alloca.h
BLI_args.h BLI_args.h
BLI_array.h BLI_array.h
BLI_array_utils.h
BLI_astar.h BLI_astar.h
BLI_bitmap.h BLI_bitmap.h
BLI_blenlib.h BLI_blenlib.h

View File

@@ -43,6 +43,7 @@
* *
* little array macro library. example of usage: * little array macro library. example of usage:
* *
* \code{.c}
* int *arr = NULL; * int *arr = NULL;
* BLI_array_declare(arr); * BLI_array_declare(arr);
* int i; * int i;
@@ -52,6 +53,7 @@
* arr[i] = something; * arr[i] = something;
* } * }
* BLI_array_free(arr); * BLI_array_free(arr);
* \endcode
* *
* arrays are buffered, using double-buffering (so on each reallocation, * arrays are buffered, using double-buffering (so on each reallocation,
* the array size is doubled). supposedly this should give good Big Oh * the array size is doubled). supposedly this should give good Big Oh
@@ -59,13 +61,10 @@
*/ */
#include <string.h> #include <string.h>
#include <stdlib.h>
#include "BLI_array.h" #include "BLI_array.h"
#include "BLI_sys_types.h" #include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
@@ -100,55 +99,3 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
arr_count += num; arr_count += num;
#endif #endif
} }
void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride)
{
const unsigned int arr_half_stride = (arr_len / 2) * arr_stride;
unsigned int i, i_end;
char *arr = arr_v;
char *buf = BLI_array_alloca(buf, arr_stride);
for (i = 0, i_end = (arr_len - 1) * arr_stride;
i < arr_half_stride;
i += arr_stride, i_end -= arr_stride)
{
memcpy(buf, &arr[i], arr_stride);
memcpy(&arr[i], &arr[i_end], arr_stride);
memcpy(&arr[i_end], buf, arr_stride);
}
}
void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir)
{
char *arr = arr_v;
char *buf = BLI_array_alloca(buf, arr_stride);
if (dir == -1) {
memcpy(buf, arr, arr_stride);
memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1));
memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride);
}
else if (dir == 1) {
memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride);
memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1));
memcpy(arr, buf, arr_stride);
}
else {
BLI_assert(0);
}
}
/**
* \note Not efficient, use for error checks/asserts.
*/
int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p)
{
const char *arr_step = (const char *)arr;
unsigned int i;
for (i = 0; i < arr_len; i++, arr_step += arr_stride) {
if (memcmp(arr_step, p, arr_stride) == 0) {
return (int)i;
}
}
return -1;
}

View File

@@ -0,0 +1,85 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenlib/intern/array_utils.c
* \ingroup bli
* \brief Generic array manipulation API.
*/
#include <string.h>
#include <stdlib.h>
#include "BLI_array_utils.h"
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride)
{
const unsigned int arr_half_stride = (arr_len / 2) * arr_stride;
unsigned int i, i_end;
char *arr = arr_v;
char *buf = BLI_array_alloca(buf, arr_stride);
for (i = 0, i_end = (arr_len - 1) * arr_stride;
i < arr_half_stride;
i += arr_stride, i_end -= arr_stride)
{
memcpy(buf, &arr[i], arr_stride);
memcpy(&arr[i], &arr[i_end], arr_stride);
memcpy(&arr[i_end], buf, arr_stride);
}
}
void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir)
{
char *arr = arr_v;
char *buf = BLI_array_alloca(buf, arr_stride);
if (dir == -1) {
memcpy(buf, arr, arr_stride);
memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1));
memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride);
}
else if (dir == 1) {
memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride);
memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1));
memcpy(arr, buf, arr_stride);
}
else {
BLI_assert(0);
}
}
/**
* \note Not efficient, use for error checks/asserts.
*/
int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p)
{
const char *arr_step = (const char *)arr;
unsigned int i;
for (i = 0; i < arr_len; i++, arr_step += arr_stride) {
if (memcmp(arr_step, p, arr_stride) == 0) {
return (int)i;
}
}
return -1;
}

View File

@@ -45,7 +45,9 @@
#include "BLI_linklist_stack.h" #include "BLI_linklist_stack.h"
#include "BLI_stackdefines.h" #include "BLI_stackdefines.h"
#include "BLI_array.h" #ifndef NDEBUG
# include "BLI_array_utils.h"
#endif
#include "BLI_kdopbvh.h" #include "BLI_kdopbvh.h"

View File

@@ -10,7 +10,7 @@
#define USE_BEAUTIFY #define USE_BEAUTIFY
extern "C" { extern "C" {
#include "BLI_array.h" #include "BLI_array_utils.h"
#include "BLI_polyfill2d.h" #include "BLI_polyfill2d.h"
#include "BLI_math.h" #include "BLI_math.h"
#include "BLI_edgehash.h" #include "BLI_edgehash.h"