X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/09d27bb4446b4d54605190b9ebcf88a808274f58..594f0f5bf1355fb8d58f403d3ebacc1c1767c429:/include/wx/dynarray.h?ds=sidebyside diff --git a/include/wx/dynarray.h b/include/wx/dynarray.h index 0085620961..7e064dfc0b 100644 --- a/include/wx/dynarray.h +++ b/include/wx/dynarray.h @@ -17,7 +17,6 @@ #endif #include "wx/defs.h" -#include "wx/debug.h" /** @name Dynamic arrays and object arrays (array which own their elements) @memo Arrays which grow on demand and do range checking (only in debug) @@ -43,13 +42,7 @@ callback compare function for quick sort must return negative value, 0 or positive value if pItem1 <, = or > pItem2 */ - -#ifdef __VISUALC__ - #define CMPFUNC_CONV _cdecl -#else // !Visual C++ - #define CMPFUNC_CONV -#endif // compiler -typedef int (CMPFUNC_CONV *CMPFUNC)(const void* pItem1, const void* pItem2); +typedef int (wxCMPFUNC_CONV *CMPFUNC)(const void* pItem1, const void* pItem2); // ---------------------------------------------------------------------------- /** @@ -123,12 +116,14 @@ protected: /** Search the element in the array, starting from the either side @param bFromEnd if TRUE, start from the end - @return index of the first item matched or NOT_FOUND - @see NOT_FOUND + @return index of the first item matched or wxNOT_FOUND + @see wxNOT_FOUND */ int Index(long lItem, bool bFromEnd = FALSE) const; /// search for an item using binary search in a sorted array int Index(long lItem, CMPFUNC fnCompare) const; + /// search for a place to insert the element into a sorted array + size_t IndexForInsert(long lItem, CMPFUNC fnCompare) const; /// add new element at the end void Add(long lItem); /// add item assuming the array is sorted with fnCompare function @@ -138,7 +133,7 @@ protected: /// remove first item matching this value void Remove(long lItem); /// remove item by index - void Remove(size_t uiIndex); + void RemoveAt(size_t uiIndex); //@} /// sort array elements using given compare function @@ -157,22 +152,38 @@ private: // template classes // ============================================================================ +// resolves the name conflict between the wxT() macor and T typedef: we can't +// use wxT() inside WX_DEFINE_ARRAY! +#define _WX_ERROR_SIZEOF wxT("illegal use of DEFINE_ARRAY") +#define _WX_ERROR_REMOVE wxT("removing inexisting element in wxArray::Remove") + // ---------------------------------------------------------------------------- // This macro generates a new array class. It is intended for storage of simple // types of sizeof()<=sizeof(long) or pointers if sizeof(pointer)<=sizeof(long) // // NB: it has only inline functions => takes no space at all +// Mod by JACS: Salford C++ doesn't like 'var->operator=' syntax, as in: +// { ((wxBaseArray *)this)->operator=((const wxBaseArray&)src); +// so using a temporary variable instead. // ---------------------------------------------------------------------------- -#define _WX_DEFINE_ARRAY(T, name) \ +// __MAC_X__ added min ~name() below for compiling Mac X +#define _WX_DEFINE_ARRAY(T, name, classexp) \ typedef int (CMPFUNC_CONV *CMPFUNC##T)(T *pItem1, T *pItem2); \ -class WXDLLEXPORTLOCAL name : public wxBaseArray \ +classexp name : public wxBaseArray \ { \ public: \ name() \ - { wxASSERT( sizeof(T) <= sizeof(long) ); } \ + { \ + size_t type = sizeof(T); \ + size_t sizelong = sizeof(long); \ + if ( type > sizelong ) \ + { wxFAIL_MSG( _WX_ERROR_SIZEOF ); } \ + } \ + ~name() {} \ \ name& operator=(const name& src) \ - { ((wxBaseArray *)this)->operator=((const wxBaseArray&)src); \ + { wxBaseArray* temp = (wxBaseArray*) this; \ + (*temp) = ((const wxBaseArray&)src); \ return *this; } \ \ T& operator[](size_t uiIndex) const \ @@ -190,12 +201,12 @@ public: \ void Insert(T Item, size_t uiIndex) \ { wxBaseArray::Insert((long)Item, uiIndex) ; } \ \ - void Remove(size_t uiIndex) { wxBaseArray::Remove(uiIndex); } \ + void RemoveAt(size_t uiIndex) { wxBaseArray::RemoveAt(uiIndex); } \ void Remove(T Item) \ { int iIndex = Index(Item); \ - wxCHECK2_MSG( iIndex != NOT_FOUND, return, \ - "removing inexisting element in wxArray::Remove" ); \ - wxBaseArray::Remove((size_t)iIndex); } \ + wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \ + _WX_ERROR_REMOVE); \ + wxBaseArray::RemoveAt((size_t)iIndex); } \ \ void Sort(CMPFUNC##T fCmp) { wxBaseArray::Sort((CMPFUNC)fCmp); } \ } @@ -211,22 +222,35 @@ public: \ // 3) it has no Sort() method because it's always sorted // 4) Index() method is much faster (the sorted arrays use binary search // instead of linear one), but Add() is slower. +// 5) there is no Insert() method because you can't insert an item into the +// given position in a sorted array but there is IndexForInsert()/AddAt() +// pair which may be used to optimize a common operation of "insert only if +// not found" // // Summary: use this class when the speed of Index() function is important, use // the normal arrays otherwise. // // NB: it has only inline functions => takes no space at all +// Mod by JACS: Salford C++ doesn't like 'var->operator=' syntax, as in: +// { ((wxBaseArray *)this)->operator=((const wxBaseArray&)src); +// so using a temporary variable instead. // ---------------------------------------------------------------------------- -#define _WX_DEFINE_SORTED_ARRAY(T, name) \ +#define _WX_DEFINE_SORTED_ARRAY(T, name, classexp) \ typedef int (CMPFUNC_CONV *SCMPFUNC##T)(T pItem1, T pItem2); \ -class WXDLLEXPORTLOCAL name : public wxBaseArray \ +classexp name : public wxBaseArray \ { \ public: \ name(SCMPFUNC##T fn) \ - { wxASSERT( sizeof(T) <= sizeof(long) ); m_fnCompare = fn; } \ + { size_t type = sizeof(T); \ + size_t sizelong = sizeof(long); \ + if ( type > sizelong ) \ + { wxFAIL_MSG( _WX_ERROR_SIZEOF ); } \ + m_fnCompare = fn; \ + } \ \ name& operator=(const name& src) \ - { ((wxBaseArray *)this)->operator=((const wxBaseArray&)src); \ + { wxBaseArray* temp = (wxBaseArray*) this; \ + (*temp) = ((const wxBaseArray&)src); \ m_fnCompare = src.m_fnCompare; \ return *this; } \ \ @@ -240,15 +264,22 @@ public: \ int Index(T Item) const \ { return wxBaseArray::Index((long)Item, (CMPFUNC)m_fnCompare); }\ \ + size_t IndexForInsert(T Item) const \ + { return wxBaseArray::IndexForInsert((long)Item, \ + (CMPFUNC)m_fnCompare); } \ + \ + void AddAt(T item, size_t index) \ + { wxBaseArray::Insert((long)item, index); } \ + \ void Add(T Item) \ { wxBaseArray::Add((long)Item, (CMPFUNC)m_fnCompare); } \ \ - void Remove(size_t uiIndex) { wxBaseArray::Remove(uiIndex); } \ + void RemoveAt(size_t uiIndex) { wxBaseArray::RemoveAt(uiIndex); } \ void Remove(T Item) \ { int iIndex = Index(Item); \ - wxCHECK2_MSG( iIndex != NOT_FOUND, return, \ - "removing inexisting element in wxArray::Remove" ); \ - wxBaseArray::Remove((size_t)iIndex); } \ + wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \ + _WX_ERROR_REMOVE ); \ + wxBaseArray::RemoveAt((size_t)iIndex); } \ \ private: \ SCMPFUNC##T m_fnCompare; \ @@ -257,9 +288,9 @@ private: \ // ---------------------------------------------------------------------------- // see WX_DECLARE_OBJARRAY and WX_DEFINE_OBJARRAY // ---------------------------------------------------------------------------- -#define _WX_DECLARE_OBJARRAY(T, name) \ +#define _WX_DECLARE_OBJARRAY(T, name, classexp) \ typedef int (CMPFUNC_CONV *CMPFUNC##T)(T** pItem1, T** pItem2); \ -class WXDLLEXPORTLOCAL name : public wxBaseArray \ +classexp name : public wxBaseArray \ { \ public: \ name() { } \ @@ -285,16 +316,18 @@ public: \ void Insert(const T* pItem, size_t uiIndex) \ { wxBaseArray::Insert((long)pItem, uiIndex); } \ \ - void Empty(); \ + void Empty() { DoEmpty(); wxBaseArray::Empty(); } \ + void Clear() { DoEmpty(); wxBaseArray::Clear(); } \ \ T* Detach(size_t uiIndex) \ { T* p = (T*)wxBaseArray::Item(uiIndex); \ - wxBaseArray::Remove(uiIndex); return p; } \ - void Remove(size_t uiIndex); \ + wxBaseArray::RemoveAt(uiIndex); return p; } \ + void RemoveAt(size_t uiIndex); \ \ void Sort(CMPFUNC##T fCmp) { wxBaseArray::Sort((CMPFUNC)fCmp); } \ \ private: \ + void DoEmpty(); \ void DoCopy(const name& src); \ } @@ -323,15 +356,17 @@ private: \ @memo declare and define array class 'name' containing elements of type 'T' */ -#define WX_DEFINE_ARRAY(T, name) typedef T _A##name; \ - _WX_DEFINE_ARRAY(_A##name, name) +#define WX_DEFINE_ARRAY(T, name) \ + typedef T _A##name; \ + _WX_DEFINE_ARRAY(_A##name, name, class) /** This macro does the same as WX_DEFINE_ARRAY except that the array will be sorted with the specified compare function. */ -#define WX_DEFINE_SORTED_ARRAY(T, name) typedef T _A##name; \ - _WX_DEFINE_SORTED_ARRAY(_A##name, name) +#define WX_DEFINE_SORTED_ARRAY(T, name) \ + typedef T _A##name; \ + _WX_DEFINE_SORTED_ARRAY(_A##name, name, class) /** This macro generates a new objarrays class which owns the objects it @@ -368,8 +403,10 @@ private: \ @memo declare objarray class 'name' containing elements of type 'T' */ -#define WX_DECLARE_OBJARRAY(T, name) typedef T _L##name; \ - _WX_DECLARE_OBJARRAY(_L##name, name) +#define WX_DECLARE_OBJARRAY(T, name) \ + typedef T _L##name; \ + _WX_DECLARE_OBJARRAY(_L##name, name, class) + /** To use an objarray class you must @@ -390,31 +427,50 @@ private: \ #define WX_DEFINE_OBJARRAY(name) "don't forget to include arrimpl.cpp!" //@} +// these macros do the same thing as the WX_XXX ones above, but should be used +// inside the library for user visible classes because otherwise they wouldn't +// be visible from outside (when using wxWindows as DLL under Windows) +#define WX_DEFINE_EXPORTED_ARRAY(T, name) \ + typedef T _A##name; \ + _WX_DEFINE_ARRAY(_A##name, name, class WXDLLEXPORT) + +#define WX_DEFINE_SORTED_EXPORTED_ARRAY(T, name) \ + typedef T _A##name; \ + _WX_DEFINE_SORTED_ARRAY(_A##name, name, class WXDLLEXPORT) + +#define WX_DECLARE_EXPORTED_OBJARRAY(T, name) \ + typedef T _L##name; \ + _WX_DECLARE_OBJARRAY(_L##name, name, class WXDLLEXPORT) + // ---------------------------------------------------------------------------- /** @name Some commonly used predefined arrays */ -// # overhead if not used? // ---------------------------------------------------------------------------- -#define WXDLLEXPORTLOCAL WXDLLEXPORT - //@{ /** @name ArrayInt */ -WX_DEFINE_ARRAY(int, wxArrayInt); +WX_DEFINE_EXPORTED_ARRAY(int, wxArrayInt); /** @name ArrayLong */ -WX_DEFINE_ARRAY(long, wxArrayLong); +WX_DEFINE_EXPORTED_ARRAY(long, wxArrayLong); /** @name ArrayPtrVoid */ -WX_DEFINE_ARRAY(void *, wxArrayPtrVoid); +WX_DEFINE_EXPORTED_ARRAY(void *, wxArrayPtrVoid); //@} //@} -#undef WXDLLEXPORTLOCAL -#define WXDLLEXPORTLOCAL - // ----------------------------------------------------------------------------- -// convinience macros +// convenience macros // ----------------------------------------------------------------------------- +// append all element of one array to another one +#define WX_APPEND_ARRAY(array, other) \ + { \ + size_t count = (other).Count(); \ + for ( size_t n = 0; n < count; n++ ) \ + { \ + (array).Add((other)[n]); \ + } \ + } + // delete all array elements // // NB: the class declaration of the array elements must be visible from the @@ -423,11 +479,14 @@ WX_DEFINE_ARRAY(void *, wxArrayPtrVoid); // count on it)! #define WX_CLEAR_ARRAY(array) \ { \ - size_t count = array.Count(); \ + size_t count = (array).Count(); \ for ( size_t n = 0; n < count; n++ ) \ { \ - delete array[n]; \ + delete (array)[n]; \ } \ + \ + (array).Empty(); \ } + #endif // _DYNARRAY_H