Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): Joseph Eagar. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00028 /* 00029 * this library needs to be changed to not use macros quite so heavily, 00030 * and to be more of a complete array API. The way arrays are 00031 * exposed to client code as normal C arrays is very useful though, imho. 00032 * it does require some use of macros, however. 00033 * 00034 * anyway, it's used a bit too heavily to simply rewrite as a 00035 * more "correct" solution without macros entirely. I originally wrote this 00036 * to be very easy to use, without the normal pain of most array libraries. 00037 * This was especially helpful when it came to the massive refactors necessary 00038 * for bmesh, and really helped to speed the process up. - joeedh 00039 * 00040 * little array macro library. example of usage: 00041 * 00042 * int *arr = NULL; 00043 * BLI_array_declare(arr); 00044 * int i; 00045 * 00046 * for (i=0; i<10; i++) { 00047 * BLI_array_growone(arr); 00048 * arr[i] = something; 00049 * } 00050 * BLI_array_free(arr); 00051 * 00052 * arrays are buffered, using double-buffering (so on each reallocation, 00053 * the array size is doubled). supposedly this should give good Big Oh 00054 * behaviour, though it may not be the best in practice. 00055 */ 00056 00057 #define BLI_array_declare(arr) \ 00058 int _##arr##_count = 0; \ 00059 void *_##arr##_tmp; \ 00060 void *_##arr##_static = NULL 00061 00062 /* this will use stack space, up to maxstatic array elements, before 00063 * switching to dynamic heap allocation */ 00064 #define BLI_array_staticdeclare(arr, maxstatic) \ 00065 int _##arr##_count = 0; \ 00066 void *_##arr##_tmp; \ 00067 char _##arr##_static[maxstatic*sizeof(arr)] 00068 00069 00070 /* this returns the entire size of the array, including any buffering. */ 00071 #define BLI_array_totalsize_dyn(arr) ( \ 00072 ((arr)==NULL) ? \ 00073 0 : \ 00074 MEM_allocN_len(arr) / sizeof(*arr) \ 00075 ) 00076 00077 00078 #define BLI_array_totalsize(arr) ( \ 00079 (size_t) \ 00080 (((void *)(arr) == (void *)_##arr##_static && (void *)(arr) != NULL) ? \ 00081 (sizeof(_##arr##_static) / sizeof(*arr)) : \ 00082 BLI_array_totalsize_dyn(arr)) \ 00083 ) 00084 00085 00086 /* this returns the logical size of the array, not including buffering. */ 00087 #define BLI_array_count(arr) _##arr##_count 00088 00089 /* Grow the array by a fixed number of items. zeroes the new elements. 00090 * 00091 * Allow for a large 'num' value when the new size is more then double 00092 * to allocate the exact sized array. */ 00093 #define _bli_array_grow_items(arr, num) ( \ 00094 (BLI_array_totalsize(arr) >= _##arr##_count + num) ? \ 00095 (_##arr##_count += num) : \ 00096 ( \ 00097 (void) (_##arr##_tmp = MEM_callocN( \ 00098 sizeof(*arr) * (num < _##arr##_count ? \ 00099 (_##arr##_count * 2 + 2) : \ 00100 (_##arr##_count + num)), \ 00101 #arr " " __FILE__ ":" STRINGIFY(__LINE__) \ 00102 ) \ 00103 ), \ 00104 (void) (arr && memcpy(_##arr##_tmp, \ 00105 arr, \ 00106 sizeof(*arr) * _##arr##_count) \ 00107 ), \ 00108 (void) (arr && ((void *)(arr) != (void*)_##arr##_static ? \ 00109 (MEM_freeN(arr), arr) : \ 00110 arr) \ 00111 ), \ 00112 (void) (arr = _##arr##_tmp \ 00113 ), \ 00114 (_##arr##_count += num) \ 00115 ) \ 00116 ) 00117 00118 /* grow an array by a specified number of items */ 00119 #define BLI_array_growitems(arr, num) ( \ 00120 ((void *)(arr)==NULL && (void *)(_##arr##_static) != NULL) ? \ 00121 ((arr= (void*)_##arr##_static), (_##arr##_count += num)) : \ 00122 _bli_array_grow_items(arr, num) \ 00123 ) 00124 00125 /* returns length of array */ 00126 #define BLI_array_growone(arr) BLI_array_growitems(arr, 1) 00127 00128 00129 /* appends an item to the array. */ 00130 #define BLI_array_append(arr, item) ( \ 00131 (void) BLI_array_growone(arr), \ 00132 (void) (arr[_##arr##_count - 1] = item) \ 00133 ) 00134 00135 /* appends an item to the array and returns a pointer to the item in the array. 00136 * item is not a pointer, but actual data value.*/ 00137 #define BLI_array_append_r(arr, item) ( \ 00138 (void) BLI_array_growone(arr), \ 00139 (void) (arr[_##arr##_count - 1] = item), \ 00140 (&arr[_##arr##_count - 1]) \ 00141 ) 00142 00143 #define BLI_array_free(arr) \ 00144 if (arr && (char *)arr != _##arr##_static) { \ 00145 BLI_array_fake_user(arr); \ 00146 MEM_freeN(arr); \ 00147 } 00148 00149 #define BLI_array_pop(arr) ( \ 00150 (arr&&_##arr##_count) ? \ 00151 arr[--_##arr##_count] : \ 00152 0 \ 00153 ) 00154 00155 /* resets the logical size of an array to zero, but doesn't 00156 * free the memory. */ 00157 #define BLI_array_empty(arr) \ 00158 _##arr##_count=0 00159 00160 /* set the count of the array, doesn't actually increase the allocated array 00161 * size. don't use this unless you know what you're doing. */ 00162 #define BLI_array_set_length(arr, count) \ 00163 _##arr##_count = (count) 00164 00165 /* only to prevent unused warnings */ 00166 #define BLI_array_fake_user(arr) \ 00167 (void)_##arr##_count, \ 00168 (void)_##arr##_tmp, \ 00169 (void)_##arr##_static 00170 00171 00172 /* not part of the 'API' but handy funcs, 00173 * same purpose as BLI_array_staticdeclare() 00174 * but use when the max size is known ahead of time */ 00175 #define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \ 00176 char _##arr##_static[maxstatic*sizeof(*arr)]; \ 00177 const int _##arr##_is_static= ((void *)_##arr##_static) != ( \ 00178 arr= (realsize <= maxstatic) ? \ 00179 (void *)_##arr##_static : \ 00180 MEM_mallocN(sizeof(*arr)*realsize, allocstr) \ 00181 ) \ 00182 00183 #define BLI_array_fixedstack_free(arr) \ 00184 if (_##arr##_is_static) MEM_freeN(arr) \ 00185