📄 gim_memory.h
字号:
#ifndef GIM_MEMORY_H_INCLUDED
#define GIM_MEMORY_H_INCLUDED
/*! \file gim_memory.h
\author Francisco Le髇
*/
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.
For the latest info, see http://gimpact.sourceforge.net/
Copyright (c) 2006 Francisco Leon. C.C. 80087371.
email: projectileman@yahoo.com
This library is free software; you can redistribute it and/or
modify it under the terms of EITHER:
(1) The GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at
your option) any later version. The text of the GNU Lesser
General Public License is included with this library in the
file GIMPACT-LICENSE-LGPL.TXT.
(2) The BSD-style license that is included with this library in
the file GIMPACT-LICENSE-BSD.TXT.
This library 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 files
GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
-----------------------------------------------------------------------------
*/
#include "GIMPACT/gim_math.h"
#include <memory.h>
//#define PREFETCH 1
//! \defgroup PREFETCH
//! @{
#ifdef PREFETCH
#include <xmmintrin.h> // for prefetch
#define pfval 64
#define pfval2 128
//! Prefetch 64
#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
//! Prefetch 128
#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
#else
//! Prefetch 64
#define pf(_x,_i)
//! Prefetch 128
#define pf2(_x,_i)
#endif
//! @}
/*! \defgroup ARRAY_UTILITIES
\brief
Functions for manip packed arrays of numbers
*/
//! @{
#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
{\
GUINT _i_;\
for (_i_=0;_i_<element_count ;_i_++)\
{\
dest_array[_i_] = source_array[_i_];\
}\
}\
#define GIM_COPY_ARRAYS_1(dest_array,source_array,element_count,copy_macro)\
{\
GUINT _i_;\
for (_i_=0;_i_<element_count ;_i_++)\
{\
copy_macro(dest_array[_i_],source_array[_i_]);\
}\
}\
#define GIM_ZERO_ARRAY(array,element_count)\
{\
GUINT _i_;\
for (_i_=0;_i_<element_count ;_i_++)\
{\
array[_i_] = 0;\
}\
}\
#define GIM_CONSTANT_ARRAY(array,element_count,constant)\
{\
GUINT _i_;\
for (_i_=0;_i_<element_count ;_i_++)\
{\
array[_i_] = constant;\
}\
}\
//! @}
/*! \defgroup MEMORY_FUNCTION_PROTOTYPES
Function prototypes to allocate and free memory.
*/
//! @{
typedef void * gim_alloc_function (size_t size);
typedef void * gim_alloca_function (size_t size);//Allocs on the heap
typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
typedef void gim_free_function (void *ptr, size_t size);
//! @}
/*! \defgroup MEMORY_FUNCTION_HANDLERS
\brief
Memory Function Handlers
set new memory management functions. if fn is 0, the default handlers are
used. */
//! @{
void gim_set_alloc_handler (gim_alloc_function *fn);
void gim_set_alloca_handler (gim_alloca_function *fn);
void gim_set_realloc_handler (gim_realloc_function *fn);
void gim_set_free_handler (gim_free_function *fn);
//! @}
/*! \defgroup MEMORY_FUNCTION_GET_HANDLERS
\brief
get current memory management functions.
*/
//! @{
gim_alloc_function *gim_get_alloc_handler (void);
gim_alloca_function *gim_get_alloca_handler(void);
gim_realloc_function *gim_get_realloc_handler (void);
gim_free_function *gim_get_free_handler (void);
//! @}
/*! \defgroup MEMORY_FUNCTIONS
Standar Memory functions
*/
//! @{
void * gim_alloc(size_t size);
void * gim_alloca(size_t size);
void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
void gim_free(void *ptr, size_t size);
//! @}
/*! \defgroup DYNAMIC_ARRAYS
\brief
Dynamic Arrays. Allocated from system memory.
<ul>
<li> For initializes a dynamic array, use GIM_DYNARRAY_CREATE or GIM_DYNARRAY_CREATE_SIZED.
<li> When an array is no longer used, must be terminated with the macro GIM_DYNARRAY_DESTROY.
</ul>
*/
//! @{
#define G_ARRAY_GROW_SIZE 100
//! Dynamic array handle.
struct GDYNAMIC_ARRAY
{
char * m_pdata;
GUINT m_size;
GUINT m_reserve_size;
};
//typedef struct _GDYNAMIC_ARRAY GDYNAMIC_ARRAY;
//! Creates a dynamic array zero sized
#define GIM_DYNARRAY_CREATE(type,array_data,reserve_size) \
{ \
array_data.m_pdata = (char *)gim_alloc(reserve_size*sizeof(type)); \
array_data.m_size = 0; \
array_data.m_reserve_size = reserve_size; \
}\
//! Creates a dynamic array with n = size elements
#define GIM_DYNARRAY_CREATE_SIZED(type,array_data,size) \
{ \
array_data.m_pdata = (char *)gim_alloc(size*sizeof(type)); \
array_data.m_size = size; \
array_data.m_reserve_size = size; \
}\
//! Reserves memory for a dynamic array.
#define GIM_DYNARRAY_RESERVE_SIZE(type,array_data,reserve_size) \
{ \
if(reserve_size>array_data.m_reserve_size )\
{ \
array_data.m_pdata = (char *) gim_realloc(array_data.m_pdata,array_data.m_size*sizeof(type),reserve_size*sizeof(type));\
array_data.m_reserve_size = reserve_size; \
}\
}\
//! Set the size of the array
#define GIM_DYNARRAY_SET_SIZE(type,array_data,size) \
{ \
GIM_DYNARRAY_RESERVE_SIZE(type,array_data,size);\
array_data.m_size = size;\
}\
//! Gets a pointer from the beginning of the array
#define GIM_DYNARRAY_POINTER(type,array_data) (type *)(array_data.m_pdata)
//! Gets a pointer from the last elemento of the array
#define GIM_DYNARRAY_POINTER_LAST(type,array_data) (((type *)array_data.m_pdata)+array_data.m_size-1)
//! Inserts an element at the last position
#define GIM_DYNARRAY_PUSH_ITEM(type,array_data,item)\
{\
if(array_data.m_reserve_size<=array_data.m_size)\
{\
GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
}\
type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
memcpy(&_pt[array_data.m_size],&item,sizeof(type));\
array_data.m_size++; \
}\
//! Inserts an element at the last position
#define GIM_DYNARRAY_PUSH_EMPTY(type,array_data)\
{\
if(array_data.m_reserve_size<=array_data.m_size)\
{\
GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
}\
array_data.m_size++; \
}\
//! Inserts an element
#define GIM_DYNARRAY_INSERT_ITEM(type,array_data,item,index) \
{ \
if(array_data.m_reserve_size<=array_data.m_size)\
{\
GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
}\
type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
if(index<array_data.m_size-1) \
{ \
memcpy(&_pt[index+1],&_pt[index],(array_data.m_size-index)*sizeof(type));\
} \
memcpy(&_pt[index],&item,sizeof(type));\
array_data.m_size++; \
}\
//! Removes an element
#define GIM_DYNARRAY_DELETE_ITEM(type,array_data,index) \
{ \
if(index<array_data.m_size-1) \
{ \
type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
memcpy(&_pt[index],&_pt[index+1],(array_data.m_size-index-1)*sizeof(type));\
} \
array_data.m_size--; \
}\
//! Removes an element at the last position
#define GIM_DYNARRAY_POP_ITEM(array_data) \
{ \
if(array_data.m_size>0) \
{ \
array_data.m_size--; \
} \
}\
//! Destroys the array
void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data);
//! @}
/*! \defgroup BITSET
\brief
Bitsets , based on \ref DYNAMIC_ARRAYS .
<ul>
<li> For initializes a bitset array, use \ref GIM_BITSET_CREATE or \ref GIM_BITSET_CREATE_SIZED.
<li> When the bitset is no longer used, must be terminated with the macro \ref GIM_DYNARRAY_DESTROY.
<li> For putting a mark on the bitset, call \ref GIM_BITSET_SET
<li> For clearing a mark on the bitset, call \ref GIM_BITSET_CLEAR
<li> For retrieving a bit value from a bitset, call \ref GIM_BITSET_GET-
</ul>
*/
//! @{
//! Creates a bitset
#define GIM_BITSET_CREATE(array_data) GIM_DYNARRAY_CREATE(GUINT,array_data,G_ARRAY_GROW_SIZE)
//! Creates a bitset, with their bits set to 0.
#define GIM_BITSET_CREATE_SIZED(array_data,bits_count)\
{\
array_data.m_size = bits_count/GUINT_BIT_COUNT + 1;\
GIM_DYNARRAY_CREATE(GUINT,array_data,array_data.m_size);\
GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
memset(_pt,0,sizeof(GUINT)*(array_data.m_size));\
}\
//! Gets the bitset bit count.
#define GIM_BITSET_SIZE(array_data) (array_data.m_size*GUINT_BIT_COUNT)
//! Resizes a bitset, with their bits set to 0.
#define GIM_BITSET_RESIZE(array_data,new_bits_count)\
{ \
GUINT _oldsize = array_data.m_size;\
array_data.m_size = new_bits_count/GUINT_BIT_COUNT + 1; \
if(_oldsize<array_data.m_size)\
{\
if(array_data.m_size > array_data.m_reserve_size)\
{\
GIM_DYNARRAY_RESERVE_SIZE(GUINT,array_data,array_data.m_size+G_ARRAY_GROW_SIZE);\
}\
GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
memset(&_pt[_oldsize],0,sizeof(GUINT)*(array_data.m_size-_oldsize));\
}\
}\
//! Sets all bitset bit to 0.
#define GIM_BITSET_CLEAR_ALL(array_data)\
{\
memset(array_data.m_pdata,0,sizeof(GUINT)*array_data.m_size);\
}\
//! Sets all bitset bit to 1.
#define GIM_BITSET_SET_ALL(array_data)\
{\
memset(array_data.m_pdata,0xFF,sizeof(GUINT)*array_data.m_size);\
}\
///Sets the desired bit to 1
#define GIM_BITSET_SET(array_data,bit_index)\
{\
if(bit_index>=GIM_BITSET_SIZE(array_data))\
{\
GIM_BITSET_RESIZE(array_data,bit_index);\
}\
GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
_pt[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
}\
///Return 0 or 1
#define GIM_BITSET_GET(array_data,bit_index,get_value) \
{\
if(bit_index>=GIM_BITSET_SIZE(array_data))\
{\
get_value = 0;\
}\
else\
{\
GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
get_value = _pt[bit_index >> GUINT_EXPONENT] & (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
}\
}\
///Sets the desired bit to 0
#define GIM_BITSET_CLEAR(array_data,bit_index) \
{\
if(bit_index<GIM_BITSET_SIZE(array_data))\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -