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) ( \
((arr) == NULL) ? \
0 : \
@ -53,7 +54,10 @@
_bli_array_totalsize_dynamic(arr)) \
)
/* BLI_array.c
/** \} */
/** BLI_array.c
*
* Doing the realloc in a macro isn't so simple,
* 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) \
int _##arr##_count = ((void)(sizeof(*(arr))), 0); \
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 */
#define BLI_array_staticdeclare(arr, maxstatic) \
int _##arr##_count = 0; \
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)
/* 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
* 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) \
(BLI_array_reserve(arr, num), (_##arr##_count += num))
#define BLI_array_grow_one(arr) \
BLI_array_grow_items(arr, 1)
/* appends an item to the array. */
/** appends an item to the array. */
#define BLI_array_append(arr, item) ( \
(void) BLI_array_grow_one(arr), \
(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.*/
#define BLI_array_append_r(arr, item) ( \
(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]) \
)
/* appends (grows) & returns a pointer to the uninitialized memory */
/** appends (grows) & returns a pointer to the uninitialized memory */
#define BLI_array_append_ret(arr) \
(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 \
)
/* 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. */
#define BLI_array_empty(arr) \
{ _##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. */
#define BLI_array_count_set(arr, count) \
{ _##arr##_count = (count); }(void)0
/* only to prevent unused warnings */
/** only to prevent unused warnings */
#define BLI_array_fake_user(arr) \
((void)_##arr##_count, \
(void)_##arr##_static)
/** \} */
/* -------------------------------------------------------------------- */
/* other useful defines
* (unrelated to the main array macros) */
/* not part of the 'API' but handy funcs,
* same purpose as BLI_array_staticdeclare()
/** \name Generic Array Utils
* 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 */
#define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \
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); \
} (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__ */

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_mempool.c
intern/DLRB_tree.c
intern/array_utils.c
intern/astar.c
intern/boxpack2d.c
intern/buffer.c
@ -114,6 +115,7 @@ set(SRC
BLI_alloca.h
BLI_args.h
BLI_array.h
BLI_array_utils.h
BLI_astar.h
BLI_bitmap.h
BLI_blenlib.h

View File

@ -43,6 +43,7 @@
*
* little array macro library. example of usage:
*
* \code{.c}
* int *arr = NULL;
* BLI_array_declare(arr);
* int i;
@ -52,6 +53,7 @@
* arr[i] = something;
* }
* BLI_array_free(arr);
* \endcode
*
* arrays are buffered, using double-buffering (so on each reallocation,
* the array size is doubled). supposedly this should give good Big Oh
@ -59,13 +61,10 @@
*/
#include <string.h>
#include <stdlib.h>
#include "BLI_array.h"
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "MEM_guardedalloc.h"
@ -100,55 +99,3 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
arr_count += num;
#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_stackdefines.h"
#include "BLI_array.h"
#ifndef NDEBUG
# include "BLI_array_utils.h"
#endif
#include "BLI_kdopbvh.h"

View File

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