Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/intl/icu/source/common/cmemory.h
Line
Count
Source (jump to first uncovered line)
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
/*
4
******************************************************************************
5
*
6
*   Copyright (C) 1997-2016, International Business Machines
7
*   Corporation and others.  All Rights Reserved.
8
*
9
******************************************************************************
10
*
11
* File CMEMORY.H
12
*
13
*  Contains stdlib.h/string.h memory functions
14
*
15
* @author       Bertrand A. Damiba
16
*
17
* Modification History:
18
*
19
*   Date        Name        Description
20
*   6/20/98     Bertrand    Created.
21
*  05/03/99     stephen     Changed from functions to macros.
22
*
23
******************************************************************************
24
*/
25
26
#ifndef CMEMORY_H
27
#define CMEMORY_H
28
29
#include "unicode/utypes.h"
30
31
#include <stddef.h>
32
#include <string.h>
33
#include "unicode/localpointer.h"
34
35
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
36
#include <stdio.h>
37
#endif
38
39
40
206k
#define uprv_memcpy(dst, src, size) U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size)
41
13.8k
#define uprv_memmove(dst, src, size) U_STANDARD_CPP_NAMESPACE memmove(dst, src, size)
42
43
/**
44
 * \def UPRV_LENGTHOF
45
 * Convenience macro to determine the length of a fixed array at compile-time.
46
 * @param array A fixed length array
47
 * @return The length of the array, in elements
48
 * @internal
49
 */
50
630
#define UPRV_LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
51
89.6k
#define uprv_memset(buffer, mark, size) U_STANDARD_CPP_NAMESPACE memset(buffer, mark, size)
52
0
#define uprv_memcmp(buffer1, buffer2, size) U_STANDARD_CPP_NAMESPACE memcmp(buffer1, buffer2,size)
53
54
U_CAPI void * U_EXPORT2
55
uprv_malloc(size_t s) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR(1);
56
57
U_CAPI void * U_EXPORT2
58
uprv_realloc(void *mem, size_t size) U_ALLOC_SIZE_ATTR(2);
59
60
U_CAPI void U_EXPORT2
61
uprv_free(void *mem);
62
63
U_CAPI void * U_EXPORT2
64
uprv_calloc(size_t num, size_t size) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR2(1,2);
65
66
/**
67
 * This should align the memory properly on any machine.
68
 * This is very useful for the safeClone functions.
69
 */
70
typedef union {
71
    long    t1;
72
    double  t2;
73
    void   *t3;
74
} UAlignedMemory;
75
76
/**
77
 * Get the least significant bits of a pointer (a memory address).
78
 * For example, with a mask of 3, the macro gets the 2 least significant bits,
79
 * which will be 0 if the pointer is 32-bit (4-byte) aligned.
80
 *
81
 * ptrdiff_t is the most appropriate integer type to cast to.
82
 * size_t should work too, since on most (or all?) platforms it has the same
83
 * width as ptrdiff_t.
84
 */
85
3
#define U_POINTER_MASK_LSB(ptr, mask) (((ptrdiff_t)(char *)(ptr)) & (mask))
86
87
/**
88
 * Get the amount of bytes that a pointer is off by from
89
 * the previous UAlignedMemory-aligned pointer.
90
 */
91
0
#define U_ALIGNMENT_OFFSET(ptr) U_POINTER_MASK_LSB(ptr, sizeof(UAlignedMemory) - 1)
92
93
/**
94
 * Get the amount of bytes to add to a pointer
95
 * in order to get the next UAlignedMemory-aligned address.
96
 */
97
0
#define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr))
98
99
/**
100
  *  Heap clean up function, called from u_cleanup()
101
  *    Clears any user heap functions from u_setMemoryFunctions()
102
  *    Does NOT deallocate any remaining allocated memory.
103
  */
104
U_CFUNC UBool 
105
cmemory_cleanup(void);
106
107
/**
108
 * A function called by <TT>uhash_remove</TT>,
109
 * <TT>uhash_close</TT>, or <TT>uhash_put</TT> to delete
110
 * an existing key or value.
111
 * @param obj A key or value stored in a hashtable
112
 * @see uprv_deleteUObject
113
 */
114
typedef void U_CALLCONV UObjectDeleter(void* obj);
115
116
/**
117
 * Deleter for UObject instances.
118
 * Works for all subclasses of UObject because it has a virtual destructor.
119
 */
120
U_CAPI void U_EXPORT2
121
uprv_deleteUObject(void *obj);
122
123
#ifdef __cplusplus
124
125
U_NAMESPACE_BEGIN
126
127
/**
128
 * "Smart pointer" class, deletes memory via uprv_free().
129
 * For most methods see the LocalPointerBase base class.
130
 * Adds operator[] for array item access.
131
 *
132
 * @see LocalPointerBase
133
 */
134
template<typename T>
135
class LocalMemory : public LocalPointerBase<T> {
136
public:
137
    using LocalPointerBase<T>::operator*;
138
    using LocalPointerBase<T>::operator->;
139
    /**
140
     * Constructor takes ownership.
141
     * @param p simple pointer to an array of T items that is adopted
142
     */
143
0
    explicit LocalMemory(T *p=NULL) : LocalPointerBase<T>(p) {}
Unexecuted instantiation: icu_62::LocalMemory<int>::LocalMemory(int*)
Unexecuted instantiation: icu_62::LocalMemory<char const*>::LocalMemory(char const**)
Unexecuted instantiation: icu_62::LocalMemory<UStringPrepProfile>::LocalMemory(UStringPrepProfile*)
Unexecuted instantiation: icu_62::LocalMemory<UStringPrepKey>::LocalMemory(UStringPrepKey*)
Unexecuted instantiation: icu_62::LocalMemory<char>::LocalMemory(char*)
Unexecuted instantiation: icu_62::LocalMemory<unsigned char>::LocalMemory(unsigned char*)
Unexecuted instantiation: icu_62::LocalMemory<icu_62::MessageFormat*>::LocalMemory(icu_62::MessageFormat**)
144
    /**
145
     * Move constructor, leaves src with isNull().
146
     * @param src source smart pointer
147
     */
148
    LocalMemory(LocalMemory<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
149
        src.ptr=NULL;
150
    }
151
    /**
152
     * Destructor deletes the memory it owns.
153
     */
154
0
    ~LocalMemory() {
155
0
        uprv_free(LocalPointerBase<T>::ptr);
156
0
    }
Unexecuted instantiation: icu_62::LocalMemory<int>::~LocalMemory()
Unexecuted instantiation: icu_62::LocalMemory<char const*>::~LocalMemory()
Unexecuted instantiation: icu_62::LocalMemory<char>::~LocalMemory()
Unexecuted instantiation: icu_62::LocalMemory<UStringPrepKey>::~LocalMemory()
Unexecuted instantiation: icu_62::LocalMemory<UStringPrepProfile>::~LocalMemory()
Unexecuted instantiation: icu_62::LocalMemory<unsigned char>::~LocalMemory()
Unexecuted instantiation: icu_62::LocalMemory<icu_62::MessageFormat*>::~LocalMemory()
157
    /**
158
     * Move assignment operator, leaves src with isNull().
159
     * The behavior is undefined if *this and src are the same object.
160
     * @param src source smart pointer
161
     * @return *this
162
     */
163
    LocalMemory<T> &operator=(LocalMemory<T> &&src) U_NOEXCEPT {
164
        return moveFrom(src);
165
    }
166
    /**
167
     * Move assignment, leaves src with isNull().
168
     * The behavior is undefined if *this and src are the same object.
169
     *
170
     * Can be called explicitly, does not need C++11 support.
171
     * @param src source smart pointer
172
     * @return *this
173
     */
174
    LocalMemory<T> &moveFrom(LocalMemory<T> &src) U_NOEXCEPT {
175
        delete[] LocalPointerBase<T>::ptr;
176
        LocalPointerBase<T>::ptr=src.ptr;
177
        src.ptr=NULL;
178
        return *this;
179
    }
180
    /**
181
     * Swap pointers.
182
     * @param other other smart pointer
183
     */
184
    void swap(LocalMemory<T> &other) U_NOEXCEPT {
185
        T *temp=LocalPointerBase<T>::ptr;
186
        LocalPointerBase<T>::ptr=other.ptr;
187
        other.ptr=temp;
188
    }
189
    /**
190
     * Non-member LocalMemory swap function.
191
     * @param p1 will get p2's pointer
192
     * @param p2 will get p1's pointer
193
     */
194
    friend inline void swap(LocalMemory<T> &p1, LocalMemory<T> &p2) U_NOEXCEPT {
195
        p1.swap(p2);
196
    }
197
    /**
198
     * Deletes the array it owns,
199
     * and adopts (takes ownership of) the one passed in.
200
     * @param p simple pointer to an array of T items that is adopted
201
     */
202
    void adoptInstead(T *p) {
203
        uprv_free(LocalPointerBase<T>::ptr);
204
        LocalPointerBase<T>::ptr=p;
205
    }
206
    /**
207
     * Deletes the array it owns, allocates a new one and reset its bytes to 0.
208
     * Returns the new array pointer.
209
     * If the allocation fails, then the current array is unchanged and
210
     * this method returns NULL.
211
     * @param newCapacity must be >0
212
     * @return the allocated array pointer, or NULL if the allocation failed
213
     */
214
    inline T *allocateInsteadAndReset(int32_t newCapacity=1);
215
    /**
216
     * Deletes the array it owns and allocates a new one, copying length T items.
217
     * Returns the new array pointer.
218
     * If the allocation fails, then the current array is unchanged and
219
     * this method returns NULL.
220
     * @param newCapacity must be >0
221
     * @param length number of T items to be copied from the old array to the new one;
222
     *               must be no more than the capacity of the old array,
223
     *               which the caller must track because the LocalMemory does not track it
224
     * @return the allocated array pointer, or NULL if the allocation failed
225
     */
226
    inline T *allocateInsteadAndCopy(int32_t newCapacity=1, int32_t length=0);
227
    /**
228
     * Array item access (writable).
229
     * No index bounds check.
230
     * @param i array index
231
     * @return reference to the array item
232
     */
233
0
    T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
Unexecuted instantiation: icu_62::LocalMemory<int>::operator[](long) const
Unexecuted instantiation: icu_62::LocalMemory<char const*>::operator[](long) const
Unexecuted instantiation: icu_62::LocalMemory<icu_62::MessageFormat*>::operator[](long) const
234
};
235
236
template<typename T>
237
0
inline T *LocalMemory<T>::allocateInsteadAndReset(int32_t newCapacity) {
238
0
    if(newCapacity>0) {
239
0
        T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
240
0
        if(p!=NULL) {
241
0
            uprv_memset(p, 0, newCapacity*sizeof(T));
242
0
            uprv_free(LocalPointerBase<T>::ptr);
243
0
            LocalPointerBase<T>::ptr=p;
244
0
        }
245
0
        return p;
246
0
    } else {
247
0
        return NULL;
248
0
    }
249
0
}
Unexecuted instantiation: icu_62::LocalMemory<int>::allocateInsteadAndReset(int)
Unexecuted instantiation: icu_62::LocalMemory<char const*>::allocateInsteadAndReset(int)
Unexecuted instantiation: icu_62::LocalMemory<UStringPrepProfile>::allocateInsteadAndReset(int)
Unexecuted instantiation: icu_62::LocalMemory<UStringPrepKey>::allocateInsteadAndReset(int)
250
251
252
template<typename T>
253
0
inline T *LocalMemory<T>::allocateInsteadAndCopy(int32_t newCapacity, int32_t length) {
254
0
    if(newCapacity>0) {
255
0
        T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
256
0
        if(p!=NULL) {
257
0
            if(length>0) {
258
0
                if(length>newCapacity) {
259
0
                    length=newCapacity;
260
0
                }
261
0
                uprv_memcpy(p, LocalPointerBase<T>::ptr, (size_t)length*sizeof(T));
262
0
            }
263
0
            uprv_free(LocalPointerBase<T>::ptr);
264
0
            LocalPointerBase<T>::ptr=p;
265
0
        }
266
0
        return p;
267
0
    } else {
268
0
        return NULL;
269
0
    }
270
0
}
Unexecuted instantiation: icu_62::LocalMemory<char>::allocateInsteadAndCopy(int, int)
Unexecuted instantiation: icu_62::LocalMemory<unsigned char>::allocateInsteadAndCopy(int, int)
271
272
/**
273
 * Simple array/buffer management class using uprv_malloc() and uprv_free().
274
 * Provides an internal array with fixed capacity. Can alias another array
275
 * or allocate one.
276
 *
277
 * The array address is properly aligned for type T. It might not be properly
278
 * aligned for types larger than T (or larger than the largest subtype of T).
279
 *
280
 * Unlike LocalMemory and LocalArray, this class never adopts
281
 * (takes ownership of) another array.
282
 */
283
template<typename T, int32_t stackCapacity>
284
class MaybeStackArray {
285
public:
286
    /**
287
     * Default constructor initializes with internal T[stackCapacity] buffer.
288
     */
289
36
    MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(FALSE) {}
icu_62::MaybeStackArray<char, 40>::MaybeStackArray()
Line
Count
Source
289
36
    MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(FALSE) {}
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<double, 8>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<void*, 16>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<_acceptLangItem, 4>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::number::impl::CompactModInfo, 12>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 20>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<char, 30>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 10>::MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<UScriptCode, 5>::MaybeStackArray()
290
    /**
291
     * Automatically allocates the heap array if the argument is larger than the stack capacity.
292
     * Intended for use when an approximate capacity is known at compile time but the true
293
     * capacity is not known until runtime.
294
     */
295
0
    MaybeStackArray(int32_t newCapacity) : MaybeStackArray() {
296
0
        if (capacity < newCapacity) { resize(newCapacity); }
297
0
    };
Unexecuted instantiation: icu_62::MaybeStackArray<char, 40>::MaybeStackArray(int)
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 20>::MaybeStackArray(int)
Unexecuted instantiation: icu_62::MaybeStackArray<char, 30>::MaybeStackArray(int)
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::MaybeStackArray(int)
298
    /**
299
     * Destructor deletes the array (if owned).
300
     */
301
36
    ~MaybeStackArray() { releaseArray(); }
icu_62::MaybeStackArray<char, 40>::~MaybeStackArray()
Line
Count
Source
301
36
    ~MaybeStackArray() { releaseArray(); }
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<double, 8>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<void*, 16>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<_acceptLangItem, 4>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::number::impl::CompactModInfo, 12>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 20>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<char, 30>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 10>::~MaybeStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<UScriptCode, 5>::~MaybeStackArray()
302
    /**
303
     * Move constructor: transfers ownership or copies the stack array.
304
     */
305
    MaybeStackArray(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT;
306
    /**
307
     * Move assignment: transfers ownership or copies the stack array.
308
     */
309
    MaybeStackArray<T, stackCapacity> &operator=(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT;
310
    /**
311
     * Returns the array capacity (number of T items).
312
     * @return array capacity
313
     */
314
99
    int32_t getCapacity() const { return capacity; }
icu_62::MaybeStackArray<char, 40>::getCapacity() const
Line
Count
Source
314
99
    int32_t getCapacity() const { return capacity; }
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<double, 8>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<void*, 16>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<_acceptLangItem, 4>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::number::impl::CompactModInfo, 12>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 10>::getCapacity() const
Unexecuted instantiation: icu_62::MaybeStackArray<UScriptCode, 5>::getCapacity() const
315
    /**
316
     * Access without ownership change.
317
     * @return the array pointer
318
     */
319
306
    T *getAlias() const { return ptr; }
icu_62::MaybeStackArray<char, 40>::getAlias() const
Line
Count
Source
319
306
    T *getAlias() const { return ptr; }
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<double, 8>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<void*, 16>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<_acceptLangItem, 4>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 20>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<char, 30>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::getAlias() const
Unexecuted instantiation: icu_62::MaybeStackArray<UScriptCode, 5>::getAlias() const
320
    /**
321
     * Returns the array limit. Simple convenience method.
322
     * @return getAlias()+getCapacity()
323
     */
324
0
    T *getArrayLimit() const { return getAlias()+capacity; }
325
    // No "operator T *() const" because that can make
326
    // expressions like mbs[index] ambiguous for some compilers.
327
    /**
328
     * Array item access (const).
329
     * No index bounds check.
330
     * @param i array index
331
     * @return reference to the array item
332
     */
333
0
    const T &operator[](ptrdiff_t i) const { return ptr[i]; }
Unexecuted instantiation: icu_62::MaybeStackArray<char, 40>::operator[](long) const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::operator[](long) const
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::operator[](long) const
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::operator[](long) const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::number::impl::CompactModInfo, 12>::operator[](long) const
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 10>::operator[](long) const
334
    /**
335
     * Array item access (writable).
336
     * No index bounds check.
337
     * @param i array index
338
     * @return reference to the array item
339
     */
340
153
    T &operator[](ptrdiff_t i) { return ptr[i]; }
icu_62::MaybeStackArray<char, 40>::operator[](long)
Line
Count
Source
340
153
    T &operator[](ptrdiff_t i) { return ptr[i]; }
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<double, 8>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<_acceptLangItem, 4>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::number::impl::CompactModInfo, 12>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 20>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<char, 30>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 10>::operator[](long)
Unexecuted instantiation: icu_62::MaybeStackArray<UScriptCode, 5>::operator[](long)
341
    /**
342
     * Deletes the array (if owned) and aliases another one, no transfer of ownership.
343
     * If the arguments are illegal, then the current array is unchanged.
344
     * @param otherArray must not be NULL
345
     * @param otherCapacity must be >0
346
     */
347
0
    void aliasInstead(T *otherArray, int32_t otherCapacity) {
348
0
        if(otherArray!=NULL && otherCapacity>0) {
349
0
            releaseArray();
350
0
            ptr=otherArray;
351
0
            capacity=otherCapacity;
352
0
            needToRelease=FALSE;
353
0
        }
354
0
    }
355
    /**
356
     * Deletes the array (if owned) and allocates a new one, copying length T items.
357
     * Returns the new array pointer.
358
     * If the allocation fails, then the current array is unchanged and
359
     * this method returns NULL.
360
     * @param newCapacity can be less than or greater than the current capacity;
361
     *                    must be >0
362
     * @param length number of T items to be copied from the old array to the new one
363
     * @return the allocated array pointer, or NULL if the allocation failed
364
     */
365
    inline T *resize(int32_t newCapacity, int32_t length=0);
366
    /**
367
     * Gives up ownership of the array if owned, or else clones it,
368
     * copying length T items; resets itself to the internal stack array.
369
     * Returns NULL if the allocation failed.
370
     * @param length number of T items to copy when cloning,
371
     *        and capacity of the clone when cloning
372
     * @param resultCapacity will be set to the returned array's capacity (output-only)
373
     * @return the array pointer;
374
     *         caller becomes responsible for deleting the array
375
     */
376
    inline T *orphanOrClone(int32_t length, int32_t &resultCapacity);
377
private:
378
    T *ptr;
379
    int32_t capacity;
380
    UBool needToRelease;
381
    T stackArray[stackCapacity];
382
36
    void releaseArray() {
383
36
        if(needToRelease) {
384
0
            uprv_free(ptr);
385
0
        }
386
36
    }
icu_62::MaybeStackArray<char, 40>::releaseArray()
Line
Count
Source
382
36
    void releaseArray() {
383
36
        if(needToRelease) {
384
0
            uprv_free(ptr);
385
0
        }
386
36
    }
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<double, 8>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<void*, 16>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<_acceptLangItem, 4>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::number::impl::CompactModInfo, 12>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 20>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<char, 30>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 10>::releaseArray()
Unexecuted instantiation: icu_62::MaybeStackArray<UScriptCode, 5>::releaseArray()
387
0
    void resetToStackArray() {
388
0
        ptr=stackArray;
389
0
        capacity=stackCapacity;
390
0
        needToRelease=FALSE;
391
0
    }
Unexecuted instantiation: icu_62::MaybeStackArray<char, 40>::resetToStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::resetToStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::resetToStackArray()
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::resetToStackArray()
392
    /* No comparison operators with other MaybeStackArray's. */
393
0
    bool operator==(const MaybeStackArray & /*other*/) {return FALSE;}
394
0
    bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;}
395
    /* No ownership transfer: No copy constructor, no assignment operator. */
396
0
    MaybeStackArray(const MaybeStackArray & /*other*/) {}
397
0
    void operator=(const MaybeStackArray & /*other*/) {}
398
399
    // No heap allocation. Use only on the stack.
400
    //   (Declaring these functions private triggers a cascade of problems:
401
    //      MSVC insists on exporting an instantiation of MaybeStackArray, which
402
    //      requires that all functions be defined.
403
    //      An empty implementation of new() is rejected, it must return a value.
404
    //      Returning NULL is rejected by gcc for operator new.
405
    //      The expedient thing is just not to override operator new.
406
    //      While relatively pointless, heap allocated instances will function.
407
    // static void * U_EXPORT2 operator new(size_t size); 
408
    // static void * U_EXPORT2 operator new[](size_t size);
409
#if U_HAVE_PLACEMENT_NEW
410
    // static void * U_EXPORT2 operator new(size_t, void *ptr);
411
#endif
412
};
413
414
template<typename T, int32_t stackCapacity>
415
icu::MaybeStackArray<T, stackCapacity>::MaybeStackArray(
416
        MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT
417
0
        : ptr(src.ptr), capacity(src.capacity), needToRelease(src.needToRelease) {
418
0
    if (src.ptr == src.stackArray) {
419
0
        ptr = stackArray;
420
0
        uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity);
421
0
    } else {
422
0
        src.resetToStackArray();  // take ownership away from src
423
0
    }
424
0
}
Unexecuted instantiation: icu_62::MaybeStackArray<char, 40>::MaybeStackArray(icu_62::MaybeStackArray<char, 40>&&)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::MaybeStackArray(icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>&&)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::MaybeStackArray(icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>&&)
425
426
template<typename T, int32_t stackCapacity>
427
inline MaybeStackArray <T, stackCapacity>&
428
0
MaybeStackArray<T, stackCapacity>::operator=(MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT {
429
0
    releaseArray();  // in case this instance had its own memory allocated
430
0
    capacity = src.capacity;
431
0
    needToRelease = src.needToRelease;
432
0
    if (src.ptr == src.stackArray) {
433
0
        ptr = stackArray;
434
0
        uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity);
435
0
    } else {
436
0
        ptr = src.ptr;
437
0
        src.resetToStackArray();  // take ownership away from src
438
0
    }
439
0
    return *this;
440
0
}
Unexecuted instantiation: icu_62::MaybeStackArray<char, 40>::operator=(icu_62::MaybeStackArray<char, 40>&&)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::operator=(icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>&&)
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::operator=(icu_62::MaybeStackArray<char16_t, 4>&&)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::operator=(icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>&&)
441
442
template<typename T, int32_t stackCapacity>
443
0
inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) {
444
0
    if(newCapacity>0) {
445
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
446
      ::fprintf(::stderr,"MaybeStacArray (resize) alloc %d * %lu\n", newCapacity,sizeof(T));
447
#endif
448
0
        T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
449
0
        if(p!=NULL) {
450
0
            if(length>0) {
451
0
                if(length>capacity) {
452
0
                    length=capacity;
453
0
                }
454
0
                if(length>newCapacity) {
455
0
                    length=newCapacity;
456
0
                }
457
0
                uprv_memcpy(p, ptr, (size_t)length*sizeof(T));
458
0
            }
459
0
            releaseArray();
460
0
            ptr=p;
461
0
            capacity=newCapacity;
462
0
            needToRelease=TRUE;
463
0
        }
464
0
        return p;
465
0
    } else {
466
0
        return NULL;
467
0
    }
468
0
}
Unexecuted instantiation: icu_62::MaybeStackArray<char, 40>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::MessagePattern::Part, 32>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<double, 8>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<void*, 16>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<_acceptLangItem, 4>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<long, 40>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 40>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::number::impl::CompactModInfo, 12>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<unsigned char, 20>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<char, 30>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 3>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::CodePointMatcher*, 3>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<char16_t, 4>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<icu_62::numparse::impl::NumberParseMatcher const*, 10>::resize(int, int)
Unexecuted instantiation: icu_62::MaybeStackArray<UScriptCode, 5>::resize(int, int)
469
470
template<typename T, int32_t stackCapacity>
471
0
inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32_t &resultCapacity) {
472
0
    T *p;
473
0
    if(needToRelease) {
474
0
        p=ptr;
475
0
    } else if(length<=0) {
476
0
        return NULL;
477
0
    } else {
478
0
        if(length>capacity) {
479
0
            length=capacity;
480
0
        }
481
0
        p=(T *)uprv_malloc(length*sizeof(T));
482
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
483
      ::fprintf(::stderr,"MaybeStacArray (orphan) alloc %d * %lu\n", length,sizeof(T));
484
#endif
485
0
        if(p==NULL) {
486
0
            return NULL;
487
0
        }
488
0
        uprv_memcpy(p, ptr, (size_t)length*sizeof(T));
489
0
    }
490
0
    resultCapacity=length;
491
0
    resetToStackArray();
492
0
    return p;
493
0
}
494
495
/**
496
 * Variant of MaybeStackArray that allocates a header struct and an array
497
 * in one contiguous memory block, using uprv_malloc() and uprv_free().
498
 * Provides internal memory with fixed array capacity. Can alias another memory
499
 * block or allocate one.
500
 * The stackCapacity is the number of T items in the internal memory,
501
 * not counting the H header.
502
 * Unlike LocalMemory and LocalArray, this class never adopts
503
 * (takes ownership of) another memory block.
504
 */
505
template<typename H, typename T, int32_t stackCapacity>
506
class MaybeStackHeaderAndArray {
507
public:
508
    /**
509
     * Default constructor initializes with internal H+T[stackCapacity] buffer.
510
     */
511
0
    MaybeStackHeaderAndArray() : ptr(&stackHeader), capacity(stackCapacity), needToRelease(FALSE) {}
512
    /**
513
     * Destructor deletes the memory (if owned).
514
     */
515
0
    ~MaybeStackHeaderAndArray() { releaseMemory(); }
516
    /**
517
     * Returns the array capacity (number of T items).
518
     * @return array capacity
519
     */
520
    int32_t getCapacity() const { return capacity; }
521
    /**
522
     * Access without ownership change.
523
     * @return the header pointer
524
     */
525
0
    H *getAlias() const { return ptr; }
526
    /**
527
     * Returns the array start.
528
     * @return array start, same address as getAlias()+1
529
     */
530
0
    T *getArrayStart() const { return reinterpret_cast<T *>(getAlias()+1); }
531
    /**
532
     * Returns the array limit.
533
     * @return array limit
534
     */
535
0
    T *getArrayLimit() const { return getArrayStart()+capacity; }
536
    /**
537
     * Access without ownership change. Same as getAlias().
538
     * A class instance can be used directly in expressions that take a T *.
539
     * @return the header pointer
540
     */
541
0
    operator H *() const { return ptr; }
542
    /**
543
     * Array item access (writable).
544
     * No index bounds check.
545
     * @param i array index
546
     * @return reference to the array item
547
     */
548
    T &operator[](ptrdiff_t i) { return getArrayStart()[i]; }
549
    /**
550
     * Deletes the memory block (if owned) and aliases another one, no transfer of ownership.
551
     * If the arguments are illegal, then the current memory is unchanged.
552
     * @param otherArray must not be NULL
553
     * @param otherCapacity must be >0
554
     */
555
    void aliasInstead(H *otherMemory, int32_t otherCapacity) {
556
        if(otherMemory!=NULL && otherCapacity>0) {
557
            releaseMemory();
558
            ptr=otherMemory;
559
            capacity=otherCapacity;
560
            needToRelease=FALSE;
561
        }
562
    }
563
    /**
564
     * Deletes the memory block (if owned) and allocates a new one,
565
     * copying the header and length T array items.
566
     * Returns the new header pointer.
567
     * If the allocation fails, then the current memory is unchanged and
568
     * this method returns NULL.
569
     * @param newCapacity can be less than or greater than the current capacity;
570
     *                    must be >0
571
     * @param length number of T items to be copied from the old array to the new one
572
     * @return the allocated pointer, or NULL if the allocation failed
573
     */
574
    inline H *resize(int32_t newCapacity, int32_t length=0);
575
    /**
576
     * Gives up ownership of the memory if owned, or else clones it,
577
     * copying the header and length T array items; resets itself to the internal memory.
578
     * Returns NULL if the allocation failed.
579
     * @param length number of T items to copy when cloning,
580
     *        and array capacity of the clone when cloning
581
     * @param resultCapacity will be set to the returned array's capacity (output-only)
582
     * @return the header pointer;
583
     *         caller becomes responsible for deleting the array
584
     */
585
    inline H *orphanOrClone(int32_t length, int32_t &resultCapacity);
586
private:
587
    H *ptr;
588
    int32_t capacity;
589
    UBool needToRelease;
590
    // stackHeader must precede stackArray immediately.
591
    H stackHeader;
592
    T stackArray[stackCapacity];
593
0
    void releaseMemory() {
594
0
        if(needToRelease) {
595
0
            uprv_free(ptr);
596
0
        }
597
0
    }
598
    /* No comparison operators with other MaybeStackHeaderAndArray's. */
599
    bool operator==(const MaybeStackHeaderAndArray & /*other*/) {return FALSE;}
600
    bool operator!=(const MaybeStackHeaderAndArray & /*other*/) {return TRUE;}
601
    /* No ownership transfer: No copy constructor, no assignment operator. */
602
    MaybeStackHeaderAndArray(const MaybeStackHeaderAndArray & /*other*/) {}
603
    void operator=(const MaybeStackHeaderAndArray & /*other*/) {}
604
605
    // No heap allocation. Use only on the stack.
606
    //   (Declaring these functions private triggers a cascade of problems;
607
    //    see the MaybeStackArray class for details.)
608
    // static void * U_EXPORT2 operator new(size_t size); 
609
    // static void * U_EXPORT2 operator new[](size_t size);
610
#if U_HAVE_PLACEMENT_NEW
611
    // static void * U_EXPORT2 operator new(size_t, void *ptr);
612
#endif
613
};
614
615
template<typename H, typename T, int32_t stackCapacity>
616
inline H *MaybeStackHeaderAndArray<H, T, stackCapacity>::resize(int32_t newCapacity,
617
0
                                                                int32_t length) {
618
0
    if(newCapacity>=0) {
619
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
620
      ::fprintf(::stderr,"MaybeStackHeaderAndArray alloc %d + %d * %ul\n", sizeof(H),newCapacity,sizeof(T));
621
#endif
622
0
        H *p=(H *)uprv_malloc(sizeof(H)+newCapacity*sizeof(T));
623
0
        if(p!=NULL) {
624
0
            if(length<0) {
625
0
                length=0;
626
0
            } else if(length>0) {
627
0
                if(length>capacity) {
628
0
                    length=capacity;
629
0
                }
630
0
                if(length>newCapacity) {
631
0
                    length=newCapacity;
632
0
                }
633
0
            }
634
0
            uprv_memcpy(p, ptr, sizeof(H)+(size_t)length*sizeof(T));
635
0
            releaseMemory();
636
0
            ptr=p;
637
0
            capacity=newCapacity;
638
0
            needToRelease=TRUE;
639
0
        }
640
0
        return p;
641
0
    } else {
642
0
        return NULL;
643
0
    }
644
0
}
645
646
template<typename H, typename T, int32_t stackCapacity>
647
inline H *MaybeStackHeaderAndArray<H, T, stackCapacity>::orphanOrClone(int32_t length,
648
                                                                       int32_t &resultCapacity) {
649
    H *p;
650
    if(needToRelease) {
651
        p=ptr;
652
    } else {
653
        if(length<0) {
654
            length=0;
655
        } else if(length>capacity) {
656
            length=capacity;
657
        }
658
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
659
      ::fprintf(::stderr,"MaybeStackHeaderAndArray (orphan) alloc %ul + %d * %lu\n", sizeof(H),length,sizeof(T));
660
#endif
661
        p=(H *)uprv_malloc(sizeof(H)+length*sizeof(T));
662
        if(p==NULL) {
663
            return NULL;
664
        }
665
        uprv_memcpy(p, ptr, sizeof(H)+(size_t)length*sizeof(T));
666
    }
667
    resultCapacity=length;
668
    ptr=&stackHeader;
669
    capacity=stackCapacity;
670
    needToRelease=FALSE;
671
    return p;
672
}
673
674
U_NAMESPACE_END
675
676
#endif  /* __cplusplus */
677
#endif  /* CMEMORY_H */