1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/arrimpl.cpp
3 // Purpose:     helper file for implementation of dynamic lists
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     16.10.97
7 // Copyright:   (c) 1997 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 /*****************************************************************************
12  * Purpose: implements methods of "template" class declared in               *
13  *          DECLARE_OBJARRAY macro and which couldn't be implemented inline  *
14  *          (because they need the full definition of type T in scope)       *
15  *                                                                           *
16  * Usage:   1) #include dynarray.h                                           *
17  *          2) WX_DECLARE_OBJARRAY                                           *
18  *          3) #include arrimpl.cpp                                          *
19  *          4) WX_DEFINE_OBJARRAY                                            *
20  *****************************************************************************/
21 
22 // needed to resolve the conflict between global T and macro parameter T
23 
24 #define _WX_ERROR_REMOVE2(x)     wxT("bad index in ") wxT(#x) wxT("::RemoveAt()")
25 
26 // macro implements remaining (not inline) methods of template list
27 // (it's private to this file)
28 #undef  _DEFINE_OBJARRAY
29 #define _DEFINE_OBJARRAY(T, name)                                             \
30 name::~name()                                                                 \
31 {                                                                             \
32   Empty();                                                                    \
33 }                                                                             \
34                                                                               \
35 void name::DoCopy(const name& src)                                            \
36 {                                                                             \
37   for ( size_t ui = 0; ui < src.size(); ui++ )                                \
38     Add(src[ui]);                                                             \
39 }                                                                             \
40                                                                               \
41 name& name::operator=(const name& src)                                        \
42 {                                                                             \
43   Empty();                                                                    \
44   DoCopy(src);                                                                \
45                                                                               \
46   return *this;                                                               \
47 }                                                                             \
48                                                                               \
49 name::name(const name& src) : wxArrayPtrVoid()                                \
50 {                                                                             \
51   DoCopy(src);                                                                \
52 }                                                                             \
53                                                                               \
54 void name::DoEmpty()                                                          \
55 {                                                                             \
56   for ( size_t ui = 0; ui < size(); ui++ )                                    \
57     delete (T*)base_array::operator[](ui);                                    \
58 }                                                                             \
59                                                                               \
60 void name::RemoveAt(size_t uiIndex, size_t nRemove)                           \
61 {                                                                             \
62   wxCHECK_RET( uiIndex < size(), _WX_ERROR_REMOVE2(name) );                   \
63                                                                               \
64   for (size_t i = 0; i < nRemove; i++ )                                       \
65     delete (T*)base_array::operator[](uiIndex + i);                           \
66                                                                               \
67   base_array::erase(begin() + uiIndex, begin() + uiIndex + nRemove);          \
68 }                                                                             \
69                                                                               \
70 void name::Add(const T& item, size_t nInsert)                                 \
71 {                                                                             \
72   if (nInsert == 0)                                                           \
73     return;                                                                   \
74   T* pItem = new T(item);                                                     \
75   size_t nOldSize = size();                                                   \
76   if ( pItem != NULL )                                                        \
77     base_array::insert(end(), nInsert, pItem);                                \
78   for (size_t i = 1; i < nInsert; i++)                                        \
79     base_array::operator[](nOldSize + i) = new T(item);                       \
80 }                                                                             \
81                                                                               \
82 void name::Insert(const T& item, size_t uiIndex, size_t nInsert)              \
83 {                                                                             \
84   if (nInsert == 0)                                                           \
85     return;                                                                   \
86   T* pItem = new T(item);                                                     \
87   if ( pItem != NULL )                                                        \
88     base_array::insert(begin() + uiIndex, nInsert, pItem);                    \
89   for (size_t i = 1; i < nInsert; i++)                                        \
90     base_array::operator[](uiIndex + i) = new T(item);                        \
91 }                                                                             \
92                                                                               \
93 int name::Index(const T& item, bool bFromEnd) const                           \
94 {                                                                             \
95   if ( bFromEnd ) {                                                           \
96     if ( size() > 0 ) {                                                       \
97       size_t ui = size() - 1;                                                 \
98       do {                                                                    \
99         if ( (T*)base_array::operator[](ui) == &item )                        \
100           return static_cast<int>(ui);                                     \
101         ui--;                                                                 \
102       }                                                                       \
103       while ( ui != 0 );                                                      \
104     }                                                                         \
105   }                                                                           \
106   else {                                                                      \
107     for( size_t ui = 0; ui < size(); ui++ ) {                                 \
108       if( (T*)base_array::operator[](ui) == &item )                           \
109         return static_cast<int>(ui);                                       \
110     }                                                                         \
111   }                                                                           \
112                                                                               \
113   return wxNOT_FOUND;                                                         \
114 }
115 
116 // redefine the macro so that now it will generate the class implementation
117 // old value would provoke a compile-time error if this file is not included
118 #undef  WX_DEFINE_OBJARRAY
119 #define WX_DEFINE_OBJARRAY(name) _DEFINE_OBJARRAY(_wxObjArray##name, name)
120