1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 4103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* Copyright (C) 1997-2012, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File CMEMORY.H 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Contains stdlib.h/string.h memory functions 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @author Bertrand A. Damiba 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 6/20/98 Bertrand Created. 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/03/99 stephen Changed from functions to macros. 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef CMEMORY_H 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CMEMORY_H 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "unicode/utypes.h" 2854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 29b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include <stddef.h> 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h> 3127f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/localpointer.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 33103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_DEBUG && defined(UPRV_MALLOC_COUNT) 34103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include <stdio.h> 35103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif 36103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 3754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_DEBUG 3854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 3954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius/* 4054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * The C++ standard requires that the source pointer for memcpy() & memmove() 4154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * is valid, not NULL, and not at the end of an allocated memory block. 4254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * In debug mode, we read one byte from the source point to verify that it's 4354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * a valid, readable pointer. 4454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius */ 4554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 4654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI void uprv_checkValidMemory(const void *p, size_t n); 4754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 4854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define uprv_memcpy(dst, src, size) ( \ 4954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius uprv_checkValidMemory(src, 1), \ 5054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size)) 5154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define uprv_memmove(dst, src, size) ( \ 5254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius uprv_checkValidMemory(src, 1), \ 5354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_STANDARD_CPP_NAMESPACE memmove(dst, src, size)) 5454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 5554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#else 5654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define uprv_memcpy(dst, src, size) U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size) 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define uprv_memmove(dst, src, size) U_STANDARD_CPP_NAMESPACE memmove(dst, src, size) 5954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 6054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif /* U_DEBUG */ 6154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define uprv_memset(buffer, mark, size) U_STANDARD_CPP_NAMESPACE memset(buffer, mark, size) 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define uprv_memcmp(buffer1, buffer2, size) U_STANDARD_CPP_NAMESPACE memcmp(buffer1, buffer2,size) 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void * U_EXPORT2 6654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusuprv_malloc(size_t s) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR(1); 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void * U_EXPORT2 6954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusuprv_realloc(void *mem, size_t size) U_ALLOC_SIZE_ATTR(2); 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_free(void *mem); 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 74103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI void * U_EXPORT2 7554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusuprv_calloc(size_t num, size_t size) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR2(1,2); 76103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This should align the memory properly on any machine. 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is very useful for the safeClone functions. 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef union { 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru long t1; 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double t2; 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru void *t3; 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} UAlignedMemory; 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 88b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Get the least significant bits of a pointer (a memory address). 89b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * For example, with a mask of 3, the macro gets the 2 least significant bits, 90b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * which will be 0 if the pointer is 32-bit (4-byte) aligned. 91b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 92b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * ptrdiff_t is the most appropriate integer type to cast to. 93b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * size_t should work too, since on most (or all?) platforms it has the same 94b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * width as ptrdiff_t. 95b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 96b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define U_POINTER_MASK_LSB(ptr, mask) (((ptrdiff_t)(char *)(ptr)) & (mask)) 97b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 98b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/** 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Get the amount of bytes that a pointer is off by from 100b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * the previous UAlignedMemory-aligned pointer. 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 102b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define U_ALIGNMENT_OFFSET(ptr) U_POINTER_MASK_LSB(ptr, sizeof(UAlignedMemory) - 1) 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Get the amount of bytes to add to a pointer 106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * in order to get the next UAlignedMemory-aligned address. 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr)) 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Indicate whether the ICU allocation functions have been used. 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is used to determine whether ICU is in an initial, unused state. 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC UBool 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querucmemory_inUse(void); 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Heap clean up function, called from u_cleanup() 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Clears any user heap functions from u_setMemoryFunctions() 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Does NOT deallocate any remaining allocated memory. 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC UBool 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querucmemory_cleanup(void); 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/** 126103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * A function called by <TT>uhash_remove</TT>, 127103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * <TT>uhash_close</TT>, or <TT>uhash_put</TT> to delete 128103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * an existing key or value. 129103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * @param obj A key or value stored in a hashtable 130103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * @see uprv_deleteUObject 131103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius */ 132103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliustypedef void U_CALLCONV UObjectDeleter(void* obj); 133103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 134103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/** 135103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Deleter for UObject instances. 136103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Works for all subclasses of UObject because it has a virtual destructor. 137103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius */ 138103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI void U_EXPORT2 139103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuprv_deleteUObject(void *obj); 140103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 141103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef __cplusplus 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 14350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN 14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" class, deletes memory via uprv_free(). 14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For most methods see the LocalPointerBase base class. 14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Adds operator[] for array item access. 14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointerBase 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T> 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass LocalMemory : public LocalPointerBase<T> { 15450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Constructor takes ownership. 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an array of T items that is adopted 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho explicit LocalMemory(T *p=NULL) : LocalPointerBase<T>(p) {} 16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Destructor deletes the memory it owns. 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ~LocalMemory() { 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(LocalPointerBase<T>::ptr); 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the array it owns, 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and adopts (takes ownership of) the one passed in. 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param p simple pointer to an array of T items that is adopted 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void adoptInstead(T *p) { 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(LocalPointerBase<T>::ptr); 17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalPointerBase<T>::ptr=p; 17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the array it owns, allocates a new one and reset its bytes to 0. 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Returns the new array pointer. 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If the allocation fails, then the current array is unchanged and 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * this method returns NULL. 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param newCapacity must be >0 18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the allocated array pointer, or NULL if the allocation failed 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho inline T *allocateInsteadAndReset(int32_t newCapacity=1); 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the array it owns and allocates a new one, copying length T items. 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Returns the new array pointer. 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If the allocation fails, then the current array is unchanged and 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * this method returns NULL. 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param newCapacity must be >0 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param length number of T items to be copied from the old array to the new one; 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * must be no more than the capacity of the old array, 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * which the caller must track because the LocalMemory does not track it 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the allocated array pointer, or NULL if the allocation failed 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho inline T *allocateInsteadAndCopy(int32_t newCapacity=1, int32_t length=0); 19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Array item access (writable). 19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * No index bounds check. 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param i array index 20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return reference to the array item 20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; } 20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 20527f654740f2a26ad62a5c155af9199af9e69b889clairehotemplate<typename T> 20627f654740f2a26ad62a5c155af9199af9e69b889clairehoinline T *LocalMemory<T>::allocateInsteadAndReset(int32_t newCapacity) { 20727f654740f2a26ad62a5c155af9199af9e69b889claireho if(newCapacity>0) { 20827f654740f2a26ad62a5c155af9199af9e69b889claireho T *p=(T *)uprv_malloc(newCapacity*sizeof(T)); 20927f654740f2a26ad62a5c155af9199af9e69b889claireho if(p!=NULL) { 21027f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_memset(p, 0, newCapacity*sizeof(T)); 21127f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(LocalPointerBase<T>::ptr); 21227f654740f2a26ad62a5c155af9199af9e69b889claireho LocalPointerBase<T>::ptr=p; 21327f654740f2a26ad62a5c155af9199af9e69b889claireho } 21427f654740f2a26ad62a5c155af9199af9e69b889claireho return p; 21527f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 21627f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 21727f654740f2a26ad62a5c155af9199af9e69b889claireho } 21827f654740f2a26ad62a5c155af9199af9e69b889claireho} 21927f654740f2a26ad62a5c155af9199af9e69b889claireho 22027f654740f2a26ad62a5c155af9199af9e69b889claireho 22127f654740f2a26ad62a5c155af9199af9e69b889clairehotemplate<typename T> 22227f654740f2a26ad62a5c155af9199af9e69b889clairehoinline T *LocalMemory<T>::allocateInsteadAndCopy(int32_t newCapacity, int32_t length) { 22327f654740f2a26ad62a5c155af9199af9e69b889claireho if(newCapacity>0) { 22427f654740f2a26ad62a5c155af9199af9e69b889claireho T *p=(T *)uprv_malloc(newCapacity*sizeof(T)); 22527f654740f2a26ad62a5c155af9199af9e69b889claireho if(p!=NULL) { 22627f654740f2a26ad62a5c155af9199af9e69b889claireho if(length>0) { 22727f654740f2a26ad62a5c155af9199af9e69b889claireho if(length>newCapacity) { 22827f654740f2a26ad62a5c155af9199af9e69b889claireho length=newCapacity; 22927f654740f2a26ad62a5c155af9199af9e69b889claireho } 23027f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_memcpy(p, LocalPointerBase<T>::ptr, length*sizeof(T)); 23127f654740f2a26ad62a5c155af9199af9e69b889claireho } 23227f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(LocalPointerBase<T>::ptr); 23327f654740f2a26ad62a5c155af9199af9e69b889claireho LocalPointerBase<T>::ptr=p; 23427f654740f2a26ad62a5c155af9199af9e69b889claireho } 23527f654740f2a26ad62a5c155af9199af9e69b889claireho return p; 23627f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 23727f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 23827f654740f2a26ad62a5c155af9199af9e69b889claireho } 23927f654740f2a26ad62a5c155af9199af9e69b889claireho} 24027f654740f2a26ad62a5c155af9199af9e69b889claireho 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Simple array/buffer management class using uprv_malloc() and uprv_free(). 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Provides an internal array with fixed capacity. Can alias another array 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * or allocate one. 24527f654740f2a26ad62a5c155af9199af9e69b889claireho * 24627f654740f2a26ad62a5c155af9199af9e69b889claireho * The array address is properly aligned for type T. It might not be properly 24727f654740f2a26ad62a5c155af9199af9e69b889claireho * aligned for types larger than T (or larger than the largest subtype of T). 24827f654740f2a26ad62a5c155af9199af9e69b889claireho * 24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Unlike LocalMemory and LocalArray, this class never adopts 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * (takes ownership of) another array. 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T, int32_t stackCapacity> 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass MaybeStackArray { 25450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Default constructor initializes with internal T[stackCapacity] buffer. 25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 25827f654740f2a26ad62a5c155af9199af9e69b889claireho MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(FALSE) {} 25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Destructor deletes the array (if owned). 26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ~MaybeStackArray() { releaseArray(); } 26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Returns the array capacity (number of T items). 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return array capacity 26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t getCapacity() const { return capacity; } 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Access without ownership change. 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the array pointer 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *getAlias() const { return ptr; } 27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Returns the array limit. Simple convenience method. 27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return getAlias()+getCapacity() 27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *getArrayLimit() const { return getAlias()+capacity; } 27854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // No "operator T *() const" because that can make 27954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // expressions like mbs[index] ambiguous for some compilers. 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 28154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * Array item access (const). 28254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * No index bounds check. 28354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * @param i array index 28454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * @return reference to the array item 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 28654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const T &operator[](ptrdiff_t i) const { return ptr[i]; } 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Array item access (writable). 28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * No index bounds check. 29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param i array index 29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return reference to the array item 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T &operator[](ptrdiff_t i) { return ptr[i]; } 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the array (if owned) and aliases another one, no transfer of ownership. 29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If the arguments are illegal, then the current array is unchanged. 29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param otherArray must not be NULL 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param otherCapacity must be >0 29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void aliasInstead(T *otherArray, int32_t otherCapacity) { 30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(otherArray!=NULL && otherCapacity>0) { 30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho releaseArray(); 30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ptr=otherArray; 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho capacity=otherCapacity; 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho needToRelease=FALSE; 30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Deletes the array (if owned) and allocates a new one, copying length T items. 31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Returns the new array pointer. 31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If the allocation fails, then the current array is unchanged and 31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * this method returns NULL. 31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param newCapacity can be less than or greater than the current capacity; 31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * must be >0 31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param length number of T items to be copied from the old array to the new one 31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the allocated array pointer, or NULL if the allocation failed 31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho inline T *resize(int32_t newCapacity, int32_t length=0); 31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /** 32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Gives up ownership of the array if owned, or else clones it, 32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * copying length T items; resets itself to the internal stack array. 32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Returns NULL if the allocation failed. 32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param length number of T items to copy when cloning, 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and capacity of the clone when cloning 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param resultCapacity will be set to the returned array's capacity (output-only) 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return the array pointer; 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * caller becomes responsible for deleting the array 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho inline T *orphanOrClone(int32_t length, int32_t &resultCapacity); 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprivate: 33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *ptr; 33227f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t capacity; 33327f654740f2a26ad62a5c155af9199af9e69b889claireho UBool needToRelease; 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T stackArray[stackCapacity]; 33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void releaseArray() { 33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(needToRelease) { 33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(ptr); 33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* No comparison operators with other MaybeStackArray's. */ 341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bool operator==(const MaybeStackArray & /*other*/) {return FALSE;} 342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;} 34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* No ownership transfer: No copy constructor, no assignment operator. */ 344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MaybeStackArray(const MaybeStackArray & /*other*/) {} 345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void operator=(const MaybeStackArray & /*other*/) {} 34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No heap allocation. Use only on the stack. 34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // (Declaring these functions private triggers a cascade of problems: 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // MSVC insists on exporting an instantiation of MaybeStackArray, which 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // requires that all functions be defined. 35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // An empty implementation of new() is rejected, it must return a value. 35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Returning NULL is rejected by gcc for operator new. 35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The expedient thing is just not to override operator new. 35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // While relatively pointless, heap allocated instances will function. 35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // static void * U_EXPORT2 operator new(size_t size); 35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // static void * U_EXPORT2 operator new[](size_t size); 35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_HAVE_PLACEMENT_NEW 35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // static void * U_EXPORT2 operator new(size_t, void *ptr); 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 36250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T, int32_t stackCapacity> 36350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoinline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) { 36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(newCapacity>0) { 365103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_DEBUG && defined(UPRV_MALLOC_COUNT) 366103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ::fprintf(::stderr,"MaybeStacArray (resize) alloc %d * %lu\n", newCapacity,sizeof(T)); 367103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif 36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *p=(T *)uprv_malloc(newCapacity*sizeof(T)); 36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(p!=NULL) { 37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length>0) { 37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length>capacity) { 37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=capacity; 37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length>newCapacity) { 37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=newCapacity; 37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(p, ptr, length*sizeof(T)); 37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho releaseArray(); 38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ptr=p; 38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho capacity=newCapacity; 38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho needToRelease=TRUE; 38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 39050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T, int32_t stackCapacity> 39150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoinline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32_t &resultCapacity) { 39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho T *p; 39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(needToRelease) { 39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=ptr; 39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(length<=0) { 39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length>capacity) { 39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=capacity; 40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(T *)uprv_malloc(length*sizeof(T)); 402103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_DEBUG && defined(UPRV_MALLOC_COUNT) 403103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ::fprintf(::stderr,"MaybeStacArray (orphan) alloc %d * %lu\n", length,sizeof(T)); 404103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif 40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(p==NULL) { 40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(p, ptr, length*sizeof(T)); 40950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resultCapacity=length; 41150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ptr=stackArray; 41250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho capacity=stackCapacity; 41350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho needToRelease=FALSE; 41450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 41550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 41727f654740f2a26ad62a5c155af9199af9e69b889claireho/** 41827f654740f2a26ad62a5c155af9199af9e69b889claireho * Variant of MaybeStackArray that allocates a header struct and an array 41927f654740f2a26ad62a5c155af9199af9e69b889claireho * in one contiguous memory block, using uprv_malloc() and uprv_free(). 42027f654740f2a26ad62a5c155af9199af9e69b889claireho * Provides internal memory with fixed array capacity. Can alias another memory 42127f654740f2a26ad62a5c155af9199af9e69b889claireho * block or allocate one. 42227f654740f2a26ad62a5c155af9199af9e69b889claireho * The stackCapacity is the number of T items in the internal memory, 42327f654740f2a26ad62a5c155af9199af9e69b889claireho * not counting the H header. 42427f654740f2a26ad62a5c155af9199af9e69b889claireho * Unlike LocalMemory and LocalArray, this class never adopts 42527f654740f2a26ad62a5c155af9199af9e69b889claireho * (takes ownership of) another memory block. 42627f654740f2a26ad62a5c155af9199af9e69b889claireho */ 42727f654740f2a26ad62a5c155af9199af9e69b889clairehotemplate<typename H, typename T, int32_t stackCapacity> 42827f654740f2a26ad62a5c155af9199af9e69b889clairehoclass MaybeStackHeaderAndArray { 42927f654740f2a26ad62a5c155af9199af9e69b889clairehopublic: 43027f654740f2a26ad62a5c155af9199af9e69b889claireho /** 43127f654740f2a26ad62a5c155af9199af9e69b889claireho * Default constructor initializes with internal H+T[stackCapacity] buffer. 43227f654740f2a26ad62a5c155af9199af9e69b889claireho */ 43327f654740f2a26ad62a5c155af9199af9e69b889claireho MaybeStackHeaderAndArray() : ptr(&stackHeader), capacity(stackCapacity), needToRelease(FALSE) {} 43427f654740f2a26ad62a5c155af9199af9e69b889claireho /** 43527f654740f2a26ad62a5c155af9199af9e69b889claireho * Destructor deletes the memory (if owned). 43627f654740f2a26ad62a5c155af9199af9e69b889claireho */ 43727f654740f2a26ad62a5c155af9199af9e69b889claireho ~MaybeStackHeaderAndArray() { releaseMemory(); } 43827f654740f2a26ad62a5c155af9199af9e69b889claireho /** 43927f654740f2a26ad62a5c155af9199af9e69b889claireho * Returns the array capacity (number of T items). 44027f654740f2a26ad62a5c155af9199af9e69b889claireho * @return array capacity 44127f654740f2a26ad62a5c155af9199af9e69b889claireho */ 44227f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t getCapacity() const { return capacity; } 44327f654740f2a26ad62a5c155af9199af9e69b889claireho /** 44427f654740f2a26ad62a5c155af9199af9e69b889claireho * Access without ownership change. 44527f654740f2a26ad62a5c155af9199af9e69b889claireho * @return the header pointer 44627f654740f2a26ad62a5c155af9199af9e69b889claireho */ 44727f654740f2a26ad62a5c155af9199af9e69b889claireho H *getAlias() const { return ptr; } 44827f654740f2a26ad62a5c155af9199af9e69b889claireho /** 44927f654740f2a26ad62a5c155af9199af9e69b889claireho * Returns the array start. 45027f654740f2a26ad62a5c155af9199af9e69b889claireho * @return array start, same address as getAlias()+1 45127f654740f2a26ad62a5c155af9199af9e69b889claireho */ 45227f654740f2a26ad62a5c155af9199af9e69b889claireho T *getArrayStart() const { return reinterpret_cast<T *>(getAlias()+1); } 45327f654740f2a26ad62a5c155af9199af9e69b889claireho /** 45427f654740f2a26ad62a5c155af9199af9e69b889claireho * Returns the array limit. 45527f654740f2a26ad62a5c155af9199af9e69b889claireho * @return array limit 45627f654740f2a26ad62a5c155af9199af9e69b889claireho */ 45727f654740f2a26ad62a5c155af9199af9e69b889claireho T *getArrayLimit() const { return getArrayStart()+capacity; } 45827f654740f2a26ad62a5c155af9199af9e69b889claireho /** 45927f654740f2a26ad62a5c155af9199af9e69b889claireho * Access without ownership change. Same as getAlias(). 46027f654740f2a26ad62a5c155af9199af9e69b889claireho * A class instance can be used directly in expressions that take a T *. 46127f654740f2a26ad62a5c155af9199af9e69b889claireho * @return the header pointer 46227f654740f2a26ad62a5c155af9199af9e69b889claireho */ 46327f654740f2a26ad62a5c155af9199af9e69b889claireho operator H *() const { return ptr; } 46427f654740f2a26ad62a5c155af9199af9e69b889claireho /** 46527f654740f2a26ad62a5c155af9199af9e69b889claireho * Array item access (writable). 46627f654740f2a26ad62a5c155af9199af9e69b889claireho * No index bounds check. 46727f654740f2a26ad62a5c155af9199af9e69b889claireho * @param i array index 46827f654740f2a26ad62a5c155af9199af9e69b889claireho * @return reference to the array item 46927f654740f2a26ad62a5c155af9199af9e69b889claireho */ 47027f654740f2a26ad62a5c155af9199af9e69b889claireho T &operator[](ptrdiff_t i) { return getArrayStart()[i]; } 47127f654740f2a26ad62a5c155af9199af9e69b889claireho /** 47227f654740f2a26ad62a5c155af9199af9e69b889claireho * Deletes the memory block (if owned) and aliases another one, no transfer of ownership. 47327f654740f2a26ad62a5c155af9199af9e69b889claireho * If the arguments are illegal, then the current memory is unchanged. 47427f654740f2a26ad62a5c155af9199af9e69b889claireho * @param otherArray must not be NULL 47527f654740f2a26ad62a5c155af9199af9e69b889claireho * @param otherCapacity must be >0 47627f654740f2a26ad62a5c155af9199af9e69b889claireho */ 47727f654740f2a26ad62a5c155af9199af9e69b889claireho void aliasInstead(H *otherMemory, int32_t otherCapacity) { 47827f654740f2a26ad62a5c155af9199af9e69b889claireho if(otherMemory!=NULL && otherCapacity>0) { 47927f654740f2a26ad62a5c155af9199af9e69b889claireho releaseMemory(); 48027f654740f2a26ad62a5c155af9199af9e69b889claireho ptr=otherMemory; 48127f654740f2a26ad62a5c155af9199af9e69b889claireho capacity=otherCapacity; 48227f654740f2a26ad62a5c155af9199af9e69b889claireho needToRelease=FALSE; 48327f654740f2a26ad62a5c155af9199af9e69b889claireho } 484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 48527f654740f2a26ad62a5c155af9199af9e69b889claireho /** 48627f654740f2a26ad62a5c155af9199af9e69b889claireho * Deletes the memory block (if owned) and allocates a new one, 48727f654740f2a26ad62a5c155af9199af9e69b889claireho * copying the header and length T array items. 48827f654740f2a26ad62a5c155af9199af9e69b889claireho * Returns the new header pointer. 48927f654740f2a26ad62a5c155af9199af9e69b889claireho * If the allocation fails, then the current memory is unchanged and 49027f654740f2a26ad62a5c155af9199af9e69b889claireho * this method returns NULL. 49127f654740f2a26ad62a5c155af9199af9e69b889claireho * @param newCapacity can be less than or greater than the current capacity; 49227f654740f2a26ad62a5c155af9199af9e69b889claireho * must be >0 49327f654740f2a26ad62a5c155af9199af9e69b889claireho * @param length number of T items to be copied from the old array to the new one 49427f654740f2a26ad62a5c155af9199af9e69b889claireho * @return the allocated pointer, or NULL if the allocation failed 49527f654740f2a26ad62a5c155af9199af9e69b889claireho */ 49627f654740f2a26ad62a5c155af9199af9e69b889claireho inline H *resize(int32_t newCapacity, int32_t length=0); 49727f654740f2a26ad62a5c155af9199af9e69b889claireho /** 49827f654740f2a26ad62a5c155af9199af9e69b889claireho * Gives up ownership of the memory if owned, or else clones it, 49927f654740f2a26ad62a5c155af9199af9e69b889claireho * copying the header and length T array items; resets itself to the internal memory. 50027f654740f2a26ad62a5c155af9199af9e69b889claireho * Returns NULL if the allocation failed. 50127f654740f2a26ad62a5c155af9199af9e69b889claireho * @param length number of T items to copy when cloning, 50227f654740f2a26ad62a5c155af9199af9e69b889claireho * and array capacity of the clone when cloning 50327f654740f2a26ad62a5c155af9199af9e69b889claireho * @param resultCapacity will be set to the returned array's capacity (output-only) 50427f654740f2a26ad62a5c155af9199af9e69b889claireho * @return the header pointer; 50527f654740f2a26ad62a5c155af9199af9e69b889claireho * caller becomes responsible for deleting the array 50627f654740f2a26ad62a5c155af9199af9e69b889claireho */ 50727f654740f2a26ad62a5c155af9199af9e69b889claireho inline H *orphanOrClone(int32_t length, int32_t &resultCapacity); 50827f654740f2a26ad62a5c155af9199af9e69b889clairehoprivate: 50927f654740f2a26ad62a5c155af9199af9e69b889claireho H *ptr; 51027f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t capacity; 51127f654740f2a26ad62a5c155af9199af9e69b889claireho UBool needToRelease; 51227f654740f2a26ad62a5c155af9199af9e69b889claireho // stackHeader must precede stackArray immediately. 51327f654740f2a26ad62a5c155af9199af9e69b889claireho H stackHeader; 51427f654740f2a26ad62a5c155af9199af9e69b889claireho T stackArray[stackCapacity]; 51527f654740f2a26ad62a5c155af9199af9e69b889claireho void releaseMemory() { 51627f654740f2a26ad62a5c155af9199af9e69b889claireho if(needToRelease) { 51727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(ptr); 51827f654740f2a26ad62a5c155af9199af9e69b889claireho } 51927f654740f2a26ad62a5c155af9199af9e69b889claireho } 52027f654740f2a26ad62a5c155af9199af9e69b889claireho /* No comparison operators with other MaybeStackHeaderAndArray's. */ 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bool operator==(const MaybeStackHeaderAndArray & /*other*/) {return FALSE;} 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bool operator!=(const MaybeStackHeaderAndArray & /*other*/) {return TRUE;} 52327f654740f2a26ad62a5c155af9199af9e69b889claireho /* No ownership transfer: No copy constructor, no assignment operator. */ 524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MaybeStackHeaderAndArray(const MaybeStackHeaderAndArray & /*other*/) {} 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void operator=(const MaybeStackHeaderAndArray & /*other*/) {} 52627f654740f2a26ad62a5c155af9199af9e69b889claireho 52727f654740f2a26ad62a5c155af9199af9e69b889claireho // No heap allocation. Use only on the stack. 52827f654740f2a26ad62a5c155af9199af9e69b889claireho // (Declaring these functions private triggers a cascade of problems; 52927f654740f2a26ad62a5c155af9199af9e69b889claireho // see the MaybeStackArray class for details.) 53027f654740f2a26ad62a5c155af9199af9e69b889claireho // static void * U_EXPORT2 operator new(size_t size); 53127f654740f2a26ad62a5c155af9199af9e69b889claireho // static void * U_EXPORT2 operator new[](size_t size); 53227f654740f2a26ad62a5c155af9199af9e69b889claireho#if U_HAVE_PLACEMENT_NEW 53327f654740f2a26ad62a5c155af9199af9e69b889claireho // static void * U_EXPORT2 operator new(size_t, void *ptr); 53427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 53527f654740f2a26ad62a5c155af9199af9e69b889claireho}; 53627f654740f2a26ad62a5c155af9199af9e69b889claireho 53727f654740f2a26ad62a5c155af9199af9e69b889clairehotemplate<typename H, typename T, int32_t stackCapacity> 53827f654740f2a26ad62a5c155af9199af9e69b889clairehoinline H *MaybeStackHeaderAndArray<H, T, stackCapacity>::resize(int32_t newCapacity, 53927f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t length) { 54027f654740f2a26ad62a5c155af9199af9e69b889claireho if(newCapacity>=0) { 541103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_DEBUG && defined(UPRV_MALLOC_COUNT) 542103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ::fprintf(::stderr,"MaybeStackHeaderAndArray alloc %d + %d * %ul\n", sizeof(H),newCapacity,sizeof(T)); 543103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif 54427f654740f2a26ad62a5c155af9199af9e69b889claireho H *p=(H *)uprv_malloc(sizeof(H)+newCapacity*sizeof(T)); 54527f654740f2a26ad62a5c155af9199af9e69b889claireho if(p!=NULL) { 54627f654740f2a26ad62a5c155af9199af9e69b889claireho if(length<0) { 54727f654740f2a26ad62a5c155af9199af9e69b889claireho length=0; 54827f654740f2a26ad62a5c155af9199af9e69b889claireho } else if(length>0) { 54927f654740f2a26ad62a5c155af9199af9e69b889claireho if(length>capacity) { 55027f654740f2a26ad62a5c155af9199af9e69b889claireho length=capacity; 55127f654740f2a26ad62a5c155af9199af9e69b889claireho } 55227f654740f2a26ad62a5c155af9199af9e69b889claireho if(length>newCapacity) { 55327f654740f2a26ad62a5c155af9199af9e69b889claireho length=newCapacity; 55427f654740f2a26ad62a5c155af9199af9e69b889claireho } 55527f654740f2a26ad62a5c155af9199af9e69b889claireho } 55627f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_memcpy(p, ptr, sizeof(H)+length*sizeof(T)); 55727f654740f2a26ad62a5c155af9199af9e69b889claireho releaseMemory(); 55827f654740f2a26ad62a5c155af9199af9e69b889claireho ptr=p; 55927f654740f2a26ad62a5c155af9199af9e69b889claireho capacity=newCapacity; 56027f654740f2a26ad62a5c155af9199af9e69b889claireho needToRelease=TRUE; 56127f654740f2a26ad62a5c155af9199af9e69b889claireho } 56227f654740f2a26ad62a5c155af9199af9e69b889claireho return p; 56327f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 56427f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 56527f654740f2a26ad62a5c155af9199af9e69b889claireho } 56627f654740f2a26ad62a5c155af9199af9e69b889claireho} 56727f654740f2a26ad62a5c155af9199af9e69b889claireho 56827f654740f2a26ad62a5c155af9199af9e69b889clairehotemplate<typename H, typename T, int32_t stackCapacity> 56927f654740f2a26ad62a5c155af9199af9e69b889clairehoinline H *MaybeStackHeaderAndArray<H, T, stackCapacity>::orphanOrClone(int32_t length, 57027f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t &resultCapacity) { 57127f654740f2a26ad62a5c155af9199af9e69b889claireho H *p; 57227f654740f2a26ad62a5c155af9199af9e69b889claireho if(needToRelease) { 57327f654740f2a26ad62a5c155af9199af9e69b889claireho p=ptr; 57427f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 57527f654740f2a26ad62a5c155af9199af9e69b889claireho if(length<0) { 57627f654740f2a26ad62a5c155af9199af9e69b889claireho length=0; 57727f654740f2a26ad62a5c155af9199af9e69b889claireho } else if(length>capacity) { 57827f654740f2a26ad62a5c155af9199af9e69b889claireho length=capacity; 57927f654740f2a26ad62a5c155af9199af9e69b889claireho } 580103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_DEBUG && defined(UPRV_MALLOC_COUNT) 581103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ::fprintf(::stderr,"MaybeStackHeaderAndArray (orphan) alloc %ul + %d * %lu\n", sizeof(H),length,sizeof(T)); 582103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif 58327f654740f2a26ad62a5c155af9199af9e69b889claireho p=(H *)uprv_malloc(sizeof(H)+length*sizeof(T)); 58427f654740f2a26ad62a5c155af9199af9e69b889claireho if(p==NULL) { 58527f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 58627f654740f2a26ad62a5c155af9199af9e69b889claireho } 58727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_memcpy(p, ptr, sizeof(H)+length*sizeof(T)); 58827f654740f2a26ad62a5c155af9199af9e69b889claireho } 58927f654740f2a26ad62a5c155af9199af9e69b889claireho resultCapacity=length; 59027f654740f2a26ad62a5c155af9199af9e69b889claireho ptr=&stackHeader; 59127f654740f2a26ad62a5c155af9199af9e69b889claireho capacity=stackCapacity; 59227f654740f2a26ad62a5c155af9199af9e69b889claireho needToRelease=FALSE; 59327f654740f2a26ad62a5c155af9199af9e69b889claireho return p; 59427f654740f2a26ad62a5c155af9199af9e69b889claireho} 59527f654740f2a26ad62a5c155af9199af9e69b889claireho 59650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END 59750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 598103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif /* __cplusplus */ 59950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif /* CMEMORY_H */ 600