X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6c82a1fd8d02beb023b21d230b97ddce42962b02..28d90b89632d53b16ccb28643b6ac0d46364d422:/src/common/list.cpp diff --git a/src/common/list.cpp b/src/common/list.cpp index 85448991d2..ed3c4a69d6 100644 --- a/src/common/list.cpp +++ b/src/common/list.cpp @@ -5,8 +5,8 @@ // Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Copyright: (c) Julian Smart +// Licence: wxWindows licence //////////////////////////////////////////////////////////////////////////////// // ============================================================================= @@ -16,8 +16,9 @@ // ----------------------------------------------------------------------------- // headers // ----------------------------------------------------------------------------- -#ifdef __GNUG__ -#pragma implementation "list.h" + +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) + #pragma implementation "list.h" #endif // For compilers that support precompilation, includes "wx.h". @@ -34,9 +35,10 @@ #ifndef WX_PRECOMP #include "wx/defs.h" #include "wx/list.h" - #include "wx/utils.h" // for copystring() (beurk...) #endif +#if !wxUSE_STL + // ============================================================================= // implementation // ============================================================================= @@ -44,7 +46,6 @@ // ----------------------------------------------------------------------------- // wxListKey // ----------------------------------------------------------------------------- - wxListKey wxDefaultListKey; bool wxListKey::operator==(wxListKeyValue value) const @@ -52,12 +53,12 @@ bool wxListKey::operator==(wxListKeyValue value) const switch ( m_keyType ) { default: - wxFAIL_MSG("bad key type."); + wxFAIL_MSG(wxT("bad key type.")); // let compiler optimize the line above away in release build // by not putting return here... case wxKEY_STRING: - return strcmp(m_key.string, value.string) == 0; + return wxStrcmp(m_key.string, value.string) == 0; case wxKEY_INTEGER: return m_key.integer == value.integer; @@ -88,11 +89,11 @@ wxNodeBase::wxNodeBase(wxListBase *list, case wxKEY_STRING: // to be free()d later - m_key.string = strdup(key.GetString()); + m_key.string = wxStrdup(key.GetString()); break; default: - wxFAIL_MSG("invalid key type"); + wxFAIL_MSG(wxT("invalid key type")); } if ( previous ) @@ -120,7 +121,7 @@ wxNodeBase::~wxNodeBase() int wxNodeBase::IndexOf() const { - wxCHECK_MSG( m_list, wxNOT_FOUND, "node doesn't belong to a list in IndexOf"); + wxCHECK_MSG( m_list, wxNOT_FOUND, wxT("node doesn't belong to a list in IndexOf")); // It would be more efficient to implement IndexOf() completely inside // wxListBase (only traverse the list once), but this is probably a more @@ -146,7 +147,7 @@ void wxListBase::Init(wxKeyType keyType) m_nodeFirst = m_nodeLast = (wxNodeBase *) NULL; m_count = 0; - m_destroy = FALSE; + m_destroy = false; m_keyType = keyType; } @@ -163,18 +164,48 @@ wxListBase::wxListBase(size_t count, void *elements[]) void wxListBase::DoCopy(const wxListBase& list) { wxASSERT_MSG( !list.m_destroy, - "copying list which owns it's elements is a bad idea" ); + wxT("copying list which owns it's elements is a bad idea") ); - m_count = list.m_count; m_destroy = list.m_destroy; m_keyType = list.m_keyType; m_nodeFirst = m_nodeLast = (wxNodeBase *) NULL; - for ( wxNodeBase *node = list.GetFirst(); node; node = node->GetNext() ) + switch (m_keyType) { - Append(node); + case wxKEY_INTEGER: + { + long key; + for ( wxNodeBase *node = list.GetFirst(); node; node = node->GetNext() ) + { + key = node->GetKeyInteger(); + Append(key, node->GetData()); + } + break; + } + + case wxKEY_STRING: + { + const wxChar *key; + for ( wxNodeBase *node = list.GetFirst(); node; node = node->GetNext() ) + { + key = node->GetKeyString(); + Append(key, node->GetData()); + } + break; + } + + default: + { + for ( wxNodeBase *node = list.GetFirst(); node; node = node->GetNext() ) + { + Append(node->GetData()); + } + break; + } } + + wxASSERT_MSG( m_count == list.m_count, _T("logic error in wxList::DoCopy") ); } wxListBase::~wxListBase() @@ -210,9 +241,12 @@ wxNodeBase *wxListBase::Append(void *object) { // all objects in a keyed list should have a key wxCHECK_MSG( m_keyType == wxKEY_NONE, (wxNodeBase *)NULL, - "need a key for the object to append" ); + wxT("need a key for the object to append") ); - wxNodeBase *node = CreateNode(m_nodeLast, (wxNodeBase *)NULL, object); + // we use wxDefaultListKey even though it is the default parameter value + // because gcc under Mac OS X seems to miscompile this call otherwise + wxNodeBase *node = CreateNode(m_nodeLast, (wxNodeBase *)NULL, object, + wxDefaultListKey); return AppendCommon(node); } @@ -222,18 +256,18 @@ wxNodeBase *wxListBase::Append(long key, void *object) wxCHECK_MSG( (m_keyType == wxKEY_INTEGER) || (m_keyType == wxKEY_NONE && m_count == 0), (wxNodeBase *)NULL, - "can't append object with numeric key to this list" ); + wxT("can't append object with numeric key to this list") ); wxNodeBase *node = CreateNode(m_nodeLast, (wxNodeBase *)NULL, object, key); return AppendCommon(node); } -wxNodeBase *wxListBase::Append (const char *key, void *object) +wxNodeBase *wxListBase::Append (const wxChar *key, void *object) { wxCHECK_MSG( (m_keyType == wxKEY_STRING) || (m_keyType == wxKEY_NONE && m_count == 0), (wxNodeBase *)NULL, - "can't append object with string key to this list" ); + wxT("can't append object with string key to this list") ); wxNodeBase *node = CreateNode(m_nodeLast, (wxNodeBase *)NULL, object, key); return AppendCommon(node); @@ -243,10 +277,10 @@ wxNodeBase *wxListBase::Insert(wxNodeBase *position, void *object) { // all objects in a keyed list should have a key wxCHECK_MSG( m_keyType == wxKEY_NONE, (wxNodeBase *)NULL, - "need a key for the object to insert" ); + wxT("need a key for the object to insert") ); wxCHECK_MSG( !position || position->m_list == this, (wxNodeBase *)NULL, - "can't insert before a node from another list" ); + wxT("can't insert before a node from another list") ); // previous and next node for the node being inserted wxNodeBase *prev, *next; @@ -262,7 +296,8 @@ wxNodeBase *wxListBase::Insert(wxNodeBase *position, void *object) next = m_nodeFirst; } - wxNodeBase *node = CreateNode(prev, next, object); + // wxDefaultListKey: see comment in Append() above + wxNodeBase *node = CreateNode(prev, next, object, wxDefaultListKey); if ( !m_nodeFirst ) { m_nodeLast = node; @@ -288,7 +323,7 @@ wxNodeBase *wxListBase::Item(size_t n) const } } - wxFAIL_MSG( "invalid index in wxListBase::Item" ); + wxFAIL_MSG( wxT("invalid index in wxListBase::Item") ); return (wxNodeBase *)NULL; } @@ -296,7 +331,7 @@ wxNodeBase *wxListBase::Item(size_t n) const wxNodeBase *wxListBase::Find(const wxListKey& key) const { wxASSERT_MSG( m_keyType == key.GetKeyType(), - "this list is not keyed on the type of this key" ); + wxT("this list is not keyed on the type of this key") ); for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() ) { @@ -310,7 +345,7 @@ wxNodeBase *wxListBase::Find(const wxListKey& key) const return (wxNodeBase *)NULL; } -wxNodeBase *wxListBase::Find(void *object) const +wxNodeBase *wxListBase::Find(const void *object) const { for ( wxNodeBase *current = GetFirst(); current; current = current->GetNext() ) { @@ -349,9 +384,9 @@ void wxListBase::DoDeleteNode(wxNodeBase *node) wxNodeBase *wxListBase::DetachNode(wxNodeBase *node) { - wxCHECK_MSG( node, NULL, "detaching NULL wxNodeBase" ); + wxCHECK_MSG( node, NULL, wxT("detaching NULL wxNodeBase") ); wxCHECK_MSG( node->m_list == this, NULL, - "detaching node which is not from this list" ); + wxT("detaching node which is not from this list") ); // update the list wxNodeBase **prevNext = node->GetPrevious() ? &node->GetPrevious()->m_next @@ -373,11 +408,11 @@ wxNodeBase *wxListBase::DetachNode(wxNodeBase *node) bool wxListBase::DeleteNode(wxNodeBase *node) { if ( !DetachNode(node) ) - return FALSE; + return false; DoDeleteNode(node); - return TRUE; + return true; } bool wxListBase::DeleteObject(void *object) @@ -387,12 +422,12 @@ bool wxListBase::DeleteObject(void *object) if ( current->GetData() == object ) { DeleteNode(current); - return TRUE; + return true; } } // not found - return FALSE; + return false; } void wxListBase::Clear() @@ -478,17 +513,21 @@ void wxListBase::Sort(const wxSortCompareFunction compfunc) // go through the list and put the pointers into the array wxNodeBase *node; - for ( node = GetFirst(); node; node = node->Next() ) + for ( node = GetFirst(); node; node = node->GetNext() ) { - *objPtr++ = node->Data(); + *objPtr++ = node->GetData(); } // sort the array - qsort((void *)objArray,num,sizeof(wxObject *),compfunc); + qsort((void *)objArray,num,sizeof(wxObject *), +#ifdef __WXWINCE__ + (int (__cdecl *)(const void *,const void *)) +#endif + compfunc); // put the sorted pointers back into the list objPtr = objArray; - for ( node = GetFirst(); node; node = node->Next() ) + for ( node = GetFirst(); node; node = node->GetNext() ) { node->SetData(*objPtr++); } @@ -497,18 +536,77 @@ void wxListBase::Sort(const wxSortCompareFunction compfunc) delete[] objArray; } +void wxListBase::Reverse() +{ + wxNodeBase* node = m_nodeFirst; + wxNodeBase* tmp; + + while (node) + { + // swap prev and next pointers + tmp = node->m_next; + node->m_next = node->m_previous; + node->m_previous = tmp; + + // this is the node that was next before swapping + node = tmp; + } + + // swap first and last node + tmp = m_nodeFirst; m_nodeFirst = m_nodeLast; m_nodeLast = tmp; +} + +void wxListBase::DeleteNodes(wxNodeBase* first, wxNodeBase* last) +{ + wxNodeBase* node = first; + + while (node != last) + { + wxNodeBase* next = node->GetNext(); + DeleteNode(node); + node = next; + } +} + +// ============================================================================ +// compatibility section from now on +// ============================================================================ + +#ifdef wxLIST_COMPATIBILITY + // ----------------------------------------------------------------------------- // wxList (a.k.a. wxObjectList) // ----------------------------------------------------------------------------- +IMPLEMENT_DYNAMIC_CLASS(wxList, wxObject) + +wxList::wxList( int key_type ) + : wxObjectList( (wxKeyType)key_type ) +{ +} + void wxObjectListNode::DeleteData() { delete (wxObject *)GetData(); } -// ----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxStringList -// ----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +static inline wxChar* MYcopystring(const wxString& s) +{ + wxChar* copy = new wxChar[s.length() + 1]; + return wxStrcpy(copy, s.c_str()); +} + +static inline wxChar* MYcopystring(const wxChar* s) +{ + wxChar* copy = new wxChar[wxStrlen(s) + 1]; + return wxStrcpy(copy, s); +} + +IMPLEMENT_DYNAMIC_CLASS(wxStringList, wxObject) // instead of WX_DEFINE_LIST(wxStringListBase) we define this function // ourselves @@ -517,21 +615,21 @@ void wxStringListNode::DeleteData() delete [] (char *)GetData(); } -bool wxStringList::Delete(const char *s) +bool wxStringList::Delete(const wxChar *s) { wxStringListNode *current; for ( current = GetFirst(); current; current = current->GetNext() ) { - if ( strcmp(current->GetData(), s) == 0 ) + if ( wxStrcmp(current->GetData(), s) == 0 ) { DeleteNode(current); - return TRUE; + return true; } } // not found - return FALSE; + return false; } void wxStringList::DoCopy(const wxStringList& other) @@ -545,25 +643,31 @@ void wxStringList::DoCopy(const wxStringList& other) } } +wxStringList::wxStringList() +{ + DeleteContents(true); +} + // Variable argument list, terminated by a zero // Makes new storage for the strings -wxStringList::wxStringList (const char *first, ...) +wxStringList::wxStringList (const wxChar *first, ...) { + DeleteContents(true); if ( !first ) return; va_list ap; va_start(ap, first); - const char *s = first; + const wxChar *s = first; for (;;) { Add(s); - s = va_arg(ap, const char *); + s = va_arg(ap, const wxChar *); // if (s == NULL) #ifdef __WXMSW__ - if ((int) s == 0) + if ((int)(long) s == 0) #else if ((long) s == 0) #endif @@ -573,16 +677,16 @@ wxStringList::wxStringList (const char *first, ...) va_end(ap); } -// Only makes new strings if arg is TRUE -char **wxStringList::ListToArray(bool new_copies) const +// Only makes new strings if arg is true +wxChar **wxStringList::ListToArray(bool new_copies) const { - char **string_array = new char *[GetCount()]; + wxChar **string_array = new wxChar *[GetCount()]; wxStringListNode *node = GetFirst(); for (size_t i = 0; i < GetCount(); i++) { - char *s = node->GetData(); + wxChar *s = node->GetData(); if ( new_copies ) - string_array[i] = copystring(s); + string_array[i] = MYcopystring(s); else string_array[i] = s; node = node->GetNext(); @@ -592,32 +696,37 @@ char **wxStringList::ListToArray(bool new_copies) const } // Checks whether s is a member of the list -bool wxStringList::Member(const char *s) const +bool wxStringList::Member(const wxChar *s) const { for ( wxStringListNode *node = GetFirst(); node; node = node->GetNext() ) { - const char *s1 = node->GetData(); - if (s == s1 || strcmp (s, s1) == 0) - return TRUE; + const wxChar *s1 = node->GetData(); + if (s == s1 || wxStrcmp (s, s1) == 0) + return true; } - return FALSE; + return false; } -static int +#ifdef __WXWINCE__ +extern "C" int __cdecl +#else +extern "C" int LINKAGEMODE +#endif + wx_comparestrings(const void *arg1, const void *arg2) { - char **s1 = (char **) arg1; - char **s2 = (char **) arg2; + wxChar **s1 = (wxChar **) arg1; + wxChar **s2 = (wxChar **) arg2; - return strcmp (*s1, *s2); + return wxStrcmp (*s1, *s2); } // Sort a list of strings - deallocates old nodes, allocates new void wxStringList::Sort() { size_t N = GetCount(); - char **array = new char *[N]; + wxChar **array = new wxChar *[N]; wxStringListNode *node; size_t i = 0; @@ -626,7 +735,7 @@ void wxStringList::Sort() array[i++] = node->GetData(); } - qsort (array, N, sizeof (char *), wx_comparestrings); + qsort (array, N, sizeof (wxChar *), wx_comparestrings); i = 0; for ( node = GetFirst(); node; node = node->GetNext() ) @@ -635,3 +744,16 @@ void wxStringList::Sort() delete [] array; } +wxNode *wxStringList::Add(const wxChar *s) +{ + return (wxNode *)wxStringListBase::Append(MYcopystring(s)); +} + +wxNode *wxStringList::Prepend(const wxChar *s) +{ + return (wxNode *)wxStringListBase::Insert(MYcopystring(s)); +} + +#endif // wxLIST_COMPATIBILITY + +#endif // !wxUSE_STL