Stimfit @PACKAGE_VERSION@
Loading...
Searching...
No Matches
ArrayPtr.hpp
Go to the documentation of this file.
1//***********************************************************************************************
2//
3// Copyright (c) 1996-1997 Axon Instruments.
4// All rights reserved.
5//
6//***********************************************************************************************
7// HEADER: ARRAYPTR.HPP
8// PURPOSE: Define the template class CArrayPtr<ITEM>
9// AUTHOR: BHI Sep 1996
10//
11//
12#ifndef INC_ARRAYPTR_HPP
13#define INC_ARRAYPTR_HPP
14
15#pragma once
16#include <stdlib.h>
17#if (__cplusplus < 201402L)
18# include <boost/shared_array.hpp>
19#else
20# include <memory>
21#endif
22
23#if defined(__UNIX__) || defined(__STF__)
24 #define max(a,b) (((a) > (b)) ? (a) : (b))
25 #define min(a,b) (((a) < (b)) ? (a) : (b))
26#endif
27
28//***********************************************************************************************
29// CLASS: CArrayPtr
30// PURPOSE: A smart pointer class for arrays of objects or primitive ITEMs.
31//
32template<class ITEM>
33class CArrayPtr
34{
35private: // Private data.
36#if (__cplusplus < 201402L)
37 boost::shared_array<ITEM> m_pArray;
38#else
39 std::shared_ptr<ITEM> m_pArray;
40#endif
41
42private: // Prevent copy constructors and operator=().
43 CArrayPtr(const CArrayPtr &);
44 const CArrayPtr &operator=(const CArrayPtr &);
45
46public: // Public member functions.
47
48 // Constructors & destructor. See notes below.
49 CArrayPtr(ITEM *pItem = NULL);
50 CArrayPtr(UINT uCount);
51 ~CArrayPtr();
52
53 // Allocation and destruction of memory pointed to by this object.
54 BOOL Alloc(UINT uCount);
55/* BOOL Realloc(UINT uOldCount, UINT uNewCount, BOOL bZero=FALSE);
56 BOOL Clone(const ITEM *pItem, UINT uCount);
57*/ void Free();
58
59 // Accessor functions to get at the wrapped array.
60 operator ITEM *() const;
61 ITEM *Get() const;
62/*
63 // Destroys the held array and replaces it with another.
64 void Set(ITEM *);
65
66 // Non-destructive release of the held pointer.
67 ITEM *Release();
68
69 // Zero the held array from 0 for uCount items.
70 void Zero(UINT uCount);
71
72 // Sorts the data held in the pointer according to a user-supplied callback.
73 void Sort(UINT uCount, int (__cdecl *FnCompare )(const void *elem1, const void *elem2 ));
74*/
75};
76
77//================================================================================================
78// FUNCTION: Constructor
79// PURPOSE: Create a new object that wraps a passed pointer.
80// NOTES: If the passed pointer is non-NULL, it *MUST* have been created on the
81// heap using the array allocater new[].
82// Unfortunately there is no reliable way to ASSERT this.
83//
84// The definition of this constructor contains a default parameter of NULL
85// so that CArrayPtr objects can be created that do not hold anything.
86//
87
88template <class ITEM>
89inline CArrayPtr<ITEM>::CArrayPtr/*CSH<ITEM>*/(ITEM *pItem)
90{
91// MEMBERASSERT();
92 ASSERT_NOTONSTACK(pItem);
93 m_pArray = std::shared_ptr<ITEM>(pItem, std::default_delete<ITEM[]>());
94}
95
96//================================================================================================
97// FUNCTION: Constructor
98// PURPOSE: Create a new object and allocate a buffer of the passed size.
99//
100template <class ITEM>
101inline CArrayPtr<ITEM>::CArrayPtr/*CSH<ITEM>*/(UINT uCount)
102{
103// MEMBERASSERT();
104 m_pArray.reset();
105 Alloc(uCount);
106}
107
108//================================================================================================
109// FUNCTION: Destructor
110// PURPOSE: Frees a held pointer if non-NULL.
111//
112template <class ITEM>
113inline CArrayPtr<ITEM>::~CArrayPtr/*CSH<ITEM>*/()
114{
115// MEMBERASSERT();
116// delete[] m_pArray;
117// m_pArray = NULL;
118}
119
120//================================================================================================
121// FUNCTION: Alloc
122// PURPOSE: Frees any held pointer and allocates a new array of the wrapped ITEM.
123//
124template <class ITEM>
126{
127// MEMBERASSERT();
128
129 // Free any existing array.
130 Free();
131
132 // Return now if nothing is to be allocated.
133 if (uCount == 0)
134 return TRUE;
135
136 // Allocate the new array.
137 m_pArray = std::shared_ptr<ITEM>(new ITEM[uCount], std::default_delete<ITEM[]>());
138 return static_cast<bool>(m_pArray);
139}
140/*
141//================================================================================================
142// FUNCTION: Realloc
143// PURPOSE: Reallocates the held pointer keeping the held data.
144//
145template <class ITEM>
146inline BOOL CArrayPtr<ITEM>::Realloc(UINT uOldCount, UINT uNewCount, BOOL bZero)
147{
148 MEMBERASSERT();
149 ARRAYASSERT(m_pArray, uOldCount);
150
151 CArrayPtr<ITEM> pNewArray;
152 if (uNewCount && !pNewArray.Alloc(uNewCount))
153 return FALSE;
154
155 for (UINT i=0; i<min(uOldCount, uNewCount); i++)
156 pNewArray[i] = m_pArray[i];
157
158 // Free any existing array.
159 Free();
160
161 // Return now if nothing is to be allocated.
162 if (uNewCount == 0)
163 return TRUE;
164
165 // Allocate the new array.
166 m_pArray = pNewArray.Release();
167 return TRUE;
168}
169
170//================================================================================================
171// FUNCTION: Clone
172// PURPOSE: Frees any held pointer and allocates a new array of the wrapped ITEM.
173// The passed array is then copied into the new buffer.
174//
175template <class ITEM>
176inline BOOL CArrayPtr<ITEM>::Clone(const ITEM *pItem, UINT uCount)
177{
178 MEMBERASSERT();
179
180 // Reallocate the held pointer.
181 if (!Alloc(uCount))
182 return FALSE;
183
184 // Check that we have valid parameters.
185 ARRAYASSERT(pItem, uCount);
186
187 // If this object was only for wrapping primitive types, a memcpy call
188 // would be most efficient for cloning, but this is inappropriate for
189 // arrays of objects.
190 // memcpy(m_pArray, pItem, uCount*sizeof(ITEM));
191
192 // Use a for loop to copy the array into the new buffer.
193 for (UINT i=0; i<uCount; i++)
194 m_pArray[i] = pItem[i];
195
196 return TRUE;
197}
198*/
199//================================================================================================
200// FUNCTION: Free
201// PURPOSE: De-allocates the held pointer. Benign NOP if no pointer held.
202//
203template <class ITEM>
205{
206// MEMBERASSERT();
207 m_pArray.reset();
208}
209
210//================================================================================================
211// FUNCTION: Get
212// PURPOSE: Returns the held pointer without giving up ownership of it.
213//
214template <class ITEM>
215inline ITEM *CArrayPtr<ITEM>::Get() const
216{
217// MEMBERASSERT();
218 return m_pArray.get();
219}
220/*
221//================================================================================================
222// FUNCTION: Set
223// PURPOSE: Destroys the held array and replaces it with another.
224//
225template <class ITEM>
226inline void CArrayPtr<ITEM>::Set(ITEM *pItem)
227{
228 ASSERT_NOTONSTACK(pItem);
229 Free();
230 m_pArray = pItem;
231}
232*/
233//================================================================================================
234// FUNCTION: Overloaded cast operator
235// PURPOSE: Returns the held pointer without giving up ownership of it.
236//
237template <class ITEM>
238inline CArrayPtr<ITEM>::operator ITEM *() const
239{
240// MEMBERASSERT();
241 return Get();
242}
243/*
244//================================================================================================
245// FUNCTION: Release
246// PURPOSE: Returns the held pointer, giving up ownership of it.
247//
248template <class ITEM>
249inline ITEM *CArrayPtr<ITEM>::Release()
250{
251 MEMBERASSERT();
252 ITEM *rval = m_pArray;
253 m_pArray = NULL;
254 return rval;
255}
256
257//================================================================================================
258// FUNCTION: Zero
259// PURPOSE: Zero's out the held pointer from item 0 for uCount items.
260//
261template <class ITEM>
262inline void CArrayPtr<ITEM>::Zero(UINT uCount)
263{
264 MEMBERASSERT();
265 ARRAYASSERT(m_pArray, uCount);
266 memset(m_pArray, 0, uCount*sizeof(ITEM));
267}
268
269//================================================================================================
270// FUNCTION: Sort
271// PURPOSE: Sorts the data held in the pointer according to a user-supplied callback.
272//
273template <class ITEM>
274inline void CArrayPtr<ITEM>::Sort(UINT uCount, int (__cdecl *FnCompare )(const void *elem1, const void *elem2 ))
275{
276 MEMBERASSERT();
277 ARRAYASSERT(m_pArray, uCount);
278 qsort(m_pArray, uCount, sizeof(ITEM), FnCompare);
279}
280*/
281
282/*
283//################################################################################################
284//################################################################################################
285//###
286//### CLASS: CArrayPtrEx
287//### PURPOSE: Extended smart pointer that also holds the count of objects held.
288//###
289//################################################################################################
290//################################################################################################
291
292// ***********************************************************************************************
293// CLASS: CArrayPtrEx
294// PURPOSE: A vector class for arrays of objects or primitive ITEMs.
295//
296template<class ITEM>
297class CArrayPtrEx
298{
299private: // Private data.
300 ITEM *m_pArray;
301 UINT m_uCount;
302
303private: // Prevent copy constructors and operator=().
304 CArrayPtrEx(const CArrayPtrEx &);
305 const CArrayPtrEx &operator=(const CArrayPtrEx &);
306
307public: // Public member functions.
308
309 // Constructors & destructor. See notes below.
310 CArrayPtrEx();
311 CArrayPtrEx(UINT uCount);
312 ~CArrayPtrEx();
313
314 // Allocation and destruction of memory pointed to by this object.
315 BOOL Alloc(UINT uCount);
316 BOOL Realloc(UINT uNewCount, BOOL bZero=FALSE);
317 BOOL Clone(const ITEM *pItem, UINT uCount);
318 void Free();
319
320 // Accessor functions to get at the wrapped array.
321 operator ITEM *() const;
322 ITEM *Get() const;
323
324 // Destroys the held array and replaces it with another.
325 void Set(ITEM *, UINT uCount);
326
327 // Non-destructive release of the held pointer.
328 ITEM *Release();
329
330 // Returns number of items held.
331 UINT GetCount() const;
332
333 // Zero the held array.
334 void Zero();
335
336 // Sorts the data held in the pointer according to a user-supplied callback.
337 void Sort(int (__cdecl *FnCompare )(const void *elem1, const void *elem2 ));
338};
339
340//================================================================================================
341// FUNCTION: Constructor
342// PURPOSE: Create a new object that wraps a passed pointer.
343// NOTES: If the passed pointer is non-NULL, it *MUST* have been created on the
344// heap using the array allocater new[].
345// Unfortunately there is no reliable way to ASSERT this.
346//
347// The definition of this constructor contains a default parameter of NULL
348// so that CArrayPtrEx objects can be created that do not hold anything.
349//
350template <class ITEM>
351inline CArrayPtrEx<ITEM>::CArrayPtrEx<ITEM>()
352{
353 MEMBERASSERT();
354 m_pArray = NULL;
355 m_uCount = 0;
356}
357
358//================================================================================================
359// FUNCTION: Constructor
360// PURPOSE: Create a new object and allocate a buffer of the passed size.
361//
362template <class ITEM>
363inline CArrayPtrEx<ITEM>::CArrayPtrEx<ITEM>(UINT uCount)
364{
365 MEMBERASSERT();
366 m_pArray = NULL;
367 m_uCount = 0;
368 Alloc(uCount);
369}
370
371//================================================================================================
372// FUNCTION: Destructor
373// PURPOSE: Frees a held pointer if non-NULL.
374//
375template <class ITEM>
376inline CArrayPtrEx<ITEM>::~CArrayPtrEx<ITEM>()
377{
378 MEMBERASSERT();
379 Free();
380}
381
382//================================================================================================
383// FUNCTION: Alloc
384// PURPOSE: Frees any held pointer and allocates a new array of the wrapped ITEM.
385//
386template <class ITEM>
387inline BOOL CArrayPtrEx<ITEM>::Alloc(UINT uCount)
388{
389 MEMBERASSERT();
390
391 // Check if we already have the right size.
392 if (m_uCount == uCount)
393 return TRUE;
394
395 // Free any existing array.
396 Free();
397
398 // Return now if nothing is to be allocated.
399 if (uCount == 0)
400 return TRUE;
401
402 // Allocate the new array.
403 m_pArray = new ITEM[uCount];
404 if (m_pArray)
405 m_uCount = uCount;
406 return (m_pArray!=NULL);
407}
408
409//================================================================================================
410// FUNCTION: Realloc
411// PURPOSE: Reallocates the held pointer keeping the held data.
412//
413template <class ITEM>
414inline BOOL CArrayPtrEx<ITEM>::Realloc(UINT uNewCount, BOOL bZero)
415{
416 MEMBERASSERT();
417 ARRAYASSERT(m_pArray, m_uCount);
418
419 if (m_uCount == uNewCount)
420 return TRUE;
421
422 UINT uOldCount = m_uCount;
423
424 CArrayPtrEx<ITEM> pNewArray;
425 if (uNewCount && !pNewArray.Alloc(uNewCount))
426 return FALSE;
427
428 for (UINT i=0; i<min(m_uCount, uNewCount); i++)
429 pNewArray[i] = m_pArray[i];
430
431 // Free any existing array.
432 Free();
433
434 // Return now if nothing is to be allocated.
435 if (uNewCount == 0)
436 return TRUE;
437
438 // Keep the new array.
439 m_pArray = pNewArray.Release();
440 m_uCount = uNewCount;
441
442 if (bZero && (uOldCount < m_uCount))
443 memset(m_pArray+uOldCount, 0, (m_uCount-uOldCount)*sizeof(ITEM));
444
445 return TRUE;
446}
447
448//================================================================================================
449// FUNCTION: Clone
450// PURPOSE: Frees any held pointer and allocates a new array of the wrapped ITEM.
451// The passed array is then copied into the new buffer.
452//
453template <class ITEM>
454inline BOOL CArrayPtrEx<ITEM>::Clone(const ITEM *pItem, UINT uCount)
455{
456 MEMBERASSERT();
457
458 // Reallocate the held pointer.
459 if (!Alloc(uCount))
460 return FALSE;
461
462 // Check that we have valid parameters.
463 ARRAYASSERT(pItem, uCount);
464
465 // If this object was only for wrapping primitive types, a memcpy call
466 // would be most efficient for cloning, but this is inappropriate for
467 // arrays of objects.
468 // memcpy(m_pArray, pItem, uCount*sizeof(ITEM));
469
470 // Use a for loop to copy the array into the new buffer.
471 for (UINT i=0; i<uCount; i++)
472 m_pArray[i] = pItem[i];
473
474 m_uCount = uCount;
475 return TRUE;
476}
477
478//================================================================================================
479// FUNCTION: Free
480// PURPOSE: De-allocates the held pointer. Benign NOP if no pointer held.
481//
482template <class ITEM>
483inline void CArrayPtrEx<ITEM>::Free()
484{
485 MEMBERASSERT();
486 delete[] m_pArray;
487 m_pArray = NULL;
488 m_uCount = 0;
489}
490
491//================================================================================================
492// FUNCTION: Get
493// PURPOSE: Returns the held pointer without giving up ownership of it.
494//
495template <class ITEM>
496inline ITEM *CArrayPtrEx<ITEM>::Get() const
497{
498 MEMBERASSERT();
499 return m_pArray;
500}
501
502//================================================================================================
503// FUNCTION: GetCount
504// PURPOSE: Returns the count of items held.
505//
506template <class ITEM>
507inline UINT CArrayPtrEx<ITEM>::GetCount() const
508{
509 MEMBERASSERT();
510 return m_uCount;
511}
512
513//================================================================================================
514// FUNCTION: Set
515// PURPOSE: Destroys the held array and replaces it with another.
516//
517template <class ITEM>
518inline void CArrayPtrEx<ITEM>::Set(ITEM *pItem, UINT uCount)
519{
520 ASSERT_NOTONSTACK(pItem);
521 Free();
522 m_pArray = pItem;
523 m_uCount = uCount;
524}
525
526//================================================================================================
527// FUNCTION: Overloaded cast operator
528// PURPOSE: Returns the held pointer without giving up ownership of it.
529//
530template <class ITEM>
531inline CArrayPtrEx<ITEM>::operator ITEM *() const
532{
533 MEMBERASSERT();
534 return Get();
535}
536
537//================================================================================================
538// FUNCTION: Release
539// PURPOSE: Returns the held pointer, giving up ownership of it.
540//
541template <class ITEM>
542inline ITEM *CArrayPtrEx<ITEM>::Release()
543{
544 MEMBERASSERT();
545 ITEM *rval = m_pArray;
546 m_pArray = NULL;
547 m_uCount = 0;
548 return rval;
549}
550
551//================================================================================================
552// FUNCTION: Zero
553// PURPOSE: Zero's out the held pointer from item 0 for uCount items.
554//
555template <class ITEM>
556inline void CArrayPtrEx<ITEM>::Zero()
557{
558 MEMBERASSERT();
559 ARRAYASSERT(m_pArray, m_uCount);
560 memset(m_pArray, 0, m_uCount*sizeof(ITEM));
561}
562
563//================================================================================================
564// FUNCTION: Sort
565// PURPOSE: Sorts the data held in the pointer according to a user-supplied callback.
566//
567template <class ITEM>
568inline void CArrayPtrEx<ITEM>::Sort(int (__cdecl *FnCompare )(const void *elem1, const void *elem2 ))
569{
570 MEMBERASSERT();
571 ARRAYASSERT(m_pArray, m_uCount);
572 qsort(m_pArray, m_uCount, sizeof(ITEM), FnCompare);
573}
574*/
575#endif // INC_ARRAYPTR_HPP
#define ASSERT_NOTONSTACK(p)
Definition axodebug.h:238
void Free()
Definition ArrayPtr.hpp:204
ITEM * Get() const
Definition ArrayPtr.hpp:215
BOOL Alloc(UINT uCount)
Definition ArrayPtr.hpp:125
int BOOL
Definition unix.h:49
unsigned int UINT
Definition unix.h:47
#define TRUE
Definition unix.h:171