From df5168c427b51f1ab2b3200a5c8f7626b3d24aae Mon Sep 17 00:00:00 2001 From: Mattia Barbon Date: Tue, 8 Jul 2003 19:52:35 +0000 Subject: [PATCH] Added --use-stl to cnfigure, wxUSE_STL to setup0.h Moved wx/datetime.inl contents to wx/datetime.h and removed inline redefinition hack. Implemented STL-like interface on top of wxList/wxArray, when wxUSE_STL=0. Implemented wxList-like and wxArray interfaces on top of std::list and std::vector, when wxUSE_STL=1. Added arrstr.h, moved wxArrayString declaration there; string.h #includes arrstr.h only if WXWIN_COMPATIBILITY_2_4 is enabled. Added WX_CLEAR_HASH_MAP, WX_CLEAR_HASH_TABLE, WX_CLEAR_LIST macros, to clear a wxHashMap, wxHashTable, wxList containing pointers: deletes pointers and makes container zero-sized. When wxUSE_STL=1, wxStringList works like a std::list. Made wxBase compile when wxUSE_STL=1. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21768 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- configure | 51 ++++ configure.in | 7 + docs/latex/wx/arrstrng.tex | 2 +- include/wx/afterstd.h | 19 ++ include/wx/apptrait.h | 1 + include/wx/arrimpl.cpp | 32 +-- include/wx/arrstr.h | 321 +++++++++++++++++++++ include/wx/beforestd.h | 38 +++ include/wx/cmdline.h | 4 +- include/wx/confbase.h | 1 + include/wx/datetime.h | 553 ++++++++++++++++++++++++++++++++++-- include/wx/dir.h | 1 + include/wx/dynarray.h | 338 ++++++++++++++++++++-- include/wx/filefn.h | 7 +- include/wx/filename.h | 5 +- include/wx/filesys.h | 3 +- include/wx/hash.h | 307 +++++++++++++++++++- include/wx/hashmap.h | 14 + include/wx/list.h | 523 ++++++++++++++++++++++++++++++++-- include/wx/listimpl.cpp | 9 + include/wx/log.h | 11 +- include/wx/msw/setup0.h | 9 + include/wx/protocol/http.h | 6 +- include/wx/string.h | 163 +---------- include/wx/textbuf.h | 27 +- include/wx/tokenzr.h | 1 + include/wx/utils.h | 1 + samples/console/console.cpp | 250 +++++++++++++++- setup.h.in | 4 + src/common/appbase.cpp | 4 +- src/common/cmdline.cpp | 27 +- src/common/config.cpp | 8 +- src/common/datetime.cpp | 14 +- src/common/dircmn.cpp | 2 +- src/common/dynarray.cpp | 148 ++++++---- src/common/dynload.cpp | 35 +-- src/common/encconv.cpp | 15 +- src/common/event.cpp | 20 +- src/common/filefn.cpp | 10 +- src/common/filesys.cpp | 8 +- src/common/fs_inet.cpp | 4 +- src/common/fs_mem.cpp | 2 +- src/common/hash.cpp | 3 + src/common/http.cpp | 53 +--- src/common/list.cpp | 36 ++- src/common/log.cpp | 11 + src/common/module.cpp | 12 +- src/common/object.cpp | 3 +- src/common/socket.cpp | 4 +- src/common/string.cpp | 4 + src/common/sysopt.cpp | 1 + src/common/tokenzr.cpp | 1 + src/common/utilscmn.cpp | 10 +- src/common/variant.cpp | 28 +- src/msw/dde.cpp | 83 +++--- src/msw/volume.cpp | 8 +- src/unix/mimetype.cpp | 3 +- 57 files changed, 2731 insertions(+), 534 deletions(-) create mode 100644 include/wx/afterstd.h create mode 100644 include/wx/arrstr.h create mode 100644 include/wx/beforestd.h diff --git a/configure b/configure index 89127a2484..0826106d8b 100755 --- a/configure +++ b/configure @@ -873,6 +873,7 @@ Optional Features: --enable-shared create shared library code --enable-optimise create optimised code --enable-debug same as debug_flag and debug_info + --enable-stl use STL for containers --enable-precomp enable use of precompiled headers (Mac OS X/Darwin) --enable-debug_flag set __WXDEBUG__ flag (recommended for developers!) --enable-debug_info create code with debugging information @@ -1937,6 +1938,7 @@ esac DEBUG_CONFIGURE=0 if test $DEBUG_CONFIGURE = 1; then DEFAULT_wxUSE_UNIVERSAL=no + DEFAULT_wxUSE_STL=no DEFAULT_wxUSE_NANOX=no @@ -2111,6 +2113,7 @@ if test $DEBUG_CONFIGURE = 1; then DEFAULT_wxUSE_MONOLITHIC=yes else DEFAULT_wxUSE_UNIVERSAL=no + DEFAULT_wxUSE_STL=no DEFAULT_wxUSE_NANOX=no @@ -3131,6 +3134,47 @@ echo "${ECHO_T}no" >&6 fi + enablestring= + echo "$as_me:$LINENO: checking for --${enablestring:-enable}-stl" >&5 +echo $ECHO_N "checking for --${enablestring:-enable}-stl... $ECHO_C" >&6 + no_cache=0 + # Check whether --enable-stl or --disable-stl was given. +if test "${enable_stl+set}" = set; then + enableval="$enable_stl" + + if test "$enableval" = yes; then + ac_cv_use_stl='wxUSE_STL=yes' + else + ac_cv_use_stl='wxUSE_STL=no' + fi + +else + + LINE=`grep "wxUSE_STL" ${wx_arg_cache_file}` + if test "x$LINE" != x ; then + eval "DEFAULT_$LINE" + else + no_cache=1 + fi + + ac_cv_use_stl='wxUSE_STL='$DEFAULT_wxUSE_STL + +fi; + + eval "$ac_cv_use_stl" + if test "$no_cache" != 1; then + echo $ac_cv_use_stl >> ${wx_arg_cache_file}.tmp + fi + + if test "$wxUSE_STL" = yes; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + + enablestring= echo "$as_me:$LINENO: checking for --${enablestring:-enable}-precomp" >&5 @@ -29785,6 +29829,13 @@ _ACEOF fi +if test "$wxUSE_STL" = "yes"; then + cat >>confdefs.h <<\_ACEOF +#define wxUSE_STL 1 +_ACEOF + +fi + if test "$wxUSE_APPLE_IEEE" = "yes"; then cat >>confdefs.h <<\_ACEOF #define wxUSE_APPLE_IEEE 1 diff --git a/configure.in b/configure.in index c1dfc7fdc3..c8117f3cdb 100644 --- a/configure.in +++ b/configure.in @@ -330,6 +330,7 @@ dnl usage DEBUG_CONFIGURE=0 if test $DEBUG_CONFIGURE = 1; then DEFAULT_wxUSE_UNIVERSAL=no + DEFAULT_wxUSE_STL=no DEFAULT_wxUSE_NANOX=no @@ -504,6 +505,7 @@ if test $DEBUG_CONFIGURE = 1; then DEFAULT_wxUSE_MONOLITHIC=yes else DEFAULT_wxUSE_UNIVERSAL=no + DEFAULT_wxUSE_STL=no DEFAULT_wxUSE_NANOX=no @@ -744,6 +746,7 @@ dnl --------------------------------------------------------------------------- WX_ARG_ENABLE(shared, [ --enable-shared create shared library code], wxUSE_SHARED) WX_ARG_ENABLE(optimise, [ --enable-optimise create optimised code], wxUSE_OPTIMISE) WX_ARG_ENABLE(debug, [ --enable-debug same as debug_flag and debug_info], wxUSE_DEBUG) +WX_ARG_ENABLE(stl, [ --enable-stl use STL for containers], wxUSE_STL) dnl allow the precompiled header option to be disabled under Mac OS X/Darwin WX_ARG_ENABLE(precomp, [ --enable-precomp enable use of precompiled headers (Mac OS X/Darwin)], wxUSE_PRECOMP) @@ -4148,6 +4151,10 @@ dnl --------------------------------------------------------------------------- dnl Register non-GUI class options for makefiles and setup.h dnl --------------------------------------------------------------------------- +if test "$wxUSE_STL" = "yes"; then + AC_DEFINE(wxUSE_STL) +fi + if test "$wxUSE_APPLE_IEEE" = "yes"; then AC_DEFINE(wxUSE_APPLE_IEEE) fi diff --git a/docs/latex/wx/arrstrng.tex b/docs/latex/wx/arrstrng.tex index 70ec048f43..e79a8fcdd2 100644 --- a/docs/latex/wx/arrstrng.tex +++ b/docs/latex/wx/arrstrng.tex @@ -48,7 +48,7 @@ functions. \wxheading{Include files} - + \wxheading{See also} diff --git a/include/wx/afterstd.h b/include/wx/afterstd.h new file mode 100644 index 0000000000..313c2257a2 --- /dev/null +++ b/include/wx/afterstd.h @@ -0,0 +1,19 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: include/wx/afterstd.h +// Purpose: #include after STL headers +// Author: Vadim Zeitlin +// Modified by: +// Created: 07/07/03 +// RCS-ID: $Id$ +// Copyright: (c) 2003 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +/** + See the comments in beforestd.h. + */ + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + diff --git a/include/wx/apptrait.h b/include/wx/apptrait.h index 8dbcaeeefc..efd605f499 100644 --- a/include/wx/apptrait.h +++ b/include/wx/apptrait.h @@ -19,6 +19,7 @@ class WXDLLEXPORT wxAppTraits; #endif // wxUSE_FONTMAP class WXDLLEXPORT wxLog; class WXDLLEXPORT wxMessageOutput; +class WXDLLEXPORT wxString; // ---------------------------------------------------------------------------- // wxAppTraits: this class defines various configurable aspects of wxApp diff --git a/include/wx/arrimpl.cpp b/include/wx/arrimpl.cpp index cee3933129..d0e3a7f5cd 100644 --- a/include/wx/arrimpl.cpp +++ b/include/wx/arrimpl.cpp @@ -35,7 +35,7 @@ name::~name() \ \ void name::DoCopy(const name& src) \ { \ - for ( size_t ui = 0; ui < src.Count(); ui++ ) \ + for ( size_t ui = 0; ui < src.size(); ui++ ) \ Add(src[ui]); \ } \ \ @@ -54,18 +54,18 @@ name::name(const name& src) : wxArrayPtrVoid() \ \ void name::DoEmpty() \ { \ - for ( size_t ui = 0; ui < Count(); ui++ ) \ - delete (T*)wxBaseArrayPtrVoid::Item(ui); \ + for ( size_t ui = 0; ui < size(); ui++ ) \ + delete (T*)base_array::operator[](ui); \ } \ \ void name::RemoveAt(size_t uiIndex, size_t nRemove) \ { \ - wxCHECK_RET( uiIndex < Count(), _WX_ERROR_REMOVE2(name) ); \ + wxCHECK_RET( uiIndex < size(), _WX_ERROR_REMOVE2(name) ); \ \ for (size_t i = 0; i < nRemove; i++ ) \ - delete (T*)wxBaseArrayPtrVoid::Item(uiIndex + i); \ + delete (T*)base_array::operator[](uiIndex + i); \ \ - wxBaseArrayPtrVoid::RemoveAt(uiIndex, nRemove); \ + base_array::erase(begin() + uiIndex, begin() + uiIndex + nRemove); \ } \ \ void name::Add(const T& item, size_t nInsert) \ @@ -73,11 +73,11 @@ void name::Add(const T& item, size_t nInsert) \ if (nInsert == 0) \ return; \ T* pItem = new T(item); \ - size_t nOldSize = GetCount(); \ + size_t nOldSize = size(); \ if ( pItem != NULL ) \ - wxBaseArrayPtrVoid::Add(pItem, nInsert); \ + base_array::insert(end(), nInsert, pItem); \ for (size_t i = 1; i < nInsert; i++) \ - wxBaseArrayPtrVoid::Item(nOldSize + i) = new T(item); \ + base_array::operator[](nOldSize + i) = new T(item); \ } \ \ void name::Insert(const T& item, size_t uiIndex, size_t nInsert) \ @@ -86,18 +86,18 @@ void name::Insert(const T& item, size_t uiIndex, size_t nInsert) \ return; \ T* pItem = new T(item); \ if ( pItem != NULL ) \ - wxBaseArrayPtrVoid::Insert(pItem, uiIndex, nInsert); \ + base_array::insert(begin() + uiIndex, nInsert, pItem); \ for (size_t i = 1; i < nInsert; i++) \ - wxBaseArrayPtrVoid::Item(uiIndex + i) = new T(item); \ + base_array::operator[](uiIndex + i) = new T(item); \ } \ \ int name::Index(const T& Item, bool bFromEnd) const \ { \ if ( bFromEnd ) { \ - if ( Count() > 0 ) { \ - size_t ui = Count() - 1; \ + if ( size() > 0 ) { \ + size_t ui = size() - 1; \ do { \ - if ( (T*)wxBaseArrayPtrVoid::Item(ui) == &Item ) \ + if ( (T*)base_array::operator[](ui) == &Item ) \ return ui; \ ui--; \ } \ @@ -105,8 +105,8 @@ int name::Index(const T& Item, bool bFromEnd) const \ } \ } \ else { \ - for( size_t ui = 0; ui < Count(); ui++ ) { \ - if( (T*)wxBaseArrayPtrVoid::Item(ui) == &Item ) \ + for( size_t ui = 0; ui < size(); ui++ ) { \ + if( (T*)base_array::operator[](ui) == &Item ) \ return ui; \ } \ } \ diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h new file mode 100644 index 0000000000..9573613632 --- /dev/null +++ b/include/wx/arrstr.h @@ -0,0 +1,321 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: include/wx/arrstr.h +// Purpose: wxArrayString class +// Author: Mattia Barbon and Vadim Zeitlin +// Modified by: +// Created: 07/07/03 +// RCS-ID: $Id$ +// Copyright: (c) 2003 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_ARRSTR_H +#define _WX_ARRSTR_H + +#include "wx/defs.h" +#include "wx/string.h" + +int WXDLLIMPEXP_BASE wxStringSortAscending(wxString*, wxString*); +int WXDLLIMPEXP_BASE wxStringSortDescending(wxString*, wxString*); + +#if wxUSE_STL + +#include "wx/dynarray.h" + +typedef int (*CMPFUNCwxString)(wxString*, wxString*); +WX_DECLARE_EXPORTED_BASEARRAY(wxString, wxBaseArrayStringBase); +WX_DEFINE_EXPORTED_TYPEARRAY(wxString, wxArrayStringBase, + wxBaseArrayStringBase); +_WX_DEFINE_SORTED_TYPEARRAY_2(wxString, wxSortedArrayStringBase, + wxBaseArrayStringBase, = wxStringSortAscending, + class WXDLLIMPEXP_BASE, CMPFUNCwxString); + +class WXDLLIMPEXP_BASE wxArrayString : public wxArrayStringBase +{ +public: + wxArrayString() { } + wxArrayString(const wxArrayString& a) : wxArrayStringBase(a) { } +}; + +class WXDLLIMPEXP_BASE wxSortedArrayString : public wxSortedArrayStringBase +{ +public: + wxSortedArrayString() : wxSortedArrayStringBase(wxStringSortAscending) + { } + wxSortedArrayString(const wxSortedArrayString& array) + : wxSortedArrayStringBase(array) + { } + wxSortedArrayString(const wxArrayString& src) + : wxSortedArrayStringBase(wxStringSortAscending) + { + reserve(src.size()); + + for ( size_t n = 0; n < src.size(); n++ ) + Add(src[n]); + } +}; + +#else // if !wxUSE_STL + +// ---------------------------------------------------------------------------- +// The string array uses it's knowledge of internal structure of the wxString +// class to optimize string storage. Normally, we would store pointers to +// string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is +// sizeof(char *)) we store these pointers instead. The cast to "wxString *" is +// really all we need to turn such pointer into a string! +// +// Of course, it can be called a dirty hack, but we use twice less memory and +// this approach is also more speed efficient, so it's probably worth it. +// +// Usage notes: when a string is added/inserted, a new copy of it is created, +// so the original string may be safely deleted. When a string is retrieved +// from the array (operator[] or Item() method), a reference is returned. +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxArrayString +{ +public: + // type of function used by wxArrayString::Sort() + typedef int (*CompareFunction)(const wxString& first, + const wxString& second); + // type of function used by wxArrayString::Sort(), for compatibility with + // wxArray + typedef int (*CompareFunction2)(wxString* first, + wxString* second); + + // constructors and destructor + // default ctor + wxArrayString() + : m_nSize(0), m_nCount(0), m_pItems(NULL), m_autoSort(FALSE) + { Init(FALSE); } + // if autoSort is TRUE, the array is always sorted (in alphabetical order) + // + // NB: the reason for using int and not bool is that like this we can avoid + // using this ctor for implicit conversions from "const char *" (which + // we'd like to be implicitly converted to wxString instead!) + // + // of course, using explicit would be even better - if all compilers + // supported it... + wxArrayString(int autoSort) + : m_nSize(0), m_nCount(0), m_pItems(NULL), m_autoSort(FALSE) + { Init(autoSort != 0); } + // copy ctor + wxArrayString(const wxArrayString& array); + // assignment operator + wxArrayString& operator=(const wxArrayString& src); + // not virtual, this class should not be derived from + ~wxArrayString(); + + // memory management + // empties the list, but doesn't release memory + void Empty(); + // empties the list and releases memory + void Clear(); + // preallocates memory for given number of items + void Alloc(size_t nCount); + // minimzes the memory usage (by freeing all extra memory) + void Shrink(); + + // simple accessors + // number of elements in the array + size_t GetCount() const { return m_nCount; } + // is it empty? + bool IsEmpty() const { return m_nCount == 0; } + // number of elements in the array (GetCount is preferred API) + size_t Count() const { return m_nCount; } + + // items access (range checking is done in debug version) + // get item at position uiIndex + wxString& Item(size_t nIndex) const + { + wxASSERT_MSG( nIndex < m_nCount, + _T("wxArrayString: index out of bounds") ); + + return *(wxString *)&(m_pItems[nIndex]); + } + + // same as Item() + wxString& operator[](size_t nIndex) const { return Item(nIndex); } + // get last item + wxString& Last() const + { + wxASSERT_MSG( !IsEmpty(), + _T("wxArrayString: index out of bounds") ); + return Item(Count() - 1); + } + +#if WXWIN_COMPATIBILITY_2_4 + // return a wxString[], useful for the controls which + // take one in their ctor. You must delete[] it yourself + // once you are done with it. Will return NULL if the + // ArrayString was empty. + wxString* GetStringArray() const; +#endif + + // item management + // Search the element in the array, starting from the beginning if + // bFromEnd is FALSE or from end otherwise. If bCase, comparison is case + // sensitive (default). Returns index of the first item matched or + // wxNOT_FOUND + int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const; + // add new element at the end (if the array is not sorted), return its + // index + size_t Add(const wxString& str, size_t nInsert = 1); + // add new element at given position + void Insert(const wxString& str, size_t uiIndex, size_t nInsert = 1); + // expand the array to have count elements + void SetCount(size_t count); + // remove first item matching this value + void Remove(const wxChar *sz); + // remove item by index +#if WXWIN_COMPATIBILITY_2_4 + void Remove(size_t nIndex, size_t nRemove = 1) { RemoveAt(nIndex, nRemove); } +#endif + void RemoveAt(size_t nIndex, size_t nRemove = 1); + + // sorting + // sort array elements in alphabetical order (or reversed alphabetical + // order if reverseOrder parameter is TRUE) + void Sort(bool reverseOrder = FALSE); + // sort array elements using specified comparaison function + void Sort(CompareFunction compareFunction); + void Sort(CompareFunction2 compareFunction); + + // comparison + // compare two arrays case sensitively + bool operator==(const wxArrayString& a) const; + // compare two arrays case sensitively + bool operator!=(const wxArrayString& a) const { return !(*this == a); } + + // STL-like interface + typedef wxString value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef int difference_type; + typedef size_t size_type; + + // FIXME: same in dynarray.h + class reverse_iterator + { + typedef wxArrayString name; + typedef name::reference reference; + typedef name::pointer pointer; + typedef reverse_iterator itor; + friend itor operator+(int o, const itor& it); + friend itor operator+(const itor& it, int o); + friend itor operator-(const itor& it, int o); + friend difference_type operator -(const itor& i1, const itor& i2); + public: + pointer m_ptr; + reverse_iterator() : m_ptr(NULL) { } + reverse_iterator(pointer ptr) : m_ptr(ptr) { } + reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } + reference operator*() const { return *m_ptr; } + pointer operator->() const { return m_ptr; } + itor operator++() { --m_ptr; return *this; } + itor operator++(int) + { reverse_iterator tmp = *this; --m_ptr; return tmp; } + itor operator--() { ++m_ptr; return *this; } + itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } + bool operator ==(const itor& it) { return m_ptr == it.m_ptr; } + bool operator !=(const itor& it) { return m_ptr != it.m_ptr; } + }; + + class const_reverse_iterator + { + typedef wxArrayString name; + typedef name::const_reference reference; + typedef name::const_pointer pointer; + typedef const_reverse_iterator itor; + friend itor operator+(int o, const itor& it); + friend itor operator+(const itor& it, int o); + friend itor operator-(const itor& it, int o); + friend difference_type operator -(const itor& i1, const itor& i2); + public: + pointer m_ptr; + const_reverse_iterator() : m_ptr(NULL) { } + const_reverse_iterator(pointer ptr) : m_ptr(ptr) { } + const_reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } + const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { } + reference operator*() const { return *m_ptr; } + pointer operator->() const { return m_ptr; } + itor operator++() { --m_ptr; return *this; } + itor operator++(int) + { itor tmp = *this; --m_ptr; return tmp; } + itor operator--() { ++m_ptr; return *this; } + itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } + bool operator ==(const itor& it) { return m_ptr == it.m_ptr; } + bool operator !=(const itor& it) { return m_ptr != it.m_ptr; } + }; + + void assign(const_iterator first, const_iterator last); + void assign(size_type n, const_reference v) + { clear(); Add(v, n); } + reference back() { return *(end() - 1); } + const_reference back() const { return *(end() - 1); } + iterator begin() { return (wxString *)&(m_pItems[0]); } + const_iterator begin() const { return (wxString *)&(m_pItems[0]); } + size_type capacity() const { return m_nSize; } + void clear() { Clear(); } + bool empty() const { return IsEmpty(); } + iterator end() { return begin() + GetCount(); } + const_iterator end() const { return begin() + GetCount(); } + iterator erase(iterator first, iterator last) + { + size_t idx = first - begin(); + RemoveAt(idx, last - first); + return begin() + idx; + } + iterator erase(iterator it) { return erase(it, it + 1); } + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + void insert(iterator it, size_type n, const_reference v) + { Insert(v, it - begin(), n); } + iterator insert(iterator it, const_reference v = value_type()) + { size_t idx = it - begin(); Insert(v, idx); return begin() + idx; } + void insert(iterator it, const_iterator first, const_iterator last); + size_type max_size() const { return INT_MAX; } + void pop_back() { RemoveAt(GetCount() - 1); } + void push_back(const_reference v) { Add(v); } + reverse_iterator rbegin() { return reverse_iterator(end() - 1); } + const_reverse_iterator rbegin() const; + reverse_iterator rend() { return reverse_iterator(begin() - 1); } + const_reverse_iterator rend() const; + void reserve(size_type n) /* base::reserve*/; + void resize(size_type n, value_type v = value_type()); + size_type size() const { return GetCount(); } + +protected: + void Init(bool autoSort); // common part of all ctors + void Copy(const wxArrayString& src); // copies the contents of another array + +private: + void Grow(size_t nIncrement = 0); // makes array bigger if needed + void Free(); // free all the strings stored + + void DoSort(); // common part of all Sort() variants + + size_t m_nSize, // current size of the array + m_nCount; // current number of elements + + wxChar **m_pItems; // pointer to data + + bool m_autoSort; // if TRUE, keep the array always sorted +}; + +class WXDLLIMPEXP_BASE wxSortedArrayString : public wxArrayString +{ +public: + wxSortedArrayString() : wxArrayString(TRUE) + { } + wxSortedArrayString(const wxArrayString& array) : wxArrayString(TRUE) + { Copy(array); } +}; + +#endif // !wxUSE_STL + +#endif diff --git a/include/wx/beforestd.h b/include/wx/beforestd.h new file mode 100644 index 0000000000..abf6b791e2 --- /dev/null +++ b/include/wx/beforestd.h @@ -0,0 +1,38 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: include/wx/beforestd.h +// Purpose: #include before STL headers +// Author: Vadim Zeitlin +// Modified by: +// Created: 07/07/03 +// RCS-ID: $Id$ +// Copyright: (c) 2003 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +/** + Unfortunately, when compiling at maximum warning level, the standard + headers themselves may generate warnings -- and really lots of them. So + before including them, this header should be included to temporarily + suppress the warnings and after this the header afterstd.h should be + included to enable them back again. + + Note that there are intentionally no inclusion guards in this file, because + it can be included several times. + */ + +#ifdef _MSC_VER + // these warning have to be disabled and not just temporarily disabled + // because they will be given at the end of the compilation of the current + // source -- and there is absolutely nothing we can do about them + + // 'foo': unreferenced inline function has been removed + #pragma warning(disable:4514) + + // 'function' : function not inlined + #pragma warning(disable:4710) + + // 'id': identifier was truncated to 'num' characters in the debug info + #pragma warning(disable:4786) + + #pragma warning(push, 1) +#endif diff --git a/include/wx/cmdline.h b/include/wx/cmdline.h index b7c038fcb0..ccfe008b4e 100644 --- a/include/wx/cmdline.h +++ b/include/wx/cmdline.h @@ -18,10 +18,12 @@ #endif #include "wx/defs.h" -#include "wx/string.h" #if wxUSE_CMDLINE_PARSER +#include "wx/string.h" +#include "wx/arrstr.h" + class WXDLLIMPEXP_BASE wxDateTime; // ---------------------------------------------------------------------------- diff --git a/include/wx/confbase.h b/include/wx/confbase.h index d17b0409e4..503247fd56 100644 --- a/include/wx/confbase.h +++ b/include/wx/confbase.h @@ -20,6 +20,7 @@ #include "wx/defs.h" #include "wx/string.h" +#include "wx/arrstr.h" // ---------------------------------------------------------------------------- // constants diff --git a/include/wx/datetime.h b/include/wx/datetime.h index c5cc700826..21e98adb72 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -30,21 +30,7 @@ class WXDLLIMPEXP_BASE wxDateTime; class WXDLLIMPEXP_BASE wxTimeSpan; class WXDLLIMPEXP_BASE wxDateSpan; -// a hack: don't use inline functions in debug builds - we don't care about -// performances and this only leads to increased rebuild time (because every -// time an inline method is changed, all files including the header must be -// rebuilt) - -// For Mingw32, causes a link error. (VZ: why?) -#if defined( __WXDEBUG__) && !defined(__MINGW32__) && !(defined(_MSC_VER) && wxUSE_ACCESSIBILITY) - #define wxDATETIME_DONT_INLINE - - #undef inline - #define inline -#else - // just in case - #undef wxDATETIME_DONT_INLINE -#endif // Debug +#include "wx/dynarray.h" // not all c-runtimes are based on 1/1/1970 being (time_t) 0 // set this to the corresponding value in seconds 1/1/1970 has on your @@ -1285,8 +1271,6 @@ private: // wxDateTimeArray: array of dates. // ---------------------------------------------------------------------------- -#include "wx/dynarray.h" - WX_DECLARE_USER_EXPORTED_OBJARRAY(wxDateTime, wxDateTimeArray, WXDLLIMPEXP_BASE); // ---------------------------------------------------------------------------- @@ -1362,21 +1346,536 @@ protected: // inline functions implementation // ============================================================================ -// don't include inline functions definitions when we're included from anything -// else than datetime.cpp in debug builds: this minimizes rebuilds if we change -// some inline function and the performance doesn't matter in the debug builds. +// ---------------------------------------------------------------------------- +// private macros +// ---------------------------------------------------------------------------- + +#define MILLISECONDS_PER_DAY 86400000l -#if !defined(wxDATETIME_DONT_INLINE) || defined(wxDEFINE_TIME_CONSTANTS) - #define INCLUDED_FROM_WX_DATETIME_H - #include "wx/datetime.inl" - #undef INCLUDED_FROM_WX_DATETIME_H +// some broken compilers (HP-UX CC) refuse to compile the "normal" version, but +// using a temp variable always might prevent other compilers from optimising +// it away - hence use of this ugly macro +#ifndef __HPUX__ + #define MODIFY_AND_RETURN(op) return wxDateTime(*this).op +#else + #define MODIFY_AND_RETURN(op) wxDateTime dt(*this); dt.op; return dt #endif -// if we defined it to be empty above, restore it now -#ifdef wxDATETIME_DONT_INLINE - #undef inline +// ---------------------------------------------------------------------------- +// wxDateTime construction +// ---------------------------------------------------------------------------- + +inline bool wxDateTime::IsInStdRange() const +{ + return m_time >= 0l && (m_time / TIME_T_FACTOR) < LONG_MAX; +} + +/* static */ +inline wxDateTime wxDateTime::Now() +{ + return wxDateTime(*GetTmNow()); +} + +/* static */ +inline wxDateTime wxDateTime::Today() +{ + struct tm *time = GetTmNow(); + time->tm_hour = 0; + time->tm_min = 0; + time->tm_sec = 0; + + return wxDateTime(*time); +} + +#if (!(defined(__VISAGECPP__) && __IBMCPP__ >= 400)) +inline wxDateTime& wxDateTime::Set(time_t timet) +{ + // assign first to avoid long multiplication overflow! + m_time = timet - WX_TIME_BASE_OFFSET ; + m_time *= TIME_T_FACTOR; + + return *this; +} +#endif + +inline wxDateTime& wxDateTime::SetToCurrent() +{ + *this = Now(); + return *this; +} + +#if (!(defined(__VISAGECPP__) && __IBMCPP__ >= 400)) +inline wxDateTime::wxDateTime(time_t timet) +{ + Set(timet); +} #endif +inline wxDateTime::wxDateTime(const struct tm& tm) +{ + Set(tm); +} + +inline wxDateTime::wxDateTime(const Tm& tm) +{ + Set(tm); +} + +inline wxDateTime::wxDateTime(double jdn) +{ + Set(jdn); +} + +inline wxDateTime& wxDateTime::Set(const Tm& tm) +{ + wxASSERT_MSG( tm.IsValid(), _T("invalid broken down date/time") ); + + return Set(tm.mday, (Month)tm.mon, tm.year, tm.hour, tm.min, tm.sec); +} + +inline wxDateTime::wxDateTime(wxDateTime_t hour, + wxDateTime_t minute, + wxDateTime_t second, + wxDateTime_t millisec) +{ + Set(hour, minute, second, millisec); +} + +inline wxDateTime::wxDateTime(wxDateTime_t day, + Month month, + int year, + wxDateTime_t hour, + wxDateTime_t minute, + wxDateTime_t second, + wxDateTime_t millisec) +{ + Set(day, month, year, hour, minute, second, millisec); +} + +// ---------------------------------------------------------------------------- +// wxDateTime accessors +// ---------------------------------------------------------------------------- + +inline wxLongLong wxDateTime::GetValue() const +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + + return m_time; +} + +inline time_t wxDateTime::GetTicks() const +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + if ( !IsInStdRange() ) + { + return (time_t)-1; + } + + return (time_t)((m_time / (long)TIME_T_FACTOR).GetLo())+WX_TIME_BASE_OFFSET ; +} + +inline bool wxDateTime::SetToLastWeekDay(WeekDay weekday, + Month month, + int year) +{ + return SetToWeekDay(weekday, -1, month, year); +} + +inline wxDateTime wxDateTime::GetWeekDayInSameWeek(WeekDay weekday, + WeekFlags flags) const +{ + MODIFY_AND_RETURN( SetToWeekDayInSameWeek(weekday) ); +} + +inline wxDateTime wxDateTime::GetNextWeekDay(WeekDay weekday) const +{ + MODIFY_AND_RETURN( SetToNextWeekDay(weekday) ); +} + +inline wxDateTime wxDateTime::GetPrevWeekDay(WeekDay weekday) const +{ + MODIFY_AND_RETURN( SetToPrevWeekDay(weekday) ); +} + +inline wxDateTime wxDateTime::GetWeekDay(WeekDay weekday, + int n, + Month month, + int year) const +{ + wxDateTime dt(*this); + + return dt.SetToWeekDay(weekday, n, month, year) ? dt : wxInvalidDateTime; +} + +inline wxDateTime wxDateTime::GetLastWeekDay(WeekDay weekday, + Month month, + int year) +{ + wxDateTime dt(*this); + + return dt.SetToLastWeekDay(weekday, month, year) ? dt : wxInvalidDateTime; +} + +inline wxDateTime wxDateTime::GetWeek(wxDateTime_t numWeek, + WeekDay weekday, + WeekFlags flags) const +{ + wxDateTime dt(*this); + + return dt.SetToTheWeek(numWeek, weekday, flags) ? dt : wxInvalidDateTime; +} + +inline wxDateTime wxDateTime::GetLastMonthDay(Month month, int year) const +{ + MODIFY_AND_RETURN( SetToLastMonthDay(month, year) ); +} + +inline wxDateTime wxDateTime::GetYearDay(wxDateTime_t yday) const +{ + MODIFY_AND_RETURN( SetToYearDay(yday) ); +} + +// ---------------------------------------------------------------------------- +// wxDateTime comparison +// ---------------------------------------------------------------------------- + +inline bool wxDateTime::IsEqualTo(const wxDateTime& datetime) const +{ + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + + return m_time == datetime.m_time; +} + +inline bool wxDateTime::IsEarlierThan(const wxDateTime& datetime) const +{ + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + + return m_time < datetime.m_time; +} + +inline bool wxDateTime::IsLaterThan(const wxDateTime& datetime) const +{ + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + + return m_time > datetime.m_time; +} + +inline bool wxDateTime::IsStrictlyBetween(const wxDateTime& t1, + const wxDateTime& t2) const +{ + // no need for assert, will be checked by the functions we call + return IsLaterThan(t1) && IsEarlierThan(t2); +} + +inline bool wxDateTime::IsBetween(const wxDateTime& t1, + const wxDateTime& t2) const +{ + // no need for assert, will be checked by the functions we call + return IsEqualTo(t1) || IsEqualTo(t2) || IsStrictlyBetween(t1, t2); +} + +inline bool wxDateTime::IsSameDate(const wxDateTime& dt) const +{ + Tm tm1 = GetTm(), + tm2 = dt.GetTm(); + + return tm1.year == tm2.year && + tm1.mon == tm2.mon && + tm1.mday == tm2.mday; +} + +inline bool wxDateTime::IsSameTime(const wxDateTime& dt) const +{ + // notice that we can't do something like this: + // + // m_time % MILLISECONDS_PER_DAY == dt.m_time % MILLISECONDS_PER_DAY + // + // because we have also to deal with (possibly) different DST settings! + Tm tm1 = GetTm(), + tm2 = dt.GetTm(); + + return tm1.hour == tm2.hour && + tm1.min == tm2.min && + tm1.sec == tm2.sec && + tm1.msec == tm2.msec; +} + +inline bool wxDateTime::IsEqualUpTo(const wxDateTime& dt, + const wxTimeSpan& ts) const +{ + return IsBetween(dt.Subtract(ts), dt.Add(ts)); +} + +// ---------------------------------------------------------------------------- +// wxDateTime arithmetics +// ---------------------------------------------------------------------------- + +inline wxDateTime wxDateTime::Add(const wxTimeSpan& diff) const +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + + return wxDateTime(m_time + diff.GetValue()); +} + +inline wxDateTime& wxDateTime::Add(const wxTimeSpan& diff) +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + + m_time += diff.GetValue(); + + return *this; +} + +inline wxDateTime& wxDateTime::operator+=(const wxTimeSpan& diff) +{ + return Add(diff); +} + +inline wxDateTime wxDateTime::Subtract(const wxTimeSpan& diff) const +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + + return wxDateTime(m_time - diff.GetValue()); +} + +inline wxDateTime& wxDateTime::Subtract(const wxTimeSpan& diff) +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + + m_time -= diff.GetValue(); + + return *this; +} + +inline wxDateTime& wxDateTime::operator-=(const wxTimeSpan& diff) +{ + return Subtract(diff); +} + +inline wxTimeSpan wxDateTime::Subtract(const wxDateTime& datetime) const +{ + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + + return wxTimeSpan(GetValue() - datetime.GetValue()); +} + +inline wxDateTime wxDateTime::Add(const wxDateSpan& diff) const +{ + return wxDateTime(*this).Add(diff); +} + +inline wxDateTime& wxDateTime::Subtract(const wxDateSpan& diff) +{ + return Add(diff.Negate()); +} + +inline wxDateTime wxDateTime::Subtract(const wxDateSpan& diff) const +{ + return wxDateTime(*this).Subtract(diff); +} + +inline wxDateTime& wxDateTime::operator-=(const wxDateSpan& diff) +{ + return Subtract(diff); +} + +inline wxDateTime& wxDateTime::operator+=(const wxDateSpan& diff) +{ + return Add(diff); +} + +// ---------------------------------------------------------------------------- +// wxDateTime and timezones +// ---------------------------------------------------------------------------- + +inline wxDateTime wxDateTime::ToTimezone(const wxDateTime::TimeZone& tz, + bool noDST) const +{ + MODIFY_AND_RETURN( MakeTimezone(tz, noDST) ); +} + +// ---------------------------------------------------------------------------- +// wxTimeSpan construction +// ---------------------------------------------------------------------------- + +inline wxTimeSpan::wxTimeSpan(long hours, + long minutes, + long seconds, + long milliseconds) +{ + // assign first to avoid precision loss + m_diff = hours; + m_diff *= 60l; + m_diff += minutes; + m_diff *= 60l; + m_diff += seconds; + m_diff *= 1000l; + m_diff += milliseconds; +} + +// ---------------------------------------------------------------------------- +// wxTimeSpan accessors +// ---------------------------------------------------------------------------- + +inline wxLongLong wxTimeSpan::GetSeconds() const +{ + return m_diff / 1000l; +} + +inline int wxTimeSpan::GetMinutes() const +{ + return (GetSeconds() / 60l).GetLo(); +} + +inline int wxTimeSpan::GetHours() const +{ + return GetMinutes() / 60; +} + +inline int wxTimeSpan::GetDays() const +{ + return GetHours() / 24; +} + +inline int wxTimeSpan::GetWeeks() const +{ + return GetDays() / 7; +} + +// ---------------------------------------------------------------------------- +// wxTimeSpan arithmetics +// ---------------------------------------------------------------------------- + +inline wxTimeSpan wxTimeSpan::Add(const wxTimeSpan& diff) const +{ + return wxTimeSpan(m_diff + diff.GetValue()); +} + +inline wxTimeSpan& wxTimeSpan::Add(const wxTimeSpan& diff) +{ + m_diff += diff.GetValue(); + + return *this; +} + +inline wxTimeSpan wxTimeSpan::Subtract(const wxTimeSpan& diff) const +{ + return wxTimeSpan(m_diff - diff.GetValue()); +} + +inline wxTimeSpan& wxTimeSpan::Subtract(const wxTimeSpan& diff) +{ + m_diff -= diff.GetValue(); + + return *this; +} + +inline wxTimeSpan& wxTimeSpan::Multiply(int n) +{ + m_diff *= (long)n; + + return *this; +} + +inline wxTimeSpan wxTimeSpan::Multiply(int n) const +{ + return wxTimeSpan(m_diff * (long)n); +} + +inline wxTimeSpan wxTimeSpan::Abs() const +{ + return wxTimeSpan(GetValue().Abs()); +} + +inline bool wxTimeSpan::IsEqualTo(const wxTimeSpan& ts) const +{ + return GetValue() == ts.GetValue(); +} + +inline bool wxTimeSpan::IsLongerThan(const wxTimeSpan& ts) const +{ + return GetValue().Abs() > ts.GetValue().Abs(); +} + +// ---------------------------------------------------------------------------- +// wxDateSpan +// ---------------------------------------------------------------------------- + +inline wxDateSpan& wxDateSpan::operator+=(const wxDateSpan& other) +{ + m_years += other.m_years; + m_months += other.m_months; + m_weeks += other.m_weeks; + m_days += other.m_days; + + return *this; +} + +inline wxDateSpan& wxDateSpan::Add(const wxDateSpan& other) +{ + return *this += other; +} + +inline wxDateSpan wxDateSpan::Add(const wxDateSpan& other) const +{ + wxDateSpan ds(*this); + ds.Add(other); + return ds; +} + +inline wxDateSpan& wxDateSpan::Multiply(int factor) +{ + m_years *= factor; + m_months *= factor; + m_weeks *= factor; + m_days *= factor; + + return *this; +} + +inline wxDateSpan wxDateSpan::Multiply(int factor) const +{ + wxDateSpan ds(*this); + ds.Multiply(factor); + return ds; +} + +inline wxDateSpan wxDateSpan::Negate() const +{ + return wxDateSpan(-m_years, -m_months, -m_weeks, -m_days); +} + +inline wxDateSpan& wxDateSpan::Neg() +{ + m_years = -m_years; + m_months = -m_months; + m_weeks = -m_weeks; + m_days = -m_days; + + return *this; +} + +inline wxDateSpan& wxDateSpan::operator-=(const wxDateSpan& other) +{ + return *this += other.Negate(); +} + +inline wxDateSpan& wxDateSpan::Subtract(const wxDateSpan& other) +{ + return *this -= other; +} + +inline wxDateSpan wxDateSpan::Subtract(const wxDateSpan& other) const +{ + wxDateSpan ds(*this); + ds.Subtract(other); + return ds; +} + +#undef MILLISECONDS_PER_DAY + +#undef MODIFY_AND_RETURN + // ============================================================================ // binary operators // ============================================================================ diff --git a/include/wx/dir.h b/include/wx/dir.h index ded205b9cf..7cb355ff5b 100644 --- a/include/wx/dir.h +++ b/include/wx/dir.h @@ -18,6 +18,7 @@ #ifndef WX_PRECOMP #include "wx/string.h" + #include "wx/arrstr.h" #endif // ---------------------------------------------------------------------------- diff --git a/include/wx/dynarray.h b/include/wx/dynarray.h index fbcf446866..b31d5b3b4d 100644 --- a/include/wx/dynarray.h +++ b/include/wx/dynarray.h @@ -12,12 +12,23 @@ #ifndef _DYNARRAY_H #define _DYNARRAY_H -#if defined(__GNUG__) && !defined(__APPLE__) +#if defined(__GNUG__) && !defined(__APPLE__) && \ + !(defined(__MINGW32__) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) #pragma interface "dynarray.h" #endif #include "wx/defs.h" +#if wxUSE_STL + #include "wx/beforestd.h" + #include + #include + #include "wx/afterstd.h" + #if defined(__WXMSW__) && defined(__MINGW32__) + #include "wx/msw/winundef.h" + #endif +#endif + /* This header defines the dynamic arrays and object arrays (i.e. arrays which own their elements). Dynamic means that the arrays grow automatically as @@ -76,6 +87,59 @@ typedef int (wxCMPFUNC_CONV *CMPFUNC)(const void* pItem1, const void* pItem2); // you cast "SomeArray *" as "BaseArray *" and then delete it) // ---------------------------------------------------------------------------- +#if wxUSE_STL + +#define _WX_DECLARE_BASEARRAY(T, name, classexp) \ +classexp name : public std::vector \ +{ \ +public: \ + void Empty() { clear(); } \ + void Clear() { clear(); } \ + void Alloc(size_t uiSize) { reserve(uiSize); } \ + void Shrink(); \ + \ + size_t GetCount() const { return size(); } \ + void SetCount(size_t n, T v = T()) { resize(n, v); } \ + bool IsEmpty() const { return empty(); } \ + size_t Count() const { return size(); } \ + \ + typedef T base_type; \ + \ +protected: \ + T& Item(size_t uiIndex) const \ + { wxASSERT( uiIndex < size() ); return (T&)operator[](uiIndex); } \ + \ + int Index(T e, bool bFromEnd = FALSE) const; \ + int Index(T lItem, CMPFUNC fnCompare) const; \ + size_t IndexForInsert(T lItem, CMPFUNC fnCompare) const; \ + void Add(T lItem, size_t nInsert = 1) \ + { insert(end(), nInsert, lItem); } \ + void Add(T lItem, CMPFUNC fnCompare); \ + void Insert(T lItem, size_t uiIndex, size_t nInsert = 1) \ + { insert(begin() + uiIndex, nInsert, lItem); } \ + void Remove(T lItem); \ + void RemoveAt(size_t uiIndex, size_t nRemove = 1) \ + { erase(begin() + uiIndex, begin() + uiIndex + nRemove); } \ + \ + void Sort(CMPFUNC fCmp) \ + { \ + Predicate p(fCmp); \ + std::sort(begin(), end(), p); \ + } \ +private: \ + class Predicate \ + { \ + typedef CMPFUNC fnc; \ + fnc m_f; \ + public: \ + Predicate(fnc f) : m_f(f) { } \ + bool operator()(const T& i1, const T& i2) \ + { return m_f((T*)&i1, (T*)&i2) < 0; /* const cast */ } \ + }; \ +} + +#else // if !wxUSE_STL + #define _WX_DECLARE_BASEARRAY(T, name, classexp) \ classexp name \ { \ @@ -113,6 +177,47 @@ protected: \ \ void Sort(CMPFUNC fnCompare); \ \ + /* *minimal* STL-ish interface, for derived classes */ \ + typedef T value_type; \ + typedef value_type* iterator; \ + typedef const value_type* const_iterator; \ + typedef value_type& reference; \ + typedef const value_type& const_reference; \ + typedef int difference_type; \ + typedef size_t size_type; \ + \ + void assign(const_iterator first, const_iterator last); \ + void assign(size_type n, const_reference v); \ + size_type capacity() const { return m_nSize; } \ + void clear() { Clear(); } \ + bool empty() const { return IsEmpty(); } \ + iterator erase(iterator first, iterator last) \ + { \ + size_type idx = first - begin(); \ + RemoveAt(idx, last - first); \ + return begin() + idx; \ + } \ + iterator erase(iterator it) { return erase(it, it + 1); } \ + void insert(iterator it, size_type n, const value_type& v) \ + { Insert(v, it - begin(), n); } \ + iterator insert(iterator it, const value_type& v = value_type()) \ + { \ + size_type idx = it - begin(); \ + Insert(v, idx); \ + return begin() + idx; \ + } \ + void insert(iterator it, const_iterator first, const_iterator last);\ + size_type max_size() const { return INT_MAX; } \ + void pop_back() { RemoveAt(size() - 1); } \ + void push_back(const value_type& v) { Add(v); } \ + void reserve(size_type n) { if(n > m_nSize) Realloc(n); } \ + void resize(size_type n, value_type v = value_type()); \ + size_type size() const { return GetCount(); } \ + \ + iterator begin() { return m_pItems; } \ + iterator end() { return m_pItems + m_nCount; } \ + const_iterator begin() const { return m_pItems; } \ + const_iterator end() const { return m_pItems + m_nCount; } \ private: \ void Grow(size_t nIncrement = 0); \ bool Realloc(size_t nSize); \ @@ -123,6 +228,8 @@ private: \ T *m_pItems; \ } +#endif // !wxUSE_STL + // ============================================================================ // The private helper macros containing the core of the array classes // ============================================================================ @@ -144,6 +251,41 @@ private: \ // _WX_DEFINE_TYPEARRAY: array for simple types // ---------------------------------------------------------------------------- +#if wxUSE_STL + +#define _WX_DEFINE_TYPEARRAY(T, name, base, classexp) \ +typedef int (CMPFUNC_CONV *CMPFUNC##T)(T *pItem1, T *pItem2); \ +classexp name : public base \ +{ \ +public: \ + T& operator[](size_t uiIndex) const \ + { return (T&)(base::operator[](uiIndex)); } \ + T& Item(size_t uiIndex) const \ + { return (T&)/*const cast*/base::operator[](uiIndex); } \ + T& Last() const \ + { return Item(Count() - 1); } \ + \ + int Index(T e, bool bFromEnd = FALSE) const \ + { return base::Index(e, bFromEnd); } \ + \ + void Add(T Item, size_t nInsert = 1) \ + { insert(end(), nInsert, Item); } \ + void Insert(T Item, size_t uiIndex, size_t nInsert = 1) \ + { insert(begin() + uiIndex, nInsert, Item); } \ + \ + void RemoveAt(size_t uiIndex, size_t nRemove = 1) \ + { base::RemoveAt(uiIndex, nRemove); } \ + void Remove(T Item) \ + { int iIndex = Index(Item); \ + wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \ + _WX_ERROR_REMOVE); \ + RemoveAt((size_t)iIndex); } \ + \ + void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC)fCmp); } \ +} + +#else // if !wxUSE_STL + #define _WX_DEFINE_TYPEARRAY(T, name, base, classexp) \ wxCOMPILE_TIME_ASSERT2(sizeof(T) <= sizeof(base::base_type), \ TypeTooBigToBeStoredIn##base, \ @@ -161,11 +303,11 @@ public: \ return *this; } \ \ T& operator[](size_t uiIndex) const \ - { return (T&)(base::Item(uiIndex)); } \ + { return (T&)(base::operator[](uiIndex)); } \ T& Item(size_t uiIndex) const \ - { return (T&)(base::Item(uiIndex)); } \ + { return (T&)(base::operator[](uiIndex)); } \ T& Last() const \ - { return (T&)(base::Item(Count() - 1)); } \ + { return (T&)(base::operator[](Count() - 1)); } \ \ int Index(T Item, bool bFromEnd = FALSE) const \ { return base::Index((base_type)Item, bFromEnd); } \ @@ -184,7 +326,129 @@ public: \ base::RemoveAt((size_t)iIndex); } \ \ void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC)fCmp); } \ -} + \ + /* STL-like interface */ \ +private: \ + typedef base::iterator biterator; \ + typedef base::const_iterator bconst_iterator; \ + typedef base::value_type bvalue_type; \ + typedef base::const_reference bconst_reference; \ +public: \ + typedef T value_type; \ + typedef value_type* pointer; \ + typedef const value_type* const_pointer; \ + typedef value_type* iterator; \ + typedef const value_type* const_iterator; \ + typedef value_type& reference; \ + typedef const value_type& const_reference; \ + typedef base::difference_type difference_type; \ + typedef base::size_type size_type; \ + \ + class reverse_iterator \ + { \ + typedef name::reference reference; \ + typedef name::pointer pointer; \ + typedef reverse_iterator itor; \ + friend itor operator+(int o, const itor& it); \ + friend itor operator+(const itor& it, int o); \ + friend itor operator-(const itor& it, int o); \ + friend difference_type operator -(const itor& i1, const itor& i2);\ + public: \ + pointer m_ptr; \ + reverse_iterator() : m_ptr(NULL) { } \ + reverse_iterator(pointer ptr) : m_ptr(ptr) { } \ + reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } \ + reference operator*() const { return *m_ptr; } \ + pointer operator->() const { return m_ptr; } \ + itor operator++() { --m_ptr; return *this; } \ + itor operator++(int) \ + { reverse_iterator tmp = *this; --m_ptr; return tmp; } \ + itor operator--() { ++m_ptr; return *this; } \ + itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } \ + bool operator ==(const itor& it) { return m_ptr == it.m_ptr; } \ + bool operator !=(const itor& it) { return m_ptr != it.m_ptr; } \ + }; \ + \ + class const_reverse_iterator \ + { \ + typedef name::const_reference reference; \ + typedef name::const_pointer pointer; \ + typedef const_reverse_iterator itor; \ + friend itor operator+(int o, const itor& it); \ + friend itor operator+(const itor& it, int o); \ + friend itor operator-(const itor& it, int o); \ + friend difference_type operator -(const itor& i1, const itor& i2);\ + public: \ + pointer m_ptr; \ + const_reverse_iterator() : m_ptr(NULL) { } \ + const_reverse_iterator(pointer ptr) : m_ptr(ptr) { } \ + const_reverse_iterator(const itor& it) : m_ptr(it.m_ptr) { } \ + const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { }\ + reference operator*() const { return *m_ptr; } \ + pointer operator->() const { return m_ptr; } \ + itor operator++() { --m_ptr; return *this; } \ + itor operator++(int) \ + { itor tmp = *this; --m_ptr; return tmp; } \ + itor operator--() { ++m_ptr; return *this; } \ + itor operator--(int) { itor tmp = *this; ++m_ptr; return tmp; } \ + bool operator ==(const itor& it) { return m_ptr == it.m_ptr; } \ + bool operator !=(const itor& it) { return m_ptr != it.m_ptr; } \ + }; \ + \ + void assign(const_iterator first, const_iterator last) \ + { base::assign((bconst_iterator)first, (bconst_iterator)last); } \ + void assign(size_type n, const_reference v) \ + { base::assign(n, (bconst_reference)v); } \ + reference back() { return *(end() - 1); } \ + const_reference back() const { return *(end() - 1); } \ + iterator begin() { return (iterator)base::begin(); } \ + const_iterator begin() const { return (const_iterator)base::begin(); }\ + size_type capacity() const { return base::capacity(); } \ + void clear() { base::clear(); } \ + bool empty() const { return base::empty(); } \ + iterator end() { return (iterator)base::end(); } \ + const_iterator end() const { return (const_iterator)base::end(); } \ + iterator erase(iterator first, iterator last) \ + { return (iterator)base::erase((biterator)first, (biterator)last); }\ + iterator erase(iterator it) \ + { return (iterator)base::erase((biterator)it); } \ + reference front() { return *begin(); } \ + const_reference front() const { return *begin(); } \ + void insert(iterator it, size_type n, const_reference v) \ + { base::insert((biterator)it, n, (bconst_reference)v); } \ + iterator insert(iterator it, const_reference v = value_type()) \ + { return (iterator)base::insert((biterator)it, (bconst_reference)v); }\ + void insert(iterator it, const_iterator first, const_iterator last) \ + { base::insert((biterator)it, (bconst_iterator)first, \ + (bconst_iterator)last); } \ + size_type max_size() const { return base::max_size(); } \ + void pop_back() { base::pop_back(); } \ + void push_back(const_reference v) \ + { base::push_back((bconst_reference)v); } \ + reverse_iterator rbegin() { return reverse_iterator(end() - 1); } \ + const_reverse_iterator rbegin() const; \ + reverse_iterator rend() { return reverse_iterator(begin() - 1); } \ + const_reverse_iterator rend() const; \ + void reserve(size_type n) { base::reserve(n); }; \ + void resize(size_type n, value_type v = value_type()); \ + size_type size() const { return base::size(); } \ +}; \ + \ +inline name::reverse_iterator operator+(int o, const name::reverse_iterator& it) { return it.m_ptr - o; } \ +inline name::reverse_iterator operator+(const name::reverse_iterator& it, int o) { return it.m_ptr - o; } \ +inline name::reverse_iterator operator-(const name::reverse_iterator& it, int o) { return it.m_ptr + o; } \ +inline name::difference_type operator -(const name::reverse_iterator& i1, \ + const name::reverse_iterator& i2) \ + { return i1.m_ptr - i2.m_ptr; } \ + \ +inline name::const_reverse_iterator operator+(int o, const name::const_reverse_iterator& it) { return it.m_ptr - o; } \ +inline name::const_reverse_iterator operator+(const name::const_reverse_iterator& it, int o) { return it.m_ptr - o; } \ +inline name::const_reverse_iterator operator-(const name::const_reverse_iterator& it, int o) { return it.m_ptr + o; } \ +inline name::difference_type operator -(const name::const_reverse_iterator& i1,\ + const name::const_reverse_iterator& i2) \ + { return i1.m_ptr - i2.m_ptr; } \ + +#endif // !wxUSE_STL // ---------------------------------------------------------------------------- // _WX_DEFINE_SORTED_TYPEARRAY: sorted array for simple data types @@ -192,14 +456,17 @@ public: \ // ---------------------------------------------------------------------------- #define _WX_DEFINE_SORTED_TYPEARRAY(T, name, base, defcomp, classexp) \ +typedef int (CMPFUNC_CONV *SCMPFUNC##T)(T pItem1, T pItem2); \ +_WX_DEFINE_SORTED_TYPEARRAY_2(T, name, base, defcomp, classexp, SCMPFUNC##T) + +#define _WX_DEFINE_SORTED_TYPEARRAY_2(T, name, base, defcomp, classexp, comptype)\ wxCOMPILE_TIME_ASSERT2(sizeof(T) <= sizeof(void *), \ TypeTooBigToBeStoredInSorted##base, \ name); \ -typedef int (CMPFUNC_CONV *SCMPFUNC##T)(T pItem1, T pItem2); \ classexp name : public base \ { \ public: \ - name(SCMPFUNC##T fn defcomp) { m_fnCompare = fn; } \ + name(comptype fn defcomp) { m_fnCompare = fn; } \ \ name& operator=(const name& src) \ { base* temp = (base*) this; \ @@ -208,11 +475,11 @@ public: \ return *this; } \ \ T& operator[](size_t uiIndex) const \ - { return (T&)(base::Item(uiIndex)); } \ + { return (T&)(base::operator[](uiIndex)); } \ T& Item(size_t uiIndex) const \ - { return (T&)(base::Item(uiIndex)); } \ + { return (T&)(base::operator[](uiIndex)); } \ T& Last() const \ - { return (T&)(base::Item(Count() - 1)); } \ + { return (T&)(base::operator[](size() - 1)); } \ \ int Index(T Item) const \ { return base::Index(Item, (CMPFUNC)m_fnCompare); } \ @@ -221,32 +488,34 @@ public: \ { return base::IndexForInsert(Item, (CMPFUNC)m_fnCompare); } \ \ void AddAt(T item, size_t index) \ - { base::Insert(item, index); } \ + { base::insert(begin() + index, item); } \ \ void Add(T Item) \ { base::Add(Item, (CMPFUNC)m_fnCompare); } \ \ void RemoveAt(size_t uiIndex, size_t nRemove = 1) \ - { base::RemoveAt(uiIndex, nRemove); } \ + { base::erase(begin() + uiIndex, begin() + uiIndex + nRemove); } \ void Remove(T Item) \ { int iIndex = Index(Item); \ wxCHECK2_MSG( iIndex != wxNOT_FOUND, return, \ _WX_ERROR_REMOVE ); \ - base::RemoveAt((size_t)iIndex); } \ + base::erase(begin() + iIndex); } \ \ private: \ - SCMPFUNC##T m_fnCompare; \ + comptype m_fnCompare; \ } + // ---------------------------------------------------------------------------- // _WX_DECLARE_OBJARRAY: an array for pointers to type T with owning semantics // ---------------------------------------------------------------------------- #define _WX_DECLARE_OBJARRAY(T, name, base, classexp) \ typedef int (CMPFUNC_CONV *CMPFUNC##T)(T **pItem1, T **pItem2); \ -classexp name : public base \ +classexp name : protected base \ { \ typedef int (CMPFUNC_CONV *CMPFUNC##base)(void **pItem1, void **pItem2); \ +typedef base base_array; \ public: \ name() { } \ name(const name& src); \ @@ -254,29 +523,40 @@ public: \ \ ~name(); \ \ + void Alloc(size_t count) { reserve(count); } \ + size_t GetCount() const { return base_array::size(); } \ + size_t size() const { return base_array::size(); } \ + bool IsEmpty() const { return base_array::empty(); } \ + size_t Count() const { return base_array::size(); } \ + void Shrink() { base::Shrink(); } \ + \ T& operator[](size_t uiIndex) const \ - { return *(T*)base::Item(uiIndex); } \ + { return *(T*)base::operator[](uiIndex); } \ T& Item(size_t uiIndex) const \ - { return *(T*)base::Item(uiIndex); } \ + { return *(T*)base::operator[](uiIndex); } \ T& Last() const \ - { return *(T*)(base::Item(Count() - 1)); } \ + { return *(T*)(base::operator[](size() - 1)); } \ \ int Index(const T& Item, bool bFromEnd = FALSE) const; \ \ void Add(const T& Item, size_t nInsert = 1); \ void Add(const T* pItem) \ - { base::Add((T*)pItem); } \ + { base::push_back((T*)pItem); } \ + void push_back(const T* pItem) \ + { base::push_back((T*)pItem); } \ + void push_back(const T& Item) \ + { Add(Item); } \ \ void Insert(const T& Item, size_t uiIndex, size_t nInsert = 1); \ void Insert(const T* pItem, size_t uiIndex) \ - { base::Insert((T*)pItem, uiIndex); } \ + { base::insert(begin() + uiIndex, (T*)pItem); } \ \ - void Empty() { DoEmpty(); base::Empty(); } \ - void Clear() { DoEmpty(); base::Clear(); } \ + void Empty() { DoEmpty(); base::clear(); } \ + void Clear() { DoEmpty(); base::clear(); } \ \ T* Detach(size_t uiIndex) \ - { T* p = (T*)base::Item(uiIndex); \ - base::RemoveAt(uiIndex); return p; } \ + { T* p = (T*)base::operator[](uiIndex); \ + base::erase(begin() + uiIndex); return p; } \ void RemoveAt(size_t uiIndex, size_t nRemove = 1); \ \ void Sort(CMPFUNC##T fCmp) { base::Sort((CMPFUNC##base)fCmp); } \ @@ -337,7 +617,7 @@ private: \ WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, class expdecl) #define WX_DEFINE_TYPEARRAY_WITH_DECL(T, name, base, classdecl) \ - typedef T _wxArray##name; \ + typedef T _wxArray##name; \ _WX_DEFINE_TYPEARRAY(_wxArray##name, name, base, classdecl) // ---------------------------------------------------------------------------- @@ -608,10 +888,10 @@ WX_DEFINE_USER_EXPORTED_ARRAY (void *, wxArrayPtrVoid, class WXDLLIMPEXP_B // append all element of one array to another one #define WX_APPEND_ARRAY(array, other) \ { \ - size_t count = (other).Count(); \ + size_t count = (other).size(); \ for ( size_t n = 0; n < count; n++ ) \ { \ - (array).Add((other)[n]); \ + (array).push_back((other)[n]); \ } \ } @@ -623,13 +903,13 @@ WX_DEFINE_USER_EXPORTED_ARRAY (void *, wxArrayPtrVoid, class WXDLLIMPEXP_B // count on it)! #define WX_CLEAR_ARRAY(array) \ { \ - size_t count = (array).Count(); \ + size_t count = (array).size(); \ for ( size_t n = 0; n < count; n++ ) \ { \ delete (array)[n]; \ } \ \ - (array).Empty(); \ + (array).clear(); \ } #endif // _DYNARRAY_H diff --git a/include/wx/filefn.h b/include/wx/filefn.h index 6b6c285858..3f00a7404f 100644 --- a/include/wx/filefn.h +++ b/include/wx/filefn.h @@ -367,12 +367,13 @@ WXDLLIMPEXP_BASE time_t wxFileModificationTime(const wxString& filename); class WXDLLIMPEXP_BASE wxPathList : public wxStringList { public: + // avoid GCC warning about virtual functions w/o virtual dtor + virtual ~wxPathList() {} + // Adds all paths in environment variable void AddEnvList(const wxString& envVariable); void Add(const wxString& path); - // Avoid compiler warning - wxNode *Add(const wxChar *s) { return wxStringList::Add(s); } // Find the first full path for which the file exists wxString FindValidPath(const wxString& filename); // Find the first full path for which the file exists; ensure it's an @@ -384,7 +385,7 @@ public: bool Member(const wxString& path); private: - DECLARE_DYNAMIC_CLASS(wxPathList) + // DECLARE_DYNAMIC_CLASS(wxPathList) }; #endif diff --git a/include/wx/filename.h b/include/wx/filename.h index cf3bdd91bc..d024415ac2 100644 --- a/include/wx/filename.h +++ b/include/wx/filename.h @@ -18,6 +18,7 @@ #ifndef WX_PRECOMP #include "wx/string.h" + #include "wx/arrstr.h" #endif /* @@ -172,7 +173,7 @@ public: // file tests // is the filename valid at all? - bool IsOk() const { return !m_dirs.IsEmpty() || !m_name.IsEmpty(); } + bool IsOk() const { return m_dirs.size() != 0 || !m_name.IsEmpty(); } // does the file with this name exists? bool FileExists() const; @@ -330,7 +331,7 @@ public: void PrependDir( const wxString &dir ); void InsertDir( int before, const wxString &dir ); void RemoveDir( int pos ); - size_t GetDirCount() const { return m_dirs.GetCount(); } + size_t GetDirCount() const { return m_dirs.size(); } // Other accessors void SetExt( const wxString &ext ) { m_ext = ext; } diff --git a/include/wx/filesys.h b/include/wx/filesys.h index dcb0dc85fc..f763f48579 100644 --- a/include/wx/filesys.h +++ b/include/wx/filesys.h @@ -160,7 +160,8 @@ protected: class WXDLLIMPEXP_BASE wxFileSystem : public wxObject { public: - wxFileSystem() : wxObject() {m_Path = m_LastName = wxEmptyString; m_Handlers.DeleteContents(TRUE); m_FindFileHandler = NULL;} + wxFileSystem() : wxObject() {m_Path = m_LastName = wxEmptyString; m_FindFileHandler = NULL;} + ~wxFileSystem() { WX_CLEAR_LIST(wxList, m_Handlers); } // sets the current location. Every call to OpenFile is // relative to this location. diff --git a/include/wx/hash.h b/include/wx/hash.h index 5ac029b01e..199a619355 100644 --- a/include/wx/hash.h +++ b/include/wx/hash.h @@ -16,8 +16,16 @@ #pragma interface "hash.h" #endif -#include "wx/list.h" -#include "wx/dynarray.h" +#include "wx/defs.h" + +#if !wxUSE_STL + #include "wx/list.h" +#endif +#if WXWIN_COMPATIBILITY_2_4 + #include "wx/dynarray.h" +#endif + +class WXDLLIMPEXP_BASE wxObject; // the default size of the hash #define wxHASH_SIZE_DEFAULT (1000) @@ -34,6 +42,8 @@ // pointers to objects // ---------------------------------------------------------------------------- +#if !wxUSE_STL + class WXDLLIMPEXP_BASE wxHashTableBase : public wxObject { public: @@ -72,6 +82,164 @@ private: DECLARE_NO_COPY_CLASS(wxHashTableBase) }; +#else + +#include "wx/hashmap.h" + +#if !defined(wxENUM_KEY_TYPE_DEFINED) +#define wxENUM_KEY_TYPE_DEFINED + +enum wxKeyType +{ + wxKEY_NONE, + wxKEY_INTEGER, + wxKEY_STRING +}; + +#endif + +union wxHashKeyValue +{ + long integer; + wxChar *string; +}; + +struct WXDLLIMPEXP_BASE wxHashTableHash +{ + wxHashTableHash() { } + wxHashTableHash( wxKeyType keyType ) : m_keyType( keyType ) { } + + wxKeyType m_keyType; + + unsigned long operator ()( const wxHashKeyValue& k ) const + { + if( m_keyType == wxKEY_STRING ) + return wxStringHash::wxCharStringHash( k.string ); + else + return (unsigned long)k.integer; + } +}; + +struct WXDLLIMPEXP_BASE wxHashTableEqual +{ + wxHashTableEqual() { } + wxHashTableEqual( wxKeyType keyType ) : m_keyType( keyType ) { } + + wxKeyType m_keyType; + + bool operator ()( const wxHashKeyValue& k1, const wxHashKeyValue& k2 ) const + { + if( m_keyType == wxKEY_STRING ) + return wxStrcmp( k1.string, k2.string ) == 0; + else + return k1.integer == k2.integer; + } +}; + +WX_DECLARE_EXPORTED_HASH_MAP( wxHashKeyValue, + void*, + wxHashTableHash, + wxHashTableEqual, + wxHashTableBaseBase ); + +class WXDLLIMPEXP_BASE wxHashTableBase +{ +public: + wxHashTableBase( wxKeyType keyType = wxKEY_INTEGER, + size_t size = wxHASH_SIZE_DEFAULT ) + : m_map( size, wxHashTableHash( keyType ), + wxHashTableEqual( keyType ) ), + m_keyType( keyType ) { } + + ~wxHashTableBase() + { + if( m_keyType == wxKEY_STRING ) + { + for( wxHashTableBaseBase::iterator it = m_map.begin(), + en = m_map.end(); + it != en; ) + { + wxChar* tmp = it->first.string; + ++it; + delete[] tmp; // used in operator++ + } + } + } + + size_t GetCount() const { return m_map.size(); } +protected: + void DoPut( long key, void* data ) + { + wxHashKeyValue k; k.integer = key; + m_map[k] = data; + } + + void DoPut( const wxChar* key, void* data ) + { + wxHashKeyValue k; + k.string = new wxChar[wxStrlen(key) + 1]; + wxStrcpy(k.string, key); + m_map[k] = data; + } + + void* DoGet( long key ) const + { + wxHashKeyValue k; k.integer = key; + wxHashTableBaseBase::const_iterator it = m_map.find( k ); + + return it != m_map.end() ? it->second : NULL; + } + + void* DoGet( const wxChar* key ) const + { + wxHashKeyValue k; k.string = (wxChar*)key; + wxHashTableBaseBase::const_iterator it = m_map.find( k ); + + return it != m_map.end() ? it->second : NULL; + } + + void* DoDelete( long key ) + { + wxHashKeyValue k; k.integer = key; + wxHashTableBaseBase::iterator it = m_map.find( k ); + + if( it != m_map.end() ) + { + void* data = it->second; + + m_map.erase( it ); + return data; + } + + return NULL; + } + + void* DoDelete( const wxChar* key ) + { + wxHashKeyValue k; k.string = (wxChar*)key; + wxHashTableBaseBase::iterator it = m_map.find( k ); + + if( it != m_map.end() ) + { + void* data = it->second; + wxChar* k = it->first.string; + + m_map.erase( it ); + delete[] k; + return data; + } + + return NULL; + } + + wxHashTableBaseBase m_map; + wxKeyType m_keyType; +}; + +#endif // !wxUSE_STL + +#if !wxUSE_STL + #if WXWIN_COMPATIBILITY_2_4 // ---------------------------------------------------------------------------- @@ -145,12 +313,110 @@ private: DECLARE_NO_COPY_CLASS(wxStringHashTable) }; -#endif +#endif // WXWIN_COMPATIBILITY_2_4 + +#endif // !wxUSE_STL // ---------------------------------------------------------------------------- // for compatibility only // ---------------------------------------------------------------------------- +#if wxUSE_STL + +class WXDLLIMPEXP_BASE wxHashTable : protected wxHashTableBase +{ + typedef wxHashTableBaseBase hash; +public: + class dummy; + + struct compatibility_iterator + { + hash::iterator m_iter; + hash* m_hash; + + operator bool() const { return m_iter != m_hash->end(); } + bool operator !() const { return m_iter == m_hash->end(); } + compatibility_iterator( hash* li, hash::iterator it ) + : m_iter( it ), m_hash( li ) {} + compatibility_iterator() { } + + dummy* operator->() { return (dummy*)this; } + }; + typedef class compatibility_iterator citer; + + class dummy + { + typedef hash::iterator it; + typedef compatibility_iterator citer; + public: + wxObject* GetData() const + { + citer* i = (citer*)this; + return (wxObject*)i->m_iter->second; + } + citer GetNext() const + { + citer* i = (citer*)this; + it lit = i->m_iter; + return citer( i->m_hash, ++lit ); + } + citer GetPrevious() const + { + citer* i = (citer*)this; + it lit = i->m_iter; + return citer( i->m_hash, ++lit ); + } + void SetData( wxObject* e ) + { + citer* i = (citer*)this; + i->m_iter->second = e; + } + private: + dummy(); + }; +public: + wxHashTable( wxKeyType keyType = wxKEY_INTEGER, + size_t size = wxHASH_SIZE_DEFAULT ) + : wxHashTableBase( keyType, size ) { } + + void Destroy() { Clear(); } + + // key and value are the same + void Put(long value, wxObject *object) { DoPut( value, object ); } + void Put(const wxChar *value, wxObject *object) { DoPut( value, object ); } + + // key and value are the same + wxObject *Get(long value) const { return (wxObject*)DoGet( value ); } + wxObject *Get(const wxChar *value) const { return (wxObject*)DoGet( value ); } + + // Deletes entry and returns data if found + wxObject *Delete(long key) { return (wxObject*)DoGet( key ); } + wxObject *Delete(const wxChar *key) { return (wxObject*)DoGet( key ); } + +#if 0 + // Construct your own integer key from a string, e.g. in case + // you need to combine it with something + long MakeKey(const wxChar *string) const; +#endif + // Way of iterating through whole hash table (e.g. to delete everything) + // Not necessary, of course, if you're only storing pointers to + // objects maintained separately + void BeginFind() { m_iter = citer( &this->m_map, this->m_map.begin() ); } + compatibility_iterator Next() + { + compatibility_iterator it = m_iter; + if( m_iter ) + m_iter = m_iter->GetNext(); + return it; + } + + void Clear() { m_map.clear(); } +private: + compatibility_iterator m_iter; +}; + +#else // if !wxUSE_STL + class WXDLLIMPEXP_BASE wxHashTable : public wxObject { public: @@ -230,6 +496,7 @@ public: // Returns number of nodes size_t GetCount() const { return m_count; } + typedef wxNode* compatibility_iterator; private: size_t m_count; // number of elements in the hashtable bool m_deleteContents; @@ -237,8 +504,30 @@ private: DECLARE_DYNAMIC_CLASS(wxHashTable) }; +#endif + +#if wxUSE_STL + // defines a new type safe hash table which stores the elements of type eltype // in lists of class listclass +#define _WX_DECLARE_HASH(eltype, dummy, hashclass, classexp) \ + classexp hashclass : public wxHashTableBase \ + { \ + public: \ + hashclass(wxKeyType keyType = wxKEY_INTEGER, \ + size_t size = wxHASH_SIZE_DEFAULT) \ + : wxHashTableBase(keyType, size) { } \ + \ + ~hashclass() { Destroy(); } \ + \ + void Destroy() { m_map.clear(); } \ + void Put(long key, eltype *data) { DoPut(key, (void*)data); } \ + eltype *Get(long key) const { return (eltype*)DoGet(key); } \ + eltype *Delete(long key) { return (eltype*)DoDelete(key); } \ + } + +#else // if !wxUSE_STL + #define _WX_DECLARE_HASH(eltype, listclass, hashclass, classexp) \ classexp hashclass : public wxHashTableBase \ { \ @@ -297,6 +586,8 @@ private: } \ } +#endif + // this macro is to be used in the user code #define WX_DECLARE_HASH(el, list, hash) \ _WX_DECLARE_HASH(el, list, hash, class) @@ -315,16 +606,16 @@ private: // place where you use this macro, otherwise the proper destructor may not // be called (a decent compiler should give a warning about it, but don't // count on it)! -#define WX_CLEAR_HASH_TABLE(array) \ +#define WX_CLEAR_HASH_TABLE(hash) \ { \ - (array).BeginFind(); \ - wxNode* it = (array).Next(); \ + (hash).BeginFind(); \ + wxHashTable::compatibility_iterator it = (hash).Next(); \ while( it ) \ { \ delete it->GetData(); \ - it = (array).Next(); \ + it = (hash).Next(); \ } \ - (array).Clear(); \ + (hash).Clear(); \ } #endif diff --git a/include/wx/hashmap.h b/include/wx/hashmap.h index 621bd6c528..554030a564 100644 --- a/include/wx/hashmap.h +++ b/include/wx/hashmap.h @@ -563,5 +563,19 @@ public: \ _WX_DECLARE_HASH_MAP( void*, VALUE_T, wxPointerHash, wxPointerEqual, \ CLASSNAME, class WXDLLEXPORT ) +// delete all hash elements +// +// NB: the class declaration of the hash elements must be visible from the +// place where you use this macro, otherwise the proper destructor may not +// be called (a decent compiler should give a warning about it, but don't +// count on it)! +#define WX_CLEAR_HASH_MAP(type, hashmap) \ + { \ + type##::iterator it, en; \ + for( it = (hashmap).begin(), en = (hashmap).end(); it != en; ++it ) \ + delete it->second; \ + (hashmap).clear(); \ + } + #endif // _WX_HASHMAP_H_ diff --git a/include/wx/list.h b/include/wx/list.h index e3c8284fb6..56c3a67430 100644 --- a/include/wx/list.h +++ b/include/wx/list.h @@ -25,7 +25,8 @@ #ifndef _WX_LISTH__ #define _WX_LISTH__ -#if defined(__GNUG__) && !defined(__APPLE__) +#if defined(__GNUG__) && !defined(__APPLE__) && \ + !(defined(__MINGW32__) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) #pragma interface "list.h" #endif @@ -37,15 +38,40 @@ #include "wx/object.h" #include "wx/string.h" +#if wxUSE_STL + #include "wx/beforestd.h" + #include + #include "wx/afterstd.h" + #if defined(__WXMSW__) && defined(__MINGW32__) + #include "wx/msw/winundef.h" + #endif +#endif + +// ---------------------------------------------------------------------------- +// types +// ---------------------------------------------------------------------------- + +// type of compare function for list sort operation (as in 'qsort'): it should +// return a negative value, 0 or positive value if the first element is less +// than, equal or greater than the second +extern "C" +{ +typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2); +} + class WXDLLIMPEXP_BASE wxObjectListNode; typedef wxObjectListNode wxNode; -// undef it to get rid of old, deprecated functions -#define wxLIST_COMPATIBILITY +// +typedef int (* LINKAGEMODE wxListIterateFunction)(void *current); -// ----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // constants -// ----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +#if !defined(wxENUM_KEY_TYPE_DEFINED) +#define wxENUM_KEY_TYPE_DEFINED + enum wxKeyType { wxKEY_NONE, @@ -53,20 +79,162 @@ enum wxKeyType wxKEY_STRING }; -// ----------------------------------------------------------------------------- -// types -// ----------------------------------------------------------------------------- +#endif -// type of compare function for list sort operation (as in 'qsort'): it should -// return a negative value, 0 or positive value if the first element is less -// than, equal or greater than the second -extern "C" -{ -typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2); -} +#if wxUSE_STL -// -typedef int (* LINKAGEMODE wxListIterateFunction)(void *current); +#define wxLIST_COMPATIBILITY + +#define WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl) \ + WX_DECLARE_LIST_X(elT, liT, decl) + +#define WX_DECLARE_LIST_2(elT, liT, dummy, decl) \ + WX_DECLARE_LIST_X(elT, liT, decl) + +#define WX_DECLARE_LIST_X(elT, liT, decl) \ + WX_DECLARE_LIST_XO(elT*, liT, decl) + +#define WX_DECLARE_LIST_XO(elT, liT, decl) \ + decl liT : public std::list \ + { \ + public: \ + class dummy; \ + \ + struct compatibility_iterator \ + { \ + typedef std::list::iterator iterator; \ + iterator m_iter; \ + liT * m_list; \ + public: \ + operator bool() const \ + { return m_list && m_iter != m_list->end(); } \ + bool operator !() const \ + { return !m_list || m_iter == m_list->end(); } \ + compatibility_iterator( const liT* li, iterator it ) \ + : m_iter( it ), m_list( (liT*)li ) {} \ + compatibility_iterator( liT* li, iterator it ) \ + : m_iter( it ), m_list( li ) {} \ + compatibility_iterator() : m_list( NULL ) { } \ + dummy* operator->() { return (dummy*)this; } \ + const dummy* operator->() const { return (const dummy*)this; } \ + }; \ + typedef struct compatibility_iterator citer; \ + \ + class dummy \ + { \ + typedef std::list::iterator it; \ + typedef compatibility_iterator citer; \ + public: \ + elT GetData() const \ + { \ + citer* i = (citer*)this; \ + return *(i->m_iter); \ + } \ + citer GetNext() const \ + { \ + citer* i = (citer*)this; \ + it lit = i->m_iter; \ + return citer( i->m_list, ++lit ); \ + } \ + citer GetPrevious() const \ + { \ + citer* i = (citer*)this; \ + it lit = i->m_iter; \ + return citer( i->m_list, ++lit ); \ + } \ + void SetData( elT e ) \ + { \ + citer* i = (citer*)this; \ + *(i->m_iter) = e; \ + } \ + private: \ + dummy(); \ + }; \ + protected: \ + iterator find( elT e ) \ + { \ + iterator it, en; \ + for( it = begin(), en = end(); it != en; ++it ) \ + if( *it == e ) \ + return it; \ + return it; \ + } \ + public: \ + liT() {}; \ + \ + citer Append( elT e ) { push_back( e ); return GetLast(); } \ + void Clear() { clear(); } \ + size_t GetCount() const { return size(); } \ + citer GetFirst() const { return citer( this, ((liT*)this)->begin() ); } \ + citer GetLast() const { return citer( this, --(((liT*)this)->end()) ); } \ + bool IsEmpty() const { return empty(); } \ + bool DeleteObject( elT e ) \ + { \ + iterator it = find( e ); \ + if( it != end() ) \ + { \ + erase( it ); \ + return true; \ + } \ + return false; \ + } \ + void Erase( const compatibility_iterator& it ) \ + { \ + erase( it.m_iter ); \ + } \ + citer Find( elT e ) const { return citer( this, ((liT*)this)->find( e ) ); } \ + citer Member( elT e ) const { return Find( e ); } \ + citer Insert( elT e ) \ + { push_front( e ); return citer( this, begin() ); } \ + citer Insert( size_t idx, elT e ) \ + { return Insert( Item( idx ), e ); } \ + citer Insert( citer idx, elT e ) \ + { return citer( this, insert( idx.m_iter, e ) ); } \ + citer Item( size_t idx ) const \ + { \ + iterator it; \ + for( it = ((liT*)this)->begin(); idx; --idx ) \ + ++it; \ + return citer( this, it ); \ + } \ + int IndexOf( elT e ) const \ + { \ + const_iterator it, en; \ + int idx; \ + for( idx = 0, it = begin(), en = end(); it != en; ++it, ++idx ) \ + if( *it == e ) \ + return idx; \ + return wxNOT_FOUND; \ + } \ + } + +#define WX_DECLARE_LIST(elementtype, listname) \ + WX_DECLARE_LIST_X(elementtype, listname, class) + +#define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \ + WX_DECLARE_LIST_X(elementtype, listname, class WXDLLEXPORT) + +#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \ + WX_DECLARE_LIST_X(elementtype, listname, class usergoo) + +// this macro must be inserted in your program after +// #include +#define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!" + +#define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name) +#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name) + +#else // if !wxUSE_STL + +// due to circular header dependencies this function has to be declared here +// (normally it's found in utils.h which includes itself list.h...) +extern WXDLLEXPORT wxChar* copystring(const wxChar *s); + +class WXDLLEXPORT wxObjectListNode; +typedef wxObjectListNode wxNode; + +// undef it to get rid of old, deprecated functions +#define wxLIST_COMPATIBILITY // ----------------------------------------------------------------------------- // key stuff: a list may be optionally keyed on integer or string key @@ -169,7 +337,9 @@ protected: int IndexOf() const; virtual void DeleteData() { } - +public: + // for wxList::iterator + void** GetDataPtr() const { return &(((wxNodeBase*)this)->m_data); } private: // optional key stuff wxListKeyValue m_key; @@ -330,6 +500,10 @@ protected: void ForEach(wxListIterateFunction func); void *LastThat(wxListIterateFunction func); + // for STL interface, "last" points to one after the last node + // of the controlled sequence (NULL for the end of the list) + void Reverse(); + void DeleteNodes(wxNodeBase* first, wxNodeBase* last); private: // helpers // common part of copy ctor and assignment operator @@ -404,6 +578,7 @@ private: { \ public: \ typedef nodetype Node; \ + typedef Node* compatibility_iterator; \ \ name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \ { } \ @@ -447,6 +622,8 @@ private: { return wxListBase::DeleteNode(node); } \ bool DeleteObject(Tbase *object) \ { return wxListBase::DeleteObject(object); } \ + void Erase(compatibility_iterator it) \ + { DeleteNode(it); } \ \ nodetype *Find(Tbase *object) const \ { return (nodetype *)wxListBase::Find(object); } \ @@ -469,6 +646,275 @@ private: (nodetype *)prev, (nodetype *)next, \ (T *)data, key); \ } \ + /* STL interface */ \ + public: \ + typedef size_t size_type; \ + typedef int difference_type; \ + typedef T* value_type; \ + typedef Tbase* base_value_type; \ + typedef value_type& reference; \ + typedef const value_type& const_reference; \ + typedef base_value_type& base_reference; \ + typedef const base_value_type& const_base_reference; \ + \ + class iterator \ + { \ + typedef name list; \ + public: \ + typedef list::Node Node; \ + typedef iterator itor; \ + typedef list::value_type* ptr_type; \ + \ + Node* m_node; \ + Node* m_init; \ + public: \ + typedef list::reference reference_type; \ + typedef ptr_type pointer_type; \ + \ + iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\ + iterator() : m_node(NULL), m_init(NULL) { } \ + reference_type operator*() const \ + { return *(pointer_type)m_node->GetDataPtr(); } \ + pointer_type operator->() const \ + { return (pointer_type)m_node->GetDataPtr(); } \ + itor& operator++() { m_node = m_node->GetNext(); return *this; }\ + itor operator++(int) \ + { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\ + itor& operator--() \ + { \ + m_node = m_node ? m_node->GetPrevious() : m_init; \ + return *this; \ + } \ + itor operator--(int) \ + { \ + itor tmp = *this; \ + m_node = m_node ? m_node->GetPrevious() : m_init; \ + return tmp; \ + } \ + bool operator!=(const itor& it) const \ + { return it.m_node != m_node; } \ + bool operator==(const itor& it) const \ + { return it.m_node == m_node; } \ + }; \ + class const_iterator \ + { \ + typedef name list; \ + public: \ + typedef list::Node Node; \ + typedef const_iterator itor; \ + typedef list::value_type* ptr_type; \ + \ + Node* m_node; \ + Node* m_init; \ + public: \ + typedef list::const_reference reference_type; \ + typedef const ptr_type pointer_type; \ + \ + const_iterator(Node* node, Node* init) \ + : m_node(node), m_init(init) { } \ + const_iterator() : m_node(NULL), m_init(NULL) { } \ + const_iterator(const iterator& it) \ + : m_node(it.m_node), m_init(it.m_init) { } \ + reference_type operator*() const \ + { return *(pointer_type)m_node->GetDataPtr(); } \ + pointer_type operator->() const \ + { return (pointer_type)m_node->GetDataPtr(); } \ + itor& operator++() { m_node = m_node->GetNext(); return *this; }\ + itor operator++(int) \ + { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\ + itor& operator--() \ + { \ + m_node = m_node ? m_node->GetPrevious() : m_init; \ + return *this; \ + } \ + itor operator--(int) \ + { \ + itor tmp = *this; \ + m_node = m_node ? m_node->GetPrevious() : m_init; \ + return tmp; \ + } \ + bool operator!=(const itor& it) const \ + { return it.m_node != m_node; } \ + bool operator==(const itor& it) const \ + { return it.m_node == m_node; } \ + }; \ + class reverse_iterator \ + { \ + typedef name list; \ + public: \ + typedef list::Node Node; \ + typedef reverse_iterator itor; \ + typedef list::value_type* ptr_type; \ + \ + Node* m_node; \ + Node* m_init; \ + public: \ + typedef list::reference reference_type; \ + typedef ptr_type pointer_type; \ + \ + reverse_iterator(Node* node, Node* init) \ + : m_node(node), m_init(init) { } \ + reverse_iterator() : m_node(NULL), m_init(NULL) { } \ + reference_type operator*() const \ + { return *(pointer_type)m_node->GetDataPtr(); } \ + pointer_type operator->() const \ + { return (pointer_type)m_node->GetDataPtr(); } \ + itor& operator++() \ + { m_node = m_node->GetPrevious(); return *this; } \ + itor operator++(int) \ + { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\ + itor& operator--() \ + { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \ + itor operator--(int) \ + { \ + itor tmp = *this; \ + m_node = m_node ? m_node->GetNext() : m_init; \ + return tmp; \ + } \ + bool operator!=(const itor& it) const \ + { return it.m_node != m_node; } \ + bool operator==(const itor& it) const \ + { return it.m_node == m_node; } \ + }; \ + class const_reverse_iterator \ + { \ + typedef name list; \ + public: \ + typedef list::Node Node; \ + typedef const_reverse_iterator itor; \ + typedef list::value_type* ptr_type; \ + \ + Node* m_node; \ + Node* m_init; \ + public: \ + typedef list::const_reference reference_type; \ + typedef const ptr_type pointer_type; \ + \ + const_reverse_iterator(Node* node, Node* init) \ + : m_node(node), m_init(init) { } \ + const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \ + const_reverse_iterator(const reverse_iterator& it) \ + : m_node(it.m_node), m_init(it.m_init) { } \ + reference_type operator*() const \ + { return *(pointer_type)m_node->GetDataPtr(); } \ + pointer_type operator->() const \ + { return (pointer_type)m_node->GetDataPtr(); } \ + itor& operator++() \ + { m_node = m_node->GetPrevious(); return *this; } \ + itor operator++(int) \ + { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\ + itor& operator--() \ + { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\ + itor operator--(int) \ + { \ + itor tmp = *this; \ + m_node = m_node ? m_node->GetNext() : m_init; \ + return tmp; \ + } \ + bool operator!=(const itor& it) const \ + { return it.m_node != m_node; } \ + bool operator==(const itor& it) const \ + { return it.m_node == m_node; } \ + }; \ + \ + wxEXPLICIT name(size_type n, const_reference v = value_type()) \ + { assign(n, v); } \ + name(const_iterator first, const_iterator last) \ + { assign(first, last); } \ + iterator begin() { return iterator(GetFirst(), GetLast()); } \ + const_iterator begin() const \ + { return const_iterator(GetFirst(), GetLast()); } \ + iterator end() { return iterator(NULL, GetLast()); } \ + const_iterator end() const { return const_iterator(NULL, GetLast()); }\ + reverse_iterator rbegin() \ + { return reverse_iterator(GetLast(), GetFirst()); } \ + const_reverse_iterator rbegin() const \ + { return const_reverse_iterator(GetLast(), GetFirst()); } \ + reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\ + const_reverse_iterator rend() const \ + { return const_reverse_iterator(NULL, GetFirst()); } \ + void resize(size_type n, value_type v = value_type()) \ + { \ + if(n < size()) \ + for(; n < size(); pop_back()); \ + else if(n > size()) \ + for(; n > size(); push_back(v)); \ + } \ + size_type size() const { return GetCount(); } \ + size_type max_size() const { return INT_MAX; } \ + bool empty() const { return IsEmpty(); } \ + reference front() { return *begin(); } \ + const_reference front() const { return *begin(); } \ + reference back() { return *--end(); } \ + const_reference back() const { return *--end(); } \ + void push_front(const_reference v = value_type()) \ + { Insert(GetFirst(), (const_base_reference)v); } \ + void pop_front() { DeleteNode(GetFirst()); } \ + void push_back(const_reference v = value_type()) \ + { Append((const_base_reference)v); } \ + void pop_back() { DeleteNode(GetLast()); } \ + void assign(const_iterator first, const_iterator last) \ + { \ + clear(); \ + for(; first != last; ++first) \ + Append((const_base_reference)*first); \ + } \ + void assign(size_type n, const_reference v = value_type()) \ + { \ + clear(); \ + for(size_type i = 0; i < n; ++i) \ + Append((const_base_reference)v); \ + } \ + iterator insert(iterator it, const_reference v = value_type()) \ + { \ + Insert(it.m_node, (const_base_reference)v); \ + return iterator(it.m_node->GetPrevious(), GetLast()); \ + } \ + void insert(iterator it, size_type n, const_reference v = value_type())\ + { \ + for(size_type i = 0; i < n; ++i) \ + Insert(it.m_node, (const_base_reference)v); \ + } \ + void insert(iterator it, const_iterator first, const_iterator last) \ + { \ + for(; first != last; ++first) \ + Insert(it.m_node, (const_base_reference)*first); \ + } \ + iterator erase(iterator it) \ + { \ + iterator next = iterator(it.m_node->GetNext(), GetLast()); \ + DeleteNode(it.m_node); return next; \ + } \ + iterator erase(iterator first, iterator last) \ + { \ + iterator next = last; ++next; \ + DeleteNodes(first.m_node, last.m_node); \ + return next; \ + } \ + void clear() { Clear(); } \ + void splice(iterator it, name& l, iterator first, iterator last) \ + { insert(it, first, last); l.erase(first, last); } \ + void splice(iterator it, name& l) \ + { splice(it, l, l.begin(), l.end() ); } \ + void splice(iterator it, name& l, iterator first) \ + { \ + iterator tmp = first; ++tmp; \ + if(it == first || it == tmp) return; \ + insert(it, *first); \ + l.erase(first); \ + } \ + void remove(const_reference v) \ + { DeleteObject((const_base_reference)v); } \ + void reverse() \ + { Reverse(); } \ + /* void swap(name& l) \ + { \ + { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \ + { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\ + { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\ + { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\ + { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\ + } */ \ } #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \ @@ -493,6 +939,7 @@ private: #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name) #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name) +#endif // !wxUSE_STL // ============================================================================= // now we can define classes 100% compatible with the old ones @@ -510,37 +957,44 @@ private: // ----------------------------------------------------------------------------- // wxList compatibility class: in fact, it's a list of wxObjects // ----------------------------------------------------------------------------- - WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode, class WXDLLIMPEXP_BASE); class WXDLLIMPEXP_BASE wxList : public wxObjectList { public: -#ifdef wxWARN_COMPAT_LIST_USE +#if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL wxDEPRECATED( wxList(int key_type = wxKEY_NONE) ); -#else +#elif !wxUSE_STL wxList(int key_type = wxKEY_NONE); #endif // this destructor is required for Darwin ~wxList() { } +#if !wxUSE_STL wxList& operator=(const wxList& list) { (void) wxListBase::operator=(list); return *this; } // compatibility methods void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); } +#endif +#if wxUSE_STL +#else wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); } +#endif private: +#if !wxUSE_STL DECLARE_DYNAMIC_CLASS(wxList) +#endif }; +#if !wxUSE_STL + // ----------------------------------------------------------------------------- // wxStringList class for compatibility with the old code // ----------------------------------------------------------------------------- - WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE); class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase @@ -583,7 +1037,32 @@ private: DECLARE_DYNAMIC_CLASS(wxStringList) }; +#else // if wxUSE_STL + +WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLEXPORT); + +class WXDLLEXPORT wxStringList : public wxStringListBase +{ +public: +}; + +#endif // wxUSE_STL + #endif // wxLIST_COMPATIBILITY +// delete all list elements +// +// NB: the class declaration of the list elements must be visible from the +// place where you use this macro, otherwise the proper destructor may not +// be called (a decent compiler should give a warning about it, but don't +// count on it)! +#define WX_CLEAR_LIST(type, list) \ + { \ + type::iterator it, en; \ + for( it = (list).begin(), en = (list).end(); it != en; ++it ) \ + delete *it; \ + (list).clear(); \ + } + #endif // _WX_LISTH__ diff --git a/include/wx/listimpl.cpp b/include/wx/listimpl.cpp index 3beb66103d..eeab9cf2b0 100644 --- a/include/wx/listimpl.cpp +++ b/include/wx/listimpl.cpp @@ -9,6 +9,13 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +#if wxUSE_STL + +#undef WX_DEFINE_LIST +#define WX_DEFINE_LIST(name) + +#else // if !wxUSE_STL + #define _DEFINE_LIST(T, name) \ void wx##name##Node::DeleteData() \ { \ @@ -22,3 +29,5 @@ // don't pollute preprocessor's name space //#undef _DEFINE_LIST + +#endif diff --git a/include/wx/log.h b/include/wx/log.h index f57a0ddb55..472d6776a8 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -16,10 +16,13 @@ #pragma interface "log.h" #endif -#include "wx/string.h" +#include "wx/defs.h" #if wxUSE_LOG +#include "wx/string.h" +#include "wx/arrstr.h" + // ---------------------------------------------------------------------------- // forward declarations // ---------------------------------------------------------------------------- @@ -185,7 +188,8 @@ public: // trace mask (see wxTraceXXX constants for details) static void SetTraceMask(wxTraceMask ulMask) { ms_ulTraceMask = ulMask; } // add string trace mask - static void AddTraceMask(const wxString& str) { ms_aTraceMasks.Add(str); } + static void AddTraceMask(const wxString& str) + { ms_aTraceMasks.push_back(str); } // add string trace mask static void RemoveTraceMask(const wxString& str); // remove all string trace masks @@ -205,8 +209,7 @@ public: // get trace mask static wxTraceMask GetTraceMask() { return ms_ulTraceMask; } // is this trace mask in the list? - static bool IsAllowedTraceMask(const wxChar *mask) - { return ms_aTraceMasks.Index(mask) != wxNOT_FOUND; } + static bool IsAllowedTraceMask(const wxChar *mask); // return the current loglevel limit static wxLogLevel GetLogLevel() { return ms_logLevel; } diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index 75ab56ebe2..eb7f96dadf 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -199,6 +199,15 @@ // global features // ---------------------------------------------------------------------------- +// Set wxUSE_STL to 1 to derive wxList(Foo) and wxArray(Foo) from +// std::list and std::vector, with a compatibility interface, +// and for wxHashMap to be implemented with templates. +// +// Default is 0 +// +// Recommended setting: YMMV +#define wxUSE_STL 0 + // Support for message/error logging. This includes wxLogXXX() functions and // wxLog and derived classes. Don't set this to 0 unless you really know what // you are doing. diff --git a/include/wx/protocol/http.h b/include/wx/protocol/http.h index fdcda59dc3..71fd1df60e 100644 --- a/include/wx/protocol/http.h +++ b/include/wx/protocol/http.h @@ -15,15 +15,17 @@ #if wxUSE_PROTOCOL_HTTP -#include "wx/list.h" +#include "wx/hashmap.h" #include "wx/protocol/protocol.h" +WX_DECLARE_EXPORTED_STRING_HASH_MAP( wxString, wxStringToStringHashMap ); + class WXDLLIMPEXP_BASE wxHTTP : public wxProtocol { DECLARE_DYNAMIC_CLASS(wxHTTP) DECLARE_PROTOCOL(wxHTTP) protected: wxProtocolError m_perr; - wxList m_headers; + wxStringToStringHashMap m_headers; bool m_read, m_proxy_mode; wxSockAddress *m_addr; public: diff --git a/include/wx/string.h b/include/wx/string.h index 8c8379b0db..4b02daaeb1 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -235,7 +235,9 @@ struct WXDLLIMPEXP_BASE wxStringData class WXDLLIMPEXP_BASE wxString { +#if !wxUSE_STL friend class WXDLLIMPEXP_BASE wxArrayString; +#endif // NB: special care was taken in arranging the member functions in such order // that all inline functions can be effectively inlined, verify that all @@ -1012,166 +1014,11 @@ public: #endif // wxSTD_STRING_COMPATIBILITY }; -// ---------------------------------------------------------------------------- -// The string array uses it's knowledge of internal structure of the wxString -// class to optimize string storage. Normally, we would store pointers to -// string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is -// sizeof(char *)) we store these pointers instead. The cast to "wxString *" is -// really all we need to turn such pointer into a string! -// -// Of course, it can be called a dirty hack, but we use twice less memory and -// this approach is also more speed efficient, so it's probably worth it. -// -// Usage notes: when a string is added/inserted, a new copy of it is created, -// so the original string may be safely deleted. When a string is retrieved -// from the array (operator[] or Item() method), a reference is returned. -// ---------------------------------------------------------------------------- - -int WXDLLIMPEXP_BASE wxStringSortAscending(wxString*, wxString*); -int WXDLLIMPEXP_BASE wxStringSortDescending(wxString*, wxString*); - -class WXDLLIMPEXP_BASE wxArrayString -{ -public: - // type of function used by wxArrayString::Sort() - typedef int (*CompareFunction)(const wxString& first, - const wxString& second); - // type of function used by wxArrayString::Sort(), for compatibility with - // wxArray - typedef int (*CompareFunction2)(wxString* first, - wxString* second); - - // constructors and destructor - // default ctor - wxArrayString() - : m_nSize(0), m_nCount(0), m_pItems(NULL), m_autoSort(FALSE) - { Init(FALSE); } - // if autoSort is TRUE, the array is always sorted (in alphabetical order) - // - // NB: the reason for using int and not bool is that like this we can avoid - // using this ctor for implicit conversions from "const char *" (which - // we'd like to be implicitly converted to wxString instead!) - // - // of course, using explicit would be even better - if all compilers - // supported it... - wxArrayString(int autoSort) - : m_nSize(0), m_nCount(0), m_pItems(NULL), m_autoSort(FALSE) - { Init(autoSort != 0); } - // copy ctor - wxArrayString(const wxArrayString& array); - // assignment operator - wxArrayString& operator=(const wxArrayString& src); - // not virtual, this class should not be derived from - ~wxArrayString(); - - // memory management - // empties the list, but doesn't release memory - void Empty(); - // empties the list and releases memory - void Clear(); - // preallocates memory for given number of items - void Alloc(size_t nCount); - // minimzes the memory usage (by freeing all extra memory) - void Shrink(); - - // simple accessors - // number of elements in the array - size_t GetCount() const { return m_nCount; } - // is it empty? - bool IsEmpty() const { return m_nCount == 0; } - // number of elements in the array (GetCount is preferred API) - size_t Count() const { return m_nCount; } - - // items access (range checking is done in debug version) - // get item at position uiIndex - wxString& Item(size_t nIndex) const - { - wxASSERT_MSG( nIndex < m_nCount, - _T("wxArrayString: index out of bounds") ); - - return *(wxString *)&(m_pItems[nIndex]); - } - - // same as Item() - wxString& operator[](size_t nIndex) const { return Item(nIndex); } - // get last item - wxString& Last() const - { - wxASSERT_MSG( !IsEmpty(), - _T("wxArrayString: index out of bounds") ); - return Item(Count() - 1); - } - -#if WXWIN_COMPATIBILITY_2_4 - // return a wxString[], useful for the controls which - // take one in their ctor. You must delete[] it yourself - // once you are done with it. Will return NULL if the - // ArrayString was empty. - wxString* GetStringArray() const; +// define wxArrayString, for compatibility +#if WXWIN_COMPATIBILITY_2_4 && !wxUSE_STL + #include "wx/arrstr.h" #endif - // item management - // Search the element in the array, starting from the beginning if - // bFromEnd is FALSE or from end otherwise. If bCase, comparison is case - // sensitive (default). Returns index of the first item matched or - // wxNOT_FOUND - int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const; - // add new element at the end (if the array is not sorted), return its - // index - size_t Add(const wxString& str, size_t nInsert = 1); - // add new element at given position - void Insert(const wxString& str, size_t uiIndex, size_t nInsert = 1); - // expand the array to have count elements - void SetCount(size_t count); - // remove first item matching this value - void Remove(const wxChar *sz); - // remove item by index -#if WXWIN_COMPATIBILITY_2_4 - void Remove(size_t nIndex, size_t nRemove = 1) { RemoveAt(nIndex, nRemove); } -#endif - void RemoveAt(size_t nIndex, size_t nRemove = 1); - - // sorting - // sort array elements in alphabetical order (or reversed alphabetical - // order if reverseOrder parameter is TRUE) - void Sort(bool reverseOrder = FALSE); - // sort array elements using specified comparaison function - void Sort(CompareFunction compareFunction); - void Sort(CompareFunction2 compareFunction); - - // comparison - // compare two arrays case sensitively - bool operator==(const wxArrayString& a) const; - // compare two arrays case sensitively - bool operator!=(const wxArrayString& a) const { return !(*this == a); } - -protected: - void Init(bool autoSort); // common part of all ctors - void Copy(const wxArrayString& src); // copies the contents of another array - -private: - void Grow(size_t nIncrement = 0); // makes array bigger if needed - void Free(); // free all the strings stored - - void DoSort(); // common part of all Sort() variants - - size_t m_nSize, // current size of the array - m_nCount; // current number of elements - - wxChar **m_pItems; // pointer to data - - bool m_autoSort; // if TRUE, keep the array always sorted -}; - -class WXDLLIMPEXP_BASE wxSortedArrayString : public wxArrayString -{ -public: - wxSortedArrayString() : wxArrayString(TRUE) - { } - wxSortedArrayString(const wxArrayString& array) : wxArrayString(TRUE) - { Copy(array); } -}; - // ---------------------------------------------------------------------------- // wxStringBuffer: a tiny class allowing to get a writable pointer into string // ---------------------------------------------------------------------------- diff --git a/include/wx/textbuf.h b/include/wx/textbuf.h index dd6322404f..2b25b2d470 100644 --- a/include/wx/textbuf.h +++ b/include/wx/textbuf.h @@ -17,6 +17,7 @@ #endif #include "wx/defs.h" +#include "wx/arrstr.h" // ---------------------------------------------------------------------------- // constants @@ -96,18 +97,18 @@ public: // --------- // get the number of lines in the buffer - size_t GetLineCount() const { return m_aLines.Count(); } + size_t GetLineCount() const { return m_aLines.size(); } // the returned line may be modified (but don't add CR/LF at the end!) - wxString& GetLine(size_t n) const { return m_aLines[n]; } - wxString& operator[](size_t n) const { return m_aLines[n]; } + wxString& GetLine(size_t n) const { return (wxString&)m_aLines[n]; } + wxString& operator[](size_t n) const { return (wxString&)m_aLines[n]; } // the current line has meaning only when you're using // GetFirstLine()/GetNextLine() functions, it doesn't get updated when // you're using "direct access" i.e. GetLine() size_t GetCurrentLine() const { return m_nCurLine; } void GoToLine(size_t n) { m_nCurLine = n; } - bool Eof() const { return (m_aLines.Count() == 0 || m_nCurLine == m_aLines.Count() - 1); } + bool Eof() const { return (m_aLines.size() == 0 || m_nCurLine == m_aLines.size() - 1); } // these methods allow more "iterator-like" traversal of the list of // lines, i.e. you may write something like: @@ -120,7 +121,7 @@ public: wxString& GetPrevLine() /* const */ { wxASSERT(m_nCurLine > 0); return m_aLines[--m_nCurLine]; } wxString& GetLastLine() /* const */ - { return m_aLines[m_nCurLine = m_aLines.Count() - 1]; } + { return m_aLines[m_nCurLine = m_aLines.size() - 1]; } // get the type of the line (see also GetEOL) wxTextFileType GetLineType(size_t n) const { return m_aTypes[n]; } @@ -136,17 +137,25 @@ public: // add a line to the end void AddLine(const wxString& str, wxTextFileType type = typeDefault) - { m_aLines.Add(str); m_aTypes.Add(type); } + { m_aLines.push_back(str); m_aTypes.push_back(type); } // insert a line before the line number n void InsertLine(const wxString& str, size_t n, wxTextFileType type = typeDefault) - { m_aLines.Insert(str, n); m_aTypes.Insert(type, n); } + { + m_aLines.insert(m_aLines.begin() + n, str); + m_aTypes.insert(m_aTypes.begin()+n, type); + } + // delete one line - void RemoveLine(size_t n) { m_aLines.RemoveAt(n); m_aTypes.RemoveAt(n); } + void RemoveLine(size_t n) + { + m_aLines.erase(m_aLines.begin() + n); + m_aTypes.erase(m_aTypes.begin() + n); + } // remove all lines - void Clear() { m_aLines.Clear(); m_nCurLine = 0; } + void Clear() { m_aLines.clear(); m_nCurLine = 0; } // change the buffer (default argument means "don't change type") // possibly in another format diff --git a/include/wx/tokenzr.h b/include/wx/tokenzr.h index bf922a992b..08d39f0938 100644 --- a/include/wx/tokenzr.h +++ b/include/wx/tokenzr.h @@ -18,6 +18,7 @@ #include "wx/object.h" #include "wx/string.h" +#include "wx/arrstr.h" // ---------------------------------------------------------------------------- // constants diff --git a/include/wx/utils.h b/include/wx/utils.h index 8d41542f1e..988754c1b6 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -23,6 +23,7 @@ #include "wx/object.h" #include "wx/list.h" #include "wx/filefn.h" +#include "wx/arrstr.h" // need this for wxGetDiskSpace() as we can't, unfortunately, forward declare // wxLongLong diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 7fbf76d464..9eef76e9c2 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -78,6 +78,7 @@ #define TEST_REGCONF #define TEST_REGEX #define TEST_REGISTRY + #define TEST_SCOPEGUARD #define TEST_SNGLINST #define TEST_SOCKETS #define TEST_STREAMS @@ -95,7 +96,10 @@ #undef TEST_ALL static const bool TEST_ALL = true; #else - #define TEST_LOG + #define TEST_ARRAYS + #define TEST_HASH + #define TEST_LIST + #define TEST_SCOPEGUARD static const bool TEST_ALL = false; #endif @@ -1148,6 +1152,41 @@ static void TestHash() { wxPuts(_T("*** Testing wxHashTable ***\n")); + { + wxHashTable hash(wxKEY_INTEGER), hash2(wxKEY_STRING); + int i; + + for ( i = 0; i < 100; ++i ) + hash.Put(i, (wxObject*)&i + i); + + hash.BeginFind(); + wxHashTable::compatibility_iterator it = hash.Next(); + i = 0; + + while (it) + { + ++i; + it = hash.Next(); + } + + if (i != 100) + wxPuts(_T("Error in wxHashTable::compatibility_iterator\n")); + + for ( i = 99; i >= 0; --i ) + if( hash.Get(i) != (wxObject*)&i + i ) + wxPuts(_T("Error in wxHashTable::Get/Put\n")); + + hash2.Put("foo", (wxObject*)&i + 1); + hash2.Put("bar", (wxObject*)&i + 2); + hash2.Put("baz", (wxObject*)&i + 3); + + if (hash2.Get("moo") != NULL) + wxPuts(_T("Error in wxHashTable::Get\n")); + + if (hash2.Get("bar") != (wxObject*)&i + 2) + wxPuts(_T("Error in wxHashTable::Get/Put\n")); + } +#if !wxUSE_STL { wxHashFoos hash; hash.DeleteContents(true); @@ -1197,8 +1236,10 @@ static void TestHash() wxPuts(_T("ok (not found)")); } } +#endif wxPrintf(_T("Hash destroyed: %u foos left\n"), Foo::count); + wxPuts(_T("*** Testing wxHashTable finished ***\n")); } #endif // TEST_HASH @@ -1361,6 +1402,104 @@ WX_DECLARE_LIST(Bar, wxListBars); #include "wx/listimpl.cpp" WX_DEFINE_LIST(wxListBars); +WX_DECLARE_LIST(int, wxListInt); +WX_DEFINE_LIST(wxListInt); + +static void TestList() +{ + wxPuts(_T("*** Testing wxList operations ***\n")); + { + wxListInt list1; + int dummy[5]; + int i; + + for ( i = 0; i < 5; ++i ) + list1.Append(dummy + i); + + if ( list1.GetCount() != 5 ) + wxPuts(_T("Wrong number of items in list\n")); + + if ( list1.Item(3)->GetData() != dummy + 3 ) + wxPuts(_T("Error in Item()\n")); + + if ( !list1.Find(dummy + 4) ) + wxPuts(_T("Error in Find()\n")); + + wxListInt::compatibility_iterator node = list1.GetFirst(); + i = 0; + + while (node) + { + if ( node->GetData() != dummy + i ) + wxPuts(_T("Error in compatibility_iterator\n")); + node = node->GetNext(); + ++i; + } + + if ( size_t(i) != list1.GetCount() ) + wxPuts(_T("Error in compatibility_iterator\n")); + + list1.Insert(dummy + 0); + list1.Insert(1, dummy + 1); + list1.Insert(list1.GetFirst()->GetNext()->GetNext(), dummy + 2); + + node = list1.GetFirst(); + i = 0; + + while (i < 3) + { + int* t = node->GetData(); + if ( t != dummy + i ) + wxPuts(_T("Error in Insert\n")); + node = node->GetNext(); + ++i; + } + } + + wxPuts(_T("*** Testing wxList operations finished ***\n")); + + wxPuts(_T("*** Testing std::list operations ***\n")); + + { + wxListInt list1; + wxListInt::iterator it, en; + wxListInt::reverse_iterator rit, ren; + int i; + for ( i = 0; i < 5; ++i ) + list1.push_back(i + &i); + + for ( it = list1.begin(), en = list1.end(), i = 0; + it != en; ++it, ++i ) + if ( *it != i + &i ) + wxPuts(_T("Error in iterator\n")); + + for ( rit = list1.rbegin(), ren = list1.rend(), i = 4; + rit != ren; ++rit, --i ) + if ( *rit != i + &i ) + wxPuts(_T("Error in reverse_iterator\n")); + + if ( *list1.rbegin() != *--list1.end() || + *list1.begin() != *--list1.rend() ) + wxPuts(_T("Error in iterator/reverse_iterator\n")); + if ( *list1.begin() != *--++list1.begin() || + *list1.rbegin() != *--++list1.rbegin() ) + wxPuts(_T("Error in iterator/reverse_iterator\n")); + + if ( list1.front() != &i || list1.back() != &i + 4 ) + wxPuts(_T("Error in front()/back()\n")); + + list1.erase(list1.begin()); + list1.erase(--list1.end()); + + for ( it = list1.begin(), en = list1.end(), i = 1; + it != en; ++it, ++i ) + if ( *it != i + &i ) + wxPuts(_T("Error in erase()\n")); + } + + wxPuts(_T("*** Testing std::list operations finished ***\n")); +} + static void TestListCtor() { wxPuts(_T("*** Testing wxList construction ***\n")); @@ -1379,7 +1518,11 @@ static void TestListCtor() wxPrintf(_T("After 2nd list creation: %u and %u objects in the lists, %u objects total.\n"), list1.GetCount(), list2.GetCount(), Bar::GetNumber()); +#if !wxUSE_STL list1.DeleteContents(true); +#else + WX_CLEAR_LIST(wxListBars, list1); +#endif } wxPrintf(_T("After list destruction: %u objects left.\n"), Bar::GetNumber()); @@ -2989,6 +3132,8 @@ static void TestRegistryAssociation() // scope guard // ---------------------------------------------------------------------------- +#ifdef TEST_SCOPEGUARD + #include "wx/scopeguard.h" static void function0() { puts("function0()"); } @@ -3009,14 +3154,16 @@ static void TestScopeGuard() ON_BLOCK_EXIT2(function2, 3.14, 'p'); Object obj; - ON_BLOCK_EXIT_OBJ0(obj, Object::method0); - ON_BLOCK_EXIT_OBJ1(obj, Object::method1, 7); - ON_BLOCK_EXIT_OBJ2(obj, Object::method2, 2.71, 'e'); + ON_BLOCK_EXIT_OBJ0(obj, &Object::method0); + ON_BLOCK_EXIT_OBJ1(obj, &Object::method1, 7); + ON_BLOCK_EXIT_OBJ2(obj, &Object::method2, 2.71, 'e'); wxScopeGuard dismissed = wxMakeGuard(function0); dismissed.Dismiss(); } +#endif + // ---------------------------------------------------------------------------- // sockets // ---------------------------------------------------------------------------- @@ -5715,6 +5862,17 @@ static void PrintArray(const wxChar* name, const wxArrayString& array) } } +static void PrintArray(const wxChar* name, const wxSortedArrayString& array) +{ + wxPrintf(_T("Dump of the array '%s'\n"), name); + + size_t nCount = array.GetCount(); + for ( size_t n = 0; n < nCount; n++ ) + { + wxPrintf(_T("\t%s[%u] = '%s'\n"), name, n, array[n].c_str()); + } +} + int wxCMPFUNC_CONV StringLenCompare(const wxString& first, const wxString& second) { @@ -5779,6 +5937,53 @@ static void TestArrayOf ## name ## s() \ TestArrayOf(UShort); TestArrayOf(Int); +static void TestStlArray() +{ + wxPuts(_T("*** Testing std::vector operations ***\n")); + + { + wxArrayInt list1; + wxArrayInt::iterator it, en; + wxArrayInt::reverse_iterator rit, ren; + int i; + for ( i = 0; i < 5; ++i ) + list1.push_back(i); + + for ( it = list1.begin(), en = list1.end(), i = 0; + it != en; ++it, ++i ) + if ( *it != i ) + wxPuts(_T("Error in iterator\n")); + + for ( rit = list1.rbegin(), ren = list1.rend(), i = 4; + rit != ren; ++rit, --i ) + if ( *rit != i ) + wxPuts(_T("Error in reverse_iterator\n")); + + if ( *list1.rbegin() != *(list1.end()-1) || + *list1.begin() != *(list1.rend()-1) ) + wxPuts(_T("Error in iterator/reverse_iterator\n")); + + it = list1.begin()+1; + rit = list1.rbegin()+1; + if ( *list1.begin() != *(it-1) || + *list1.rbegin() != *(rit-1) ) + wxPuts(_T("Error in iterator/reverse_iterator\n")); + + if ( list1.front() != 0 || list1.back() != 4 ) + wxPuts(_T("Error in front()/back()\n")); + + list1.erase(list1.begin()); + list1.erase(list1.end()-1); + + for ( it = list1.begin(), en = list1.end(), i = 1; + it != en; ++it, ++i ) + if ( *it != i ) + wxPuts(_T("Error in erase()\n")); + } + + wxPuts(_T("*** Testing std::vector operations finished ***\n")); +} + static void TestArrayOfObjects() { wxPuts(_T("*** Testing wxObjArray ***\n")); @@ -6211,6 +6416,16 @@ static void TestStringMatch() #include "wx/snglinst.h" #endif // TEST_SNGLINST +static int MyStringCompare(wxString* s1, wxString* s2) +{ + return wxStrcmp(s1->c_str(), s2->c_str()); +} + +static int MyStringReverseCompare(wxString* s1, wxString* s2) +{ + return -wxStrcmp(s1->c_str(), s2->c_str()); +} + int main(int argc, char **argv) { wxApp::CheckBuildOptions(wxBuildOptions()); @@ -6340,7 +6555,7 @@ int main(int argc, char **argv) #endif // TEST_STRINGS #ifdef TEST_ARRAYS - if ( TEST_ALL ) + if ( 1 || TEST_ALL ) { wxArrayString a1; a1.Add(_T("tiger")); @@ -6357,38 +6572,50 @@ int main(int argc, char **argv) wxArrayString a2(a1); PrintArray(_T("a2"), a2); +#if !wxUSE_STL wxSortedArrayString a3(a1); +#else + wxSortedArrayString a3; + for (wxArrayString::iterator it = a1.begin(), en = a1.end(); + it != en; ++it) + a3.Add(*it); +#endif PrintArray(_T("a3"), a3); wxPuts(_T("*** After deleting three strings from a1")); - a1.Remove(2,3); + a1.RemoveAt(2,3); PrintArray(_T("a1"), a1); PrintArray(_T("a2"), a2); PrintArray(_T("a3"), a3); +#if !wxUSE_STL wxPuts(_T("*** After reassigning a1 to a2 and a3")); a3 = a2 = a1; PrintArray(_T("a2"), a2); PrintArray(_T("a3"), a3); +#endif wxPuts(_T("*** After sorting a1")); - a1.Sort(); + a1.Sort(&MyStringCompare); PrintArray(_T("a1"), a1); wxPuts(_T("*** After sorting a1 in reverse order")); - a1.Sort(true); + a1.Sort(&MyStringReverseCompare); PrintArray(_T("a1"), a1); +#if !wxUSE_STL wxPuts(_T("*** After sorting a1 by the string length")); - a1.Sort(StringLenCompare); + a1.Sort(&StringLenCompare); PrintArray(_T("a1"), a1); +#endif TestArrayOfObjects(); TestArrayOfUShorts(); } TestArrayOfInts(); + TestStlArray(); #endif // TEST_ARRAYS #ifdef TEST_DIR @@ -6418,6 +6645,7 @@ int main(int argc, char **argv) #ifdef TEST_LIST TestListCtor(); + TestList(); #endif // TEST_LIST #ifdef TEST_LOCALE @@ -6663,6 +6891,10 @@ int main(int argc, char **argv) TestDateTimeInteractive(); #endif // TEST_DATETIME +#ifdef TEST_SCOPEGUARD + TestScopeGuard(); +#endif + #ifdef TEST_USLEEP wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z...")); wxUsleep(3000); diff --git a/setup.h.in b/setup.h.in index 79bc5c8ae7..57b110ba55 100644 --- a/setup.h.in +++ b/setup.h.in @@ -157,6 +157,10 @@ */ #undef HAVE_CONST_CAST +/* + * use STL for containers and wxString + */ +#define wxUSE_STL 0 /* * Use regex support */ diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index a43948154a..04304f3672 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -262,11 +262,11 @@ void wxAppConsole::ProcessPendingEvents() } // iterate until the list becomes empty - wxNode *node = wxPendingEvents->GetFirst(); + wxList::compatibility_iterator node = wxPendingEvents->GetFirst(); while (node) { wxEvtHandler *handler = (wxEvtHandler *)node->GetData(); - delete node; + wxPendingEvents->Erase(node); // In ProcessPendingEvents(), new handlers might be add // and we can safely leave the critical section here. diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp index 87c1c8ecee..5313adf3e0 100644 --- a/src/common/cmdline.cpp +++ b/src/common/cmdline.cpp @@ -216,19 +216,19 @@ wxCmdLineParserData::wxCmdLineParserData() void wxCmdLineParserData::SetArguments(int argc, wxChar **argv) { - m_arguments.Empty(); + m_arguments.clear(); for ( int n = 0; n < argc; n++ ) { - m_arguments.Add(argv[n]); + m_arguments.push_back(argv[n]); } } void wxCmdLineParserData::SetArguments(const wxString& cmdLine) { - m_arguments.Empty(); + m_arguments.clear(); - m_arguments.Add(wxTheApp->GetAppName()); + m_arguments.push_back(wxTheApp->GetAppName()); wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdLine); @@ -488,7 +488,7 @@ bool wxCmdLineParser::Found(const wxString& name, wxDateTime *value) const size_t wxCmdLineParser::GetParamCount() const { - return m_data->m_parameters.GetCount(); + return m_data->m_parameters.size(); } wxString wxCmdLineParser::GetParam(size_t n) const @@ -529,7 +529,7 @@ int wxCmdLineParser::Parse(bool showUsage) // parse everything wxString arg; - size_t count = m_data->m_arguments.GetCount(); + size_t count = m_data->m_arguments.size(); for ( size_t n = 1; ok && (n < count); n++ ) // 0 is program name { arg = m_data->m_arguments[n]; @@ -632,7 +632,8 @@ int wxCmdLineParser::Parse(bool showUsage) wxString arg2 = arg[0u]; arg2 += arg.Mid(len + 1); // +1 for leading '-' - m_data->m_arguments.Insert(arg2, n + 1); + m_data->m_arguments.insert + (m_data->m_arguments.begin() + n + 1, arg2); count++; } //else: it's our value, we'll deal with it below @@ -779,7 +780,7 @@ int wxCmdLineParser::Parse(bool showUsage) // TODO check the param type - m_data->m_parameters.Add(arg); + m_data->m_parameters.push_back(arg); if ( !(param.flags & wxCMD_LINE_PARAM_MULTIPLE) ) { @@ -905,7 +906,7 @@ wxString wxCmdLineParser::GetUsageString() wxString appname = wxTheApp->GetAppName(); if ( !appname ) { - wxCHECK_MSG( !m_data->m_arguments.IsEmpty(), wxEmptyString, + wxCHECK_MSG( m_data->m_arguments.size() != 0, wxEmptyString, _T("no program name") ); appname = wxFileNameFromPath(m_data->m_arguments[0]); @@ -989,8 +990,8 @@ wxString wxCmdLineParser::GetUsageString() usage << _T(']'); } - namesOptions.Add(option); - descOptions.Add(opt.description); + namesOptions.push_back(option); + descOptions.push_back(opt.description); } count = m_data->m_paramDesc.GetCount(); @@ -1021,7 +1022,7 @@ wxString wxCmdLineParser::GetUsageString() // now construct the detailed help message size_t len, lenMax = 0; - count = namesOptions.GetCount(); + count = namesOptions.size(); for ( n = 0; n < count; n++ ) { len = namesOptions[n].length(); @@ -1236,7 +1237,7 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p) } } - args.Add(arg); + args.push_back(arg); } return args; diff --git a/src/common/config.cpp b/src/common/config.cpp index 664f34574c..24c66d9e90 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -395,7 +395,7 @@ wxString wxExpandEnvVars(const wxString& str) // this function is used to properly interpret '..' in path void wxSplitPath(wxArrayString& aParts, const wxChar *sz) { - aParts.Empty(); + aParts.clear(); wxString strCurrent; const wxChar *pc = sz; @@ -406,15 +406,15 @@ void wxSplitPath(wxArrayString& aParts, const wxChar *sz) } else if ( strCurrent == wxT("..") ) { // go up one level - if ( aParts.IsEmpty() ) + if ( aParts.size() == 0 ) wxLogWarning(_("'%s' has extra '..', ignored."), sz); else - aParts.RemoveAt(aParts.Count() - 1); + aParts.erase(aParts.end() - 1); strCurrent.Empty(); } else if ( !strCurrent.IsEmpty() ) { - aParts.Add(strCurrent); + aParts.push_back(strCurrent); strCurrent.Empty(); } //else: diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 4f1df66c7e..6751dd2ad9 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -75,8 +75,6 @@ #include "wx/tokenzr.h" #include "wx/module.h" -#define wxDEFINE_TIME_CONSTANTS // before including datetime.h - #include #include "wx/datetime.h" @@ -162,7 +160,7 @@ public: virtual void OnExit() { wxDateTimeHolidayAuthority::ClearAllAuthorities(); - wxDateTimeHolidayAuthority::ms_authorities.Clear(); + wxDateTimeHolidayAuthority::ms_authorities.clear(); } private: @@ -3816,7 +3814,7 @@ wxHolidayAuthoritiesArray wxDateTimeHolidayAuthority::ms_authorities; /* static */ bool wxDateTimeHolidayAuthority::IsHoliday(const wxDateTime& dt) { - size_t count = ms_authorities.GetCount(); + size_t count = ms_authorities.size(); for ( size_t n = 0; n < count; n++ ) { if ( ms_authorities[n]->DoIsHoliday(dt) ) @@ -3836,9 +3834,9 @@ wxDateTimeHolidayAuthority::GetHolidaysInRange(const wxDateTime& dtStart, { wxDateTimeArray hol; - holidays.Empty(); + holidays.Clear(); - size_t count = ms_authorities.GetCount(); + size_t count = ms_authorities.size(); for ( size_t nAuth = 0; nAuth < count; nAuth++ ) { ms_authorities[nAuth]->DoGetHolidaysInRange(dtStart, dtEnd, hol); @@ -3848,7 +3846,7 @@ wxDateTimeHolidayAuthority::GetHolidaysInRange(const wxDateTime& dtStart, holidays.Sort(wxDateTimeCompareFunc); - return holidays.GetCount(); + return holidays.size(); } /* static */ @@ -3860,7 +3858,7 @@ void wxDateTimeHolidayAuthority::ClearAllAuthorities() /* static */ void wxDateTimeHolidayAuthority::AddAuthority(wxDateTimeHolidayAuthority *auth) { - ms_authorities.Add(auth); + ms_authorities.push_back(auth); } wxDateTimeHolidayAuthority::~wxDateTimeHolidayAuthority() diff --git a/src/common/dircmn.cpp b/src/common/dircmn.cpp index 246df8fb3a..d491ed9d53 100644 --- a/src/common/dircmn.cpp +++ b/src/common/dircmn.cpp @@ -206,7 +206,7 @@ public: virtual wxDirTraverseResult OnFile(const wxString& filename) { - m_files.Add(filename); + m_files.push_back(filename); return wxDIR_CONTINUE; } diff --git a/src/common/dynarray.cpp b/src/common/dynarray.cpp index 2b185f156f..7224e1db53 100644 --- a/src/common/dynarray.cpp +++ b/src/common/dynarray.cpp @@ -53,7 +53,64 @@ wxCOMPILE_TIME_ASSERT( sizeof(long) <= sizeof(void *), // wxBaseArray - dynamic array of 'T's // ---------------------------------------------------------------------------- -#define _WX_DEFINE_BASEARRAY(T, name) \ +#define _WX_DEFINE_BASEARRAY_COMMON(T, name) \ +/* searches the array for an item (forward or backwards) */ \ +int name::Index(T lItem, bool bFromEnd) const \ +{ \ + if ( bFromEnd ) { \ + if ( size() > 0 ) { \ + size_t n = size(); \ + do { \ + if ( (*this)[--n] == lItem ) \ + return n; \ + } \ + while ( n != 0 ); \ + } \ + } \ + else { \ + for( size_t n = 0; n < size(); n++ ) { \ + if( (*this)[n] == lItem ) \ + return n; \ + } \ + } \ + \ + return wxNOT_FOUND; \ +} \ + \ +/* add item assuming the array is sorted with fnCompare function */ \ +void name::Add(T lItem, CMPFUNC fnCompare) \ +{ \ + Insert(lItem, IndexForInsert(lItem, fnCompare)); \ +} \ + \ + +#if wxUSE_STL + +#define _WX_DEFINE_BASEARRAY_NOCOMMON(T, name) \ +size_t name::IndexForInsert(T lItem, CMPFUNC fnCompare) const \ +{ \ + Predicate p(fnCompare); \ + const_iterator it = std::lower_bound(begin(), end(), lItem, p); \ + return it - begin(); \ +} \ + \ +int name::Index(T lItem, CMPFUNC fnCompare) const \ +{ \ + size_t n = IndexForInsert(lItem, fnCompare); \ + \ + return (n >= size() || \ + (*fnCompare)(&lItem, &(*this)[n])) ? wxNOT_FOUND : (int)n; \ +} \ + \ +void name::Shrink() \ +{ \ + name tmp(*this); \ + swap(tmp); \ +} + +#else // if !wxUSE_STL + +#define _WX_DEFINE_BASEARRAY_NOCOMMON(T, name) \ /* ctor */ \ name::name() \ { \ @@ -229,27 +286,32 @@ void name::Shrink() \ } \ } \ \ -/* searches the array for an item (forward or backwards) */ \ -int name::Index(T lItem, bool bFromEnd) const \ +/* add item at the end */ \ +void name::Add(T lItem, size_t nInsert) \ { \ - if ( bFromEnd ) { \ - if ( m_nCount > 0 ) { \ - size_t n = m_nCount; \ - do { \ - if ( m_pItems[--n] == lItem ) \ - return n; \ - } \ - while ( n != 0 ); \ - } \ - } \ - else { \ - for( size_t n = 0; n < m_nCount; n++ ) { \ - if( m_pItems[n] == lItem ) \ - return n; \ - } \ - } \ + if (nInsert == 0) \ + return; \ + Grow(nInsert); \ + for (size_t i = 0; i < nInsert; i++) \ + m_pItems[m_nCount++] = lItem; \ +} \ \ - return wxNOT_FOUND; \ +/* add item at the given position */ \ +void name::Insert(T lItem, size_t nIndex, size_t nInsert) \ +{ \ + wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArray::Insert") ); \ + wxCHECK_RET( m_nCount <= m_nCount + nInsert, \ + wxT("array size overflow in wxArray::Insert") ); \ + \ + if (nInsert == 0) \ + return; \ + Grow(nInsert); \ + \ + memmove(&m_pItems[nIndex + nInsert], &m_pItems[nIndex], \ + (m_nCount - nIndex)*sizeof(T)); \ + for (size_t i = 0; i < nInsert; i++) \ + m_pItems[nIndex + i] = lItem; \ + m_nCount += nInsert; \ } \ \ /* search for a place to insert item into sorted array (binary search) */ \ @@ -289,40 +351,6 @@ int name::Index(T lItem, CMPFUNC fnCompare) const \ : (int)n; \ } \ \ -/* add item at the end */ \ -void name::Add(T lItem, size_t nInsert) \ -{ \ - if (nInsert == 0) \ - return; \ - Grow(nInsert); \ - for (size_t i = 0; i < nInsert; i++) \ - m_pItems[m_nCount++] = lItem; \ -} \ - \ -/* add item assuming the array is sorted with fnCompare function */ \ -void name::Add(T lItem, CMPFUNC fnCompare) \ -{ \ - Insert(lItem, IndexForInsert(lItem, fnCompare)); \ -} \ - \ -/* add item at the given position */ \ -void name::Insert(T lItem, size_t nIndex, size_t nInsert) \ -{ \ - wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArray::Insert") ); \ - wxCHECK_RET( m_nCount <= m_nCount + nInsert, \ - wxT("array size overflow in wxArray::Insert") ); \ - \ - if (nInsert == 0) \ - return; \ - Grow(nInsert); \ - \ - memmove(&m_pItems[nIndex + nInsert], &m_pItems[nIndex], \ - (m_nCount - nIndex)*sizeof(T)); \ - for (size_t i = 0; i < nInsert; i++) \ - m_pItems[nIndex + i] = lItem; \ - m_nCount += nInsert; \ -} \ - \ /* removes item from array (by index) */ \ void name::RemoveAt(size_t nIndex, size_t nRemove) \ { \ @@ -352,9 +380,21 @@ void name::Sort(CMPFUNC fCmp) \ qsort(m_pItems, m_nCount, sizeof(T), fCmp); \ } +#endif + +#define _WX_DEFINE_BASEARRAY(T, name) \ + _WX_DEFINE_BASEARRAY_COMMON(T, name) \ + _WX_DEFINE_BASEARRAY_NOCOMMON(T, name) + _WX_DEFINE_BASEARRAY(const void *, wxBaseArrayPtrVoid) _WX_DEFINE_BASEARRAY(short, wxBaseArrayShort) _WX_DEFINE_BASEARRAY(int, wxBaseArrayInt) _WX_DEFINE_BASEARRAY(long, wxBaseArrayLong) //_WX_DEFINE_BASEARRAY(double, wxBaseArrayDouble) +#if wxUSE_STL +#include "wx/arrstr.h" + +_WX_DEFINE_BASEARRAY(wxString, wxBaseArrayStringBase) + +#endif diff --git a/src/common/dynload.cpp b/src/common/dynload.cpp index 437f341c6a..65bdd6ddb4 100644 --- a/src/common/dynload.cpp +++ b/src/common/dynload.cpp @@ -475,18 +475,18 @@ void wxPluginLibrary::RegisterModules() wxASSERT_MSG( m, _T("wxDynamicCast of wxModule failed") ); - m_wxmodules.Append(m); + m_wxmodules.push_back(m); wxModule::RegisterModule(m); } } // FIXME: Likewise this is (well was) very similar to InitializeModules() - for ( wxModuleList::Node *node = m_wxmodules.GetFirst(); - node; - node = node->GetNext()) + for ( wxModuleList::iterator it = m_wxmodules.begin(); + it != m_wxmodules.end(); + ++it) { - if( !node->GetData()->Init() ) + if( !(*it)->Init() ) { wxLogDebug(_T("wxModule::Init() failed for wxPluginLibrary")); @@ -497,13 +497,14 @@ void wxPluginLibrary::RegisterModules() // let the dtor Exit the rest on shutdown, (which we'll initiate // shortly). - wxModuleList::Node *oldNode = 0; + wxModuleList::iterator oldNode = m_wxmodules.end(); do { - node = node->GetNext(); - delete oldNode; - wxModule::UnregisterModule( node->GetData() ); - oldNode = node; - } while( node ); + ++it; + if( oldNode != m_wxmodules.end() ) + m_wxmodules.erase(oldNode); + wxModule::UnregisterModule( *it ); + oldNode = it; + } while( it != m_wxmodules.end() ); --m_linkcount; // Flag us for deletion break; @@ -513,15 +514,15 @@ void wxPluginLibrary::RegisterModules() void wxPluginLibrary::UnregisterModules() { - wxModuleList::Node *node; + wxModuleList::iterator it; - for ( node = m_wxmodules.GetFirst(); node; node = node->GetNext() ) - node->GetData()->Exit(); + for ( it = m_wxmodules.begin(); it != m_wxmodules.end(); ++it ) + (*it)->Exit(); - for ( node = m_wxmodules.GetFirst(); node; node = node->GetNext() ) - wxModule::UnregisterModule( node->GetData() ); + for ( it = m_wxmodules.begin(); it != m_wxmodules.end(); ++it ) + wxModule::UnregisterModule( *it ); - m_wxmodules.DeleteContents(TRUE); + WX_CLEAR_LIST(wxModuleList, m_wxmodules); } diff --git a/src/common/encconv.cpp b/src/common/encconv.cpp index e4763473e5..759dd58fa5 100644 --- a/src/common/encconv.cpp +++ b/src/common/encconv.cpp @@ -383,7 +383,14 @@ static wxFontEncoding }; - +static bool FindEncoding(const wxFontEncodingArray& arr, wxFontEncoding f) +{ + for (wxFontEncodingArray::const_iterator it = arr.begin(), en = arr.end(); + it != en; ++it) + if (*it == f) + return true; + return false; +} wxFontEncodingArray wxEncodingConverter::GetPlatformEquivalents(wxFontEncoding enc, int platform) { @@ -412,9 +419,9 @@ wxFontEncodingArray wxEncodingConverter::GetPlatformEquivalents(wxFontEncoding e if (EquivalentEncodings[clas][i][e] == enc) { for (f = EquivalentEncodings[clas][platform]; *f != STOP; f++) - if (*f == enc) arr.Add(enc); + if (*f == enc) arr.push_back(enc); for (f = EquivalentEncodings[clas][platform]; *f != STOP; f++) - if (arr.Index(*f) == wxNOT_FOUND) arr.Add(*f); + if (!FindEncoding(arr, *f)) arr.push_back(*f); i = NUM_OF_PLATFORMS/*hack*/; break; } clas++; @@ -442,7 +449,7 @@ wxFontEncodingArray wxEncodingConverter::GetAllEquivalents(wxFontEncoding enc) { for (j = 0; j < NUM_OF_PLATFORMS; j++) for (f = EquivalentEncodings[clas][j]; *f != STOP; f++) - if (arr.Index(*f) == wxNOT_FOUND) arr.Add(*f); + if (!FindEncoding(arr, *f)) arr.push_back(*f); i = NUM_OF_PLATFORMS/*hack*/; break; } clas++; diff --git a/src/common/event.cpp b/src/common/event.cpp index 99d1100aa9..ff13a80111 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -712,19 +712,19 @@ wxEvtHandler::~wxEvtHandler() if (m_dynamicEvents) { - wxNode *node = m_dynamicEvents->GetFirst(); - while (node) + wxList::iterator it = m_dynamicEvents->begin(), + en = m_dynamicEvents->end(); + for (;it != en; ++it) { #if WXWIN_COMPATIBILITY_EVENT_TYPES - wxEventTableEntry *entry = (wxEventTableEntry*)node->GetData(); + wxEventTableEntry *entry = (wxEventTableEntry*)*it; #else // !WXWIN_COMPATIBILITY_EVENT_TYPES - wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData(); + wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)*it; #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES if (entry->m_callbackUserData) delete entry->m_callbackUserData; delete entry; - node = node->GetNext(); } delete m_dynamicEvents; }; @@ -818,11 +818,11 @@ void wxEvtHandler::ProcessPendingEvents() wxENTER_CRIT_SECT( *m_eventsLocker); #endif - wxNode *node = m_pendingEvents->GetFirst(); + wxList::compatibility_iterator node = m_pendingEvents->GetFirst(); while ( node ) { wxEvent *event = (wxEvent *)node->GetData(); - delete node; + m_pendingEvents->Erase(node); // In ProcessEvent, new events might get added and // we can safely leave the crtical section here. @@ -1000,7 +1000,7 @@ bool wxEvtHandler::Disconnect( int id, int lastId, wxEventType eventType, if (!m_dynamicEvents) return FALSE; - wxNode *node = m_dynamicEvents->GetFirst(); + wxList::compatibility_iterator node = m_dynamicEvents->GetFirst(); while (node) { #if WXWIN_COMPATIBILITY_EVENT_TYPES @@ -1018,7 +1018,7 @@ bool wxEvtHandler::Disconnect( int id, int lastId, wxEventType eventType, { if (entry->m_callbackUserData) delete entry->m_callbackUserData; - m_dynamicEvents->DeleteNode( node ); + m_dynamicEvents->Erase( node ); delete entry; return TRUE; } @@ -1034,7 +1034,7 @@ bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event ) int commandId = event.GetId(); - wxNode *node = m_dynamicEvents->GetFirst(); + wxList::compatibility_iterator node = m_dynamicEvents->GetFirst(); while (node) { #if WXWIN_COMPATIBILITY_EVENT_TYPES diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp index 29c5ad4891..40af10e79a 100644 --- a/src/common/filefn.cpp +++ b/src/common/filefn.cpp @@ -232,7 +232,7 @@ WXDLLEXPORT int wxOpen( const wxChar *pathname, int flags, mode_t mode ) // wxPathList // ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxStringList) +// IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxStringList) static inline wxChar* MYcopystring(const wxString& s) { @@ -248,7 +248,7 @@ static inline wxChar* MYcopystring(const wxChar* s) void wxPathList::Add (const wxString& path) { - wxStringList::Add (WXSTRINGCAST path); + wxStringList::Append (WXSTRINGCAST path); } // Add paths e.g. from the PATH environment variable @@ -309,7 +309,7 @@ void wxPathList::EnsureFileAccessible (const wxString& path) bool wxPathList::Member (const wxString& path) { - for (wxStringList::Node *node = GetFirst(); node; node = node->GetNext()) + for (wxStringList::compatibility_iterator node = GetFirst(); node; node = node->GetNext()) { wxString path2( node->GetData() ); if ( @@ -337,9 +337,9 @@ wxString wxPathList::FindValidPath (const wxString& file) wxChar *filename = (wxChar*) NULL; /* shut up buggy egcs warning */ filename = wxIsAbsolutePath (buf) ? wxFileNameFromPath (buf) : (wxChar *)buf; - for (wxStringList::Node *node = GetFirst(); node; node = node->GetNext()) + for (wxStringList::compatibility_iterator node = GetFirst(); node; node = node->GetNext()) { - wxChar *path = node->GetData(); + const wxChar *path = node->GetData(); wxStrcpy (wxFileFunctionsBuffer, path); wxChar ch = wxFileFunctionsBuffer[wxStrlen(wxFileFunctionsBuffer)-1]; if (ch != wxT('\\') && ch != wxT('/')) diff --git a/src/common/filesys.cpp b/src/common/filesys.cpp index 4213f32dc4..c1e3070423 100644 --- a/src/common/filesys.cpp +++ b/src/common/filesys.cpp @@ -28,7 +28,6 @@ #include "wx/log.h" - //-------------------------------------------------------------------------------- // wxFileSystemHandler //-------------------------------------------------------------------------------- @@ -323,7 +322,7 @@ wxFSFile* wxFileSystem::OpenFile(const wxString& location) unsigned i, ln; char meta; wxFSFile *s = NULL; - wxNode *node; + wxList::compatibility_iterator node; ln = loc.Length(); meta = 0; @@ -377,7 +376,7 @@ wxFSFile* wxFileSystem::OpenFile(const wxString& location) wxString wxFileSystem::FindFirst(const wxString& spec, int flags) { - wxNode *node; + wxList::compatibility_iterator node; wxString spec2(spec); m_FindFileHandler = NULL; @@ -424,8 +423,7 @@ void wxFileSystem::AddHandler(wxFileSystemHandler *handler) void wxFileSystem::CleanUpHandlers() { - m_Handlers.DeleteContents(TRUE); - m_Handlers.Clear(); + WX_CLEAR_LIST(wxList, m_Handlers); } const static wxString g_unixPathString(wxT("/")); diff --git a/src/common/fs_inet.cpp b/src/common/fs_inet.cpp index 7d4be026c9..1e3d353a7c 100644 --- a/src/common/fs_inet.cpp +++ b/src/common/fs_inet.cpp @@ -156,11 +156,11 @@ wxFSFile* wxInternetFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxStri wxInternetFSHandler::~wxInternetFSHandler() { - wxNode *n; + wxHashTable::compatibility_iterator n; wxInetCacheNode *n2; m_Cache.BeginFind(); - while ((n = m_Cache.Next()) != NULL) + while ((n = m_Cache.Next())) { n2 = (wxInetCacheNode*) n->GetData(); wxRemoveFile(n2->GetTemp()); diff --git a/src/common/fs_mem.cpp b/src/common/fs_mem.cpp index a1013b5bde..81bf369765 100644 --- a/src/common/fs_mem.cpp +++ b/src/common/fs_mem.cpp @@ -101,6 +101,7 @@ wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase() if (m_Hash) { + WX_CLEAR_HASH_TABLE(*m_Hash); delete m_Hash; m_Hash = NULL; } @@ -160,7 +161,6 @@ bool wxMemoryFSHandlerBase::CheckHash(const wxString& filename) if (m_Hash == NULL) { m_Hash = new wxHashTable(wxKEY_STRING); - m_Hash -> DeleteContents(TRUE); } if (m_Hash -> Get(filename) != NULL) diff --git a/src/common/hash.cpp b/src/common/hash.cpp index db2a5a141a..1df6c30b78 100644 --- a/src/common/hash.cpp +++ b/src/common/hash.cpp @@ -34,6 +34,8 @@ #include "wx/hash.h" +#if !wxUSE_STL + #include #include @@ -722,3 +724,4 @@ void wxHashTable::Clear () m_count = 0; } +#endif // !wxUSE_STL diff --git a/src/common/http.cpp b/src/common/http.cpp index 346896925a..bc1583ab90 100644 --- a/src/common/http.cpp +++ b/src/common/http.cpp @@ -38,8 +38,7 @@ IMPLEMENT_PROTOCOL(wxHTTP, wxT("http"), wxT("80"), TRUE) #define HTTP_BSIZE 2048 wxHTTP::wxHTTP() - : wxProtocol(), - m_headers(wxKEY_STRING) + : wxProtocol() { m_addr = NULL; m_read = FALSE; @@ -57,17 +56,7 @@ wxHTTP::~wxHTTP() void wxHTTP::ClearHeaders() { - // wxString isn't a wxObject - wxNode *node = m_headers.GetFirst(); - wxString *string; - - while (node) { - string = (wxString *)node->GetData(); - delete string; - node = node->GetNext(); - } - - m_headers.Clear(); + m_headers.clear(); } wxString wxHTTP::GetContentType() @@ -87,45 +76,34 @@ void wxHTTP::SetHeader(const wxString& header, const wxString& h_data) m_read = FALSE; } - wxNode *node = m_headers.Find(header); - - if (!node) - m_headers.Append(header.Upper(), (wxObject *)(new wxString(h_data))); - else { - wxString *str = (wxString *)node->GetData(); - (*str) = h_data; - } + wxStringToStringHashMap::iterator it = m_headers.find(header); + if (it != m_headers.end()) + it->second = h_data; + else + m_headers[header.Upper()] = h_data; } wxString wxHTTP::GetHeader(const wxString& header) { - wxNode *node; - wxString upper_header; + wxStringToStringHashMap::iterator it = m_headers.find(header.Upper()); - upper_header = header.Upper(); - - node = m_headers.Find(upper_header); - if (!node) + if (it == m_headers.end()) return wxEmptyString; - return *((wxString *)node->GetData()); + return it->second; } void wxHTTP::SendHeaders() { - wxNode *head = m_headers.GetFirst(); + typedef wxStringToStringHashMap::iterator iterator; + wxString buf; - while (head) + for (iterator it = m_headers.begin(), en = m_headers.end(); it != en; ++it ) { - wxString *str = (wxString *)head->GetData(); - - wxString buf; - buf.Printf(wxT("%s: %s\r\n"), head->GetKeyString(), str->GetData()); + buf.Printf(wxT("%s: %s\r\n"), it->first.c_str(), it->second.c_str()); const wxWX2MBbuf cbuf = buf.mb_str(); Write(cbuf, strlen(cbuf)); - - head = head->GetNext(); } } @@ -152,10 +130,9 @@ bool wxHTTP::ParseHeaders() break; wxString left_str = line.BeforeFirst(':'); - wxString *str = new wxString(line.AfterFirst(':').Strip(wxString::both)); left_str.MakeUpper(); - m_headers.Append(left_str, (wxObject *) str); + m_headers[left_str] = line.AfterFirst(':').Strip(wxString::both); } return TRUE; } diff --git a/src/common/list.cpp b/src/common/list.cpp index fed64c544f..62200c7e5e 100644 --- a/src/common/list.cpp +++ b/src/common/list.cpp @@ -37,6 +37,8 @@ #include "wx/list.h" #endif +#if !wxUSE_STL + // ============================================================================= // implementation // ============================================================================= @@ -44,7 +46,6 @@ // ----------------------------------------------------------------------------- // wxListKey // ----------------------------------------------------------------------------- - wxListKey wxDefaultListKey; bool wxListKey::operator==(wxListKeyValue value) const @@ -531,6 +532,38 @@ 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 // ============================================================================ @@ -732,3 +765,4 @@ wxNode *wxStringList::Prepend(const wxChar *s) #endif // wxLIST_COMPATIBILITY +#endif // !wxUSE_STL diff --git a/src/common/log.cpp b/src/common/log.cpp index 86a83f0954..897ee542a5 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -33,6 +33,7 @@ // wxWindows #ifndef WX_PRECOMP #include "wx/app.h" + #include "wx/arrstr.h" #include "wx/intl.h" #include "wx/string.h" #endif //WX_PRECOMP @@ -497,6 +498,16 @@ void wxLog::Flush() // nothing to do here } +/*static*/ bool wxLog::IsAllowedTraceMask(const wxChar *mask) +{ + for ( wxArrayString::iterator it = ms_aTraceMasks.begin(), + en = ms_aTraceMasks.end(); + it != en; ++it ) + if ( *it == mask) + return true; + return false; +} + // ---------------------------------------------------------------------------- // wxLogStderr class implementation // ---------------------------------------------------------------------------- diff --git a/src/common/module.cpp b/src/common/module.cpp index 8397312756..e8ddb80a0a 100644 --- a/src/common/module.cpp +++ b/src/common/module.cpp @@ -38,13 +38,14 @@ void wxModule::RegisterModule(wxModule* module) void wxModule::UnregisterModule(wxModule* module) { m_modules.DeleteObject(module); + delete module; } // Collect up all module-derived classes, create an instance of each, // and register them. void wxModule::RegisterModules() { - wxNode *node; + wxHashTable::compatibility_iterator node; wxClassInfo* classInfo; wxClassInfo::sm_classTable->BeginFind(); @@ -65,13 +66,13 @@ void wxModule::RegisterModules() bool wxModule::InitializeModules() { // Initialize user-defined modules - wxModuleList::Node *node; + wxModuleList::compatibility_iterator node; for ( node = m_modules.GetFirst(); node; node = node->GetNext() ) { if ( !node->GetData()->Init() ) { // clean up already initialized modules - process in reverse order - wxModuleList::Node *n; + wxModuleList::compatibility_iterator n; for ( n = node->GetPrevious(); n; n = n->GetPrevious() ) { n->GetData()->OnExit(); @@ -87,13 +88,12 @@ bool wxModule::InitializeModules() void wxModule::CleanUpModules() { // Cleanup user-defined modules - wxModuleList::Node *node; + wxModuleList::compatibility_iterator node; for ( node = m_modules.GetFirst(); node; node = node->GetNext() ) { node->GetData()->Exit(); } - m_modules.DeleteContents(TRUE); - m_modules.Clear(); + WX_CLEAR_LIST(wxModuleList, m_modules); } diff --git a/src/common/object.cpp b/src/common/object.cpp index 8dad5efc0f..f0ca00964c 100644 --- a/src/common/object.cpp +++ b/src/common/object.cpp @@ -22,7 +22,8 @@ #endif #ifndef WX_PRECOMP -#include "wx/hash.h" + #include "wx/hash.h" + #include "wx/object.h" #endif #include diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 96f06d81b2..377384849f 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -828,7 +828,7 @@ void wxSocketBase::SaveState() void wxSocketBase::RestoreState() { - wxNode *node; + wxList::compatibility_iterator node; wxSocketState *state; node = m_states.GetLast(); @@ -846,7 +846,7 @@ void wxSocketBase::RestoreState() m_cdata = state->m_cdata; #endif // WXWIN_COMPATIBILITY - delete node; + m_states.Erase(node); delete state; } diff --git a/src/common/string.cpp b/src/common/string.cpp index 7fe2592efb..42c3a74f40 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1753,6 +1753,8 @@ wxString& wxString::replace(size_t nStart, size_t nLen, // ArrayString // ============================================================================ +#if !wxUSE_STL + // size increment = min(50% of current size, ARRAY_MAXSIZE_INCREMENT) #define ARRAY_MAXSIZE_INCREMENT 4096 @@ -2181,6 +2183,8 @@ bool wxArrayString::operator==(const wxArrayString& a) const return TRUE; } +#endif // !wxUSE_STL + int wxStringSortAscending(wxString* s1, wxString* s2) { return wxStrcmp(s1->c_str(), s2->c_str()); diff --git a/src/common/sysopt.cpp b/src/common/sysopt.cpp index 6bc09e7de1..2c3439278e 100644 --- a/src/common/sysopt.cpp +++ b/src/common/sysopt.cpp @@ -37,6 +37,7 @@ #include "wx/string.h" #include "wx/sysopt.h" #include "wx/module.h" +#include "wx/arrstr.h" // ---------------------------------------------------------------------------- // private classes diff --git a/src/common/tokenzr.cpp b/src/common/tokenzr.cpp index 32c220a69a..a8946b57a3 100644 --- a/src/common/tokenzr.cpp +++ b/src/common/tokenzr.cpp @@ -29,6 +29,7 @@ #endif #include "wx/tokenzr.h" +#include "wx/arrstr.h" // Required for wxIs... functions #include diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 5a91c57e8f..eefe29c5c9 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -673,7 +673,7 @@ wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt) } #endif - wxWindowList::Node *node = win->GetChildren().GetLast(); + wxWindowList::compatibility_iterator node = win->GetChildren().GetLast(); while (node) { wxWindow* child = node->GetData(); @@ -702,7 +702,7 @@ wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt) // Go backwards through the list since windows // on top are likely to have been appended most // recently. - wxWindowList::Node *node = wxTopLevelWindows.GetLast(); + wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast(); while (node) { wxWindow* win = node->GetData(); @@ -837,7 +837,7 @@ wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit) void wxEnableTopLevelWindows(bool enable) { - wxWindowList::Node *node; + wxWindowList::compatibility_iterator node; for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) node->GetData()->Enable(enable); } @@ -848,7 +848,7 @@ wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip) // don't reenable them later m_winDisabled = NULL; - wxWindowList::Node *node; + wxWindowList::compatibility_iterator node; for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) { wxWindow *winTop = node->GetData(); @@ -874,7 +874,7 @@ wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip) wxWindowDisabler::~wxWindowDisabler() { - wxWindowList::Node *node; + wxWindowList::compatibility_iterator node; for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) { wxWindow *winTop = node->GetData(); diff --git a/src/common/variant.cpp b/src/common/variant.cpp index b7399182ca..85ea9a9805 100644 --- a/src/common/variant.cpp +++ b/src/common/variant.cpp @@ -94,7 +94,7 @@ wxVariantDataList::~wxVariantDataList() void wxVariantDataList::SetValue(const wxList& value) { Clear(); - wxNode* node = value.GetFirst(); + wxList::compatibility_iterator node = value.GetFirst(); while (node) { wxVariant* var = (wxVariant*) node->GetData(); @@ -105,7 +105,7 @@ void wxVariantDataList::SetValue(const wxList& value) void wxVariantDataList::Clear() { - wxNode* node = m_value.GetFirst(); + wxList::compatibility_iterator node = m_value.GetFirst(); while (node) { wxVariant* var = (wxVariant*) node->GetData(); @@ -122,7 +122,7 @@ void wxVariantDataList::Copy(wxVariantData& data) wxVariantDataList& listData = (wxVariantDataList&) data; listData.Clear(); - wxNode* node = m_value.GetFirst(); + wxList::compatibility_iterator node = m_value.GetFirst(); while (node) { wxVariant* var = (wxVariant*) node->GetData(); @@ -136,8 +136,8 @@ bool wxVariantDataList::Eq(wxVariantData& data) const wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") ); wxVariantDataList& listData = (wxVariantDataList&) data; - wxNode* node1 = m_value.GetFirst(); - wxNode* node2 = listData.GetValue().GetFirst(); + wxList::compatibility_iterator node1 = m_value.GetFirst(); + wxList::compatibility_iterator node2 = listData.GetValue().GetFirst(); while (node1 && node2) { wxVariant* var1 = (wxVariant*) node1->GetData(); @@ -164,7 +164,7 @@ bool wxVariantDataList::Write(wxSTD ostream& str) const bool wxVariantDataList::Write(wxString& str) const { str = wxT(""); - wxNode* node = m_value.GetFirst(); + wxList::compatibility_iterator node = m_value.GetFirst(); while (node) { wxVariant* var = (wxVariant*) node->GetData(); @@ -245,8 +245,8 @@ bool wxVariantDataStringList::Eq(wxVariantData& data) const wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Eq: argument mismatch") ); wxVariantDataStringList& listData = (wxVariantDataStringList&) data; - wxStringList::Node *node1 = m_value.GetFirst(); - wxStringList::Node *node2 = listData.GetValue().GetFirst(); + wxStringList::compatibility_iterator node1 = m_value.GetFirst(); + wxStringList::compatibility_iterator node2 = listData.GetValue().GetFirst(); while (node1 && node2) { wxString str1 ( node1->GetData() ); @@ -273,10 +273,10 @@ bool wxVariantDataStringList::Write(wxSTD ostream& str) const bool wxVariantDataStringList::Write(wxString& str) const { str.Empty(); - wxStringList::Node *node = m_value.GetFirst(); + wxStringList::compatibility_iterator node = m_value.GetFirst(); while (node) { - wxChar* s = node->GetData(); + const wxChar* s = node->GetData(); if (node != m_value.GetFirst()) str += wxT(" "); str += s; @@ -1735,7 +1735,7 @@ wxVariant wxVariant::operator[] (size_t idx) const wxVariantDataStringList* data = (wxVariantDataStringList*) m_data; wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") ); - wxVariant variant( wxString( (wxChar*) (data->GetValue().Item(idx)->GetData()) )); + wxVariant variant( wxString( (const wxChar*) (data->GetValue().Item(idx)->GetData()) )); return variant; } return wxNullVariant; @@ -1942,7 +1942,7 @@ bool wxVariant::Member(const wxVariant& value) const { wxList& list = GetList(); - wxNode* node = list.GetFirst(); + wxList::compatibility_iterator node = list.GetFirst(); while (node) { wxVariant* other = (wxVariant*) node->GetData(); @@ -1959,10 +1959,10 @@ bool wxVariant::Delete(int item) wxList& list = GetList(); wxASSERT_MSG( (item < (int) list.GetCount()), wxT("Invalid index to Delete") ); - wxNode* node = list.Item(item); + wxList::compatibility_iterator node = list.Item(item); wxVariant* variant = (wxVariant*) node->GetData(); delete variant; - delete node; + list.Erase(node); return TRUE; } diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index 606abdac8b..cb98067949 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -38,7 +38,7 @@ #include "wx/module.h" #include "wx/dde.h" #include "wx/intl.h" - +#include "wx/hashmap.h" #include "wx/msw/private.h" @@ -122,9 +122,11 @@ static void DDELogError(const wxString& s, UINT error = DMLERR_NO_ERROR); // global variables // ---------------------------------------------------------------------------- +WX_DECLARE_STRING_HASH_MAP( HSZ, wxAtomMap ); + static DWORD DDEIdInst = 0L; static wxDDEConnection *DDECurrentlyConnecting = NULL; -static wxList wxAtomTable(wxKEY_STRING); +static wxAtomMap wxAtomTable; #include "wx/listimpl.cpp" @@ -193,15 +195,10 @@ extern void wxDDEInitialize() void wxDDECleanUp() { - wxDDEClientObjects.DeleteContents(true); - wxDDEClientObjects.Clear(); - wxDDEClientObjects.DeleteContents(false); + WX_CLEAR_LIST(wxDDEClientList, wxDDEClientObjects); + WX_CLEAR_LIST(wxDDEServerList, wxDDEServerObjects); - wxDDEServerObjects.DeleteContents(true); - wxDDEServerObjects.Clear(); - wxDDEServerObjects.DeleteContents(false); - - wxAtomTable.Clear(); + wxAtomTable.clear(); if ( DDEIdInst != 0 ) { @@ -217,7 +214,7 @@ void wxDDECleanUp() // Global find connection static wxDDEConnection *DDEFindConnection(HCONV hConv) { - wxDDEServerList::Node *serverNode = wxDDEServerObjects.GetFirst(); + wxDDEServerList::compatibility_iterator serverNode = wxDDEServerObjects.GetFirst(); wxDDEConnection *found = NULL; while (serverNode && !found) { @@ -231,7 +228,7 @@ static wxDDEConnection *DDEFindConnection(HCONV hConv) return found; } - wxDDEClientList::Node *clientNode = wxDDEClientObjects.GetFirst(); + wxDDEClientList::compatibility_iterator clientNode = wxDDEClientObjects.GetFirst(); while (clientNode && !found) { wxDDEClient *object = clientNode->GetData(); @@ -244,7 +241,7 @@ static wxDDEConnection *DDEFindConnection(HCONV hConv) // Global delete connection static void DDEDeleteConnection(HCONV hConv) { - wxDDEServerList::Node *serverNode = wxDDEServerObjects.GetFirst(); + wxDDEServerList::compatibility_iterator serverNode = wxDDEServerObjects.GetFirst(); bool found = false; while (serverNode && !found) { @@ -257,7 +254,7 @@ static void DDEDeleteConnection(HCONV hConv) return; } - wxDDEClientList::Node *clientNode = wxDDEClientObjects.GetFirst(); + wxDDEClientList::compatibility_iterator clientNode = wxDDEClientObjects.GetFirst(); while (clientNode && !found) { wxDDEClient *object = clientNode->GetData(); @@ -269,7 +266,7 @@ static void DDEDeleteConnection(HCONV hConv) // Find a server from a service name static wxDDEServer *DDEFindServer(const wxString& s) { - wxDDEServerList::Node *node = wxDDEServerObjects.GetFirst(); + wxDDEServerList::compatibility_iterator node = wxDDEServerObjects.GetFirst(); wxDDEServer *found = NULL; while (node && !found) { @@ -328,11 +325,11 @@ wxDDEServer::~wxDDEServer() wxDDEServerObjects.DeleteObject(this); - wxDDEConnectionList::Node *node = m_connections.GetFirst(); + wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst(); while (node) { wxDDEConnection *connection = node->GetData(); - wxDDEConnectionList::Node *next = node->GetNext(); + wxDDEConnectionList::compatibility_iterator next = node->GetNext(); connection->SetConnected(false); connection->OnDisconnect(); // May delete the node implicitly node = next; @@ -343,7 +340,7 @@ wxDDEServer::~wxDDEServer() while (node) { wxDDEConnection *connection = node->GetData(); - wxDDEConnectionList::Node *next = node->GetNext(); + wxDDEConnectionList::compatibility_iterator next = node->GetNext(); delete connection; node = next; } @@ -356,7 +353,7 @@ wxConnectionBase *wxDDEServer::OnAcceptConnection(const wxString& /* topic */) wxDDEConnection *wxDDEServer::FindConnection(WXHCONV conv) { - wxDDEConnectionList::Node *node = m_connections.GetFirst(); + wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst(); wxDDEConnection *found = NULL; while (node && !found) { @@ -371,22 +368,21 @@ wxDDEConnection *wxDDEServer::FindConnection(WXHCONV conv) // Only delete the entry in the map, not the actual connection bool wxDDEServer::DeleteConnection(WXHCONV conv) { - wxDDEConnectionList::Node *node = m_connections.GetFirst(); - bool found = false; - while (node && !found) + wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst(); + while (node) { wxDDEConnection *connection = node->GetData(); if (connection->m_hConv == conv) { - found = true; - delete node; + m_connections.Erase(node); + return true; } else { node = node->GetNext(); } } - return found; + return false; } // ---------------------------------------------------------------------------- @@ -403,7 +399,7 @@ wxDDEClient::wxDDEClient() wxDDEClient::~wxDDEClient() { wxDDEClientObjects.DeleteObject(this); - wxDDEConnectionList::Node *node = m_connections.GetFirst(); + wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst(); while (node) { wxDDEConnection *connection = node->GetData(); @@ -451,7 +447,7 @@ wxConnectionBase *wxDDEClient::OnMakeConnection() wxDDEConnection *wxDDEClient::FindConnection(WXHCONV conv) { - wxDDEConnectionList::Node *node = m_connections.GetFirst(); + wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst(); wxDDEConnection *found = NULL; while (node && !found) { @@ -466,19 +462,18 @@ wxDDEConnection *wxDDEClient::FindConnection(WXHCONV conv) // Only delete the entry in the map, not the actual connection bool wxDDEClient::DeleteConnection(WXHCONV conv) { - wxDDEConnectionList::Node *node = m_connections.GetFirst(); - bool found = false; - while (node && !found) + wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst(); + while (node) { wxDDEConnection *connection = node->GetData(); if (connection->m_hConv == conv) { - found = true; - delete node; + m_connections.Erase(node); + return true; } else node = node->GetNext(); } - return found; + return false; } // ---------------------------------------------------------------------------- @@ -934,23 +929,21 @@ _DDECallback(WORD wType, // ---------------------------------------------------------------------------- // Atom table stuff -static HSZ DDEAddAtom(const wxString& string) +static HSZ DDEAddAtom(const wxString& str) { - HSZ atom = DDEAtomFromString(string); - wxAtomTable.Append(string, (wxObject *)atom); + HSZ atom = DDEAtomFromString(str); + wxAtomTable[str] = atom; return atom; } -static HSZ DDEGetAtom(const wxString& string) +static HSZ DDEGetAtom(const wxString& str) { - wxNode *node = wxAtomTable.Find(string); - if (node) - return (HSZ)node->GetData(); - else - { - DDEAddAtom(string); - return (HSZ)(wxAtomTable.Find(string)->GetData()); - } + wxAtomMap::iterator it = wxAtomTable.find(str); + + if (it != wxAtomTable.end()) + return it->second; + + return DDEAddAtom(str); } // atom <-> strings diff --git a/src/msw/volume.cpp b/src/msw/volume.cpp index c36b73379a..97723420c3 100644 --- a/src/msw/volume.cpp +++ b/src/msw/volume.cpp @@ -30,7 +30,9 @@ #if wxUSE_FSVOLUME #ifndef WX_PRECOMP - #include "wx/icon.h" + #if wxUSE_GUI + #include "wx/icon.h" + #endif #include "wx/intl.h" #endif // WX_PRECOMP @@ -287,9 +289,9 @@ static void BuildListFromNN(wxArrayString& list, NETRESOURCE* pResSrc, // Function: CompareFcn // Purpose: Used to sort the NN list alphabetically, case insensitive. //============================================================================= -static int CompareFcn(const wxString& first, const wxString& second) +static int CompareFcn(wxString* first, wxString* second) { - return wxStricmp(first.c_str(), second.c_str()); + return wxStricmp(first->c_str(), second->c_str()); } // CompareFcn //============================================================================= diff --git a/src/unix/mimetype.cpp b/src/unix/mimetype.cpp index 22d2b25d2b..1c6eb62aae 100644 --- a/src/unix/mimetype.cpp +++ b/src/unix/mimetype.cpp @@ -1821,7 +1821,8 @@ int wxMimeTypesManagerImpl::AddToMimeData(const wxString& strType, m_aEntries.Add(entry ? entry : new wxMimeTypeCommands); // change nIndex so we can use it below to add the extensions - nIndex = m_aExtensions.Add(wxEmptyString); + m_aExtensions.Add(wxEmptyString); + nIndex = m_aExtensions.size(); m_aDescriptions.Add(strDesc); } -- 2.45.2