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<wxString>. Made wxBase compile when wxUSE_STL=1. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21768 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
19
include/wx/afterstd.h
Normal file
19
include/wx/afterstd.h
Normal file
@@ -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 <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
See the comments in beforestd.h.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
@@ -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
|
||||
|
@@ -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; \
|
||||
} \
|
||||
} \
|
||||
|
321
include/wx/arrstr.h
Normal file
321
include/wx/arrstr.h
Normal file
@@ -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 <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// 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
|
38
include/wx/beforestd.h
Normal file
38
include/wx/beforestd.h
Normal file
@@ -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 <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// 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
|
@@ -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;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "wx/defs.h"
|
||||
#include "wx/string.h"
|
||||
#include "wx/arrstr.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
|
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#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
|
||||
#define MILLISECONDS_PER_DAY 86400000l
|
||||
|
||||
// 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
|
||||
// ============================================================================
|
||||
|
@@ -18,6 +18,7 @@
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/string.h"
|
||||
#include "wx/arrstr.h"
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -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 <vector>
|
||||
#include <algorithm>
|
||||
#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<T> \
|
||||
{ \
|
||||
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
|
||||
|
@@ -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
|
||||
|
@@ -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; }
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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_
|
||||
|
||||
|
@@ -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,25 +38,18 @@
|
||||
#include "wx/object.h"
|
||||
#include "wx/string.h"
|
||||
|
||||
class WXDLLIMPEXP_BASE wxObjectListNode;
|
||||
typedef wxObjectListNode wxNode;
|
||||
#if wxUSE_STL
|
||||
#include "wx/beforestd.h"
|
||||
#include <list>
|
||||
#include "wx/afterstd.h"
|
||||
#if defined(__WXMSW__) && defined(__MINGW32__)
|
||||
#include "wx/msw/winundef.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// undef it to get rid of old, deprecated functions
|
||||
#define wxLIST_COMPATIBILITY
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// constants
|
||||
// -----------------------------------------------------------------------------
|
||||
enum wxKeyType
|
||||
{
|
||||
wxKEY_NONE,
|
||||
wxKEY_INTEGER,
|
||||
wxKEY_STRING
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// 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
|
||||
@@ -65,9 +59,183 @@ extern "C"
|
||||
typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2);
|
||||
}
|
||||
|
||||
class WXDLLIMPEXP_BASE wxObjectListNode;
|
||||
typedef wxObjectListNode wxNode;
|
||||
|
||||
//
|
||||
typedef int (* LINKAGEMODE wxListIterateFunction)(void *current);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if !defined(wxENUM_KEY_TYPE_DEFINED)
|
||||
#define wxENUM_KEY_TYPE_DEFINED
|
||||
|
||||
enum wxKeyType
|
||||
{
|
||||
wxKEY_NONE,
|
||||
wxKEY_INTEGER,
|
||||
wxKEY_STRING
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if wxUSE_STL
|
||||
|
||||
#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<elT> \
|
||||
{ \
|
||||
public: \
|
||||
class dummy; \
|
||||
\
|
||||
struct compatibility_iterator \
|
||||
{ \
|
||||
typedef std::list<elT>::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<elT>::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 <wx/listimpl.cpp>
|
||||
#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__
|
||||
|
@@ -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
|
||||
|
@@ -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; }
|
||||
|
||||
|
@@ -199,6 +199,15 @@
|
||||
// global features
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Set wxUSE_STL to 1 to derive wxList(Foo) and wxArray(Foo) from
|
||||
// std::list<Foo*> and std::vector<Foo*>, 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.
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -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
|
||||
|
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "wx/object.h"
|
||||
#include "wx/string.h"
|
||||
#include "wx/arrstr.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user