added wxTLS_TYPE() macro
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55019 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
375a5d3a93
commit
64a044d5a6
67
configure
vendored
67
configure
vendored
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.in Id: configure.in 54853 2008-07-30 15:48:24Z SC .
|
||||
# From configure.in Id: configure.in 54996 2008-08-06 17:50:06Z VZ .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.61 for wxWidgets 2.9.0.
|
||||
#
|
||||
@ -40135,13 +40135,76 @@ _ACEOF
|
||||
{ echo "$as_me:$LINENO: WARNING: wxMutex won't be recursive on this platform" >&5
|
||||
echo "$as_me: WARNING: wxMutex won't be recursive on this platform" >&2;}
|
||||
fi
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for __thread keyword" >&5
|
||||
echo $ECHO_N "checking for __thread keyword... $ECHO_C" >&6; }
|
||||
if test "${wx_cv_cc___thread+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
static __thread int n = 0;
|
||||
static __thread int *p = 0;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
wx_cv_cc___thread=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
wx_cv_cc___thread=no
|
||||
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $wx_cv_cc___thread" >&5
|
||||
echo "${ECHO_T}$wx_cv_cc___thread" >&6; }
|
||||
|
||||
if test "$wx_cv_cc___thread" = "yes"; then
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE___THREAD_KEYWORD 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
if test "$wxUSE_THREADS" = "yes" ; then
|
||||
case "${host}" in
|
||||
x86_64-*-mingw32* )
|
||||
x86_64-*-mingw32* )
|
||||
;;
|
||||
*-*-mingw32* )
|
||||
{ echo "$as_me:$LINENO: checking if compiler supports -mthreads" >&5
|
||||
|
20
configure.in
20
configure.in
@ -4985,13 +4985,31 @@ if test "$TOOLKIT" != "MSW" -a "$USE_OS2" != 1; then
|
||||
AC_MSG_WARN([wxMutex won't be recursive on this platform])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl test for compiler thread-specific variables support
|
||||
AC_CACHE_CHECK([for __thread keyword],
|
||||
wx_cv_cc___thread,
|
||||
[
|
||||
AC_TRY_COMPILE([#include <pthread.h>],
|
||||
[
|
||||
static __thread int n = 0;
|
||||
static __thread int *p = 0;
|
||||
],
|
||||
wx_cv_cc___thread=yes,
|
||||
wx_cv_cc___thread=no
|
||||
)
|
||||
])
|
||||
|
||||
if test "$wx_cv_cc___thread" = "yes"; then
|
||||
AC_DEFINE(HAVE___THREAD_KEYWORD)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl from if !MSW
|
||||
else
|
||||
if test "$wxUSE_THREADS" = "yes" ; then
|
||||
case "${host}" in
|
||||
x86_64-*-mingw32* )
|
||||
x86_64-*-mingw32* )
|
||||
;;
|
||||
*-*-mingw32* )
|
||||
dnl check if the compiler accepts -mthreads
|
||||
|
73
include/wx/msw/tls.h
Normal file
73
include/wx/msw/tls.h
Normal file
@ -0,0 +1,73 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/unix/tls.h
|
||||
// Purpose: Win32 implementation of wxTlsValue<>
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2008-08-08
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_MSW_TLS_H_
|
||||
#define _WX_MSW_TLS_H_
|
||||
|
||||
#include "wx/log.h"
|
||||
|
||||
#include "wx/msw/wrapwin.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxTlsKey is a helper class encapsulating a TLS slot
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class wxTlsKey
|
||||
{
|
||||
public:
|
||||
// ctor allocates a new key
|
||||
wxTlsKey()
|
||||
{
|
||||
m_slot = ::TlsAlloc();
|
||||
if ( m_slot == TLS_OUT_OF_INDEXES )
|
||||
wxLogError("Creating TLS key failed");
|
||||
}
|
||||
|
||||
// return true if the key was successfully allocated
|
||||
bool IsOk() const { return m_slot != TLS_OUT_OF_INDEXES; }
|
||||
|
||||
// get the key value, there is no error return
|
||||
void *Get() const
|
||||
{
|
||||
return ::TlsGetValue(m_slot);
|
||||
}
|
||||
|
||||
// change the key value, return true if ok
|
||||
bool Set(void *value)
|
||||
{
|
||||
if ( !::TlsSetValue(m_slot, value) )
|
||||
{
|
||||
wxLogSysError(_("Failed to set TLS value"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// free the key
|
||||
~wxTlsKey()
|
||||
{
|
||||
if ( IsOk() )
|
||||
{
|
||||
if ( !::TlsFree(m_slot) )
|
||||
{
|
||||
wxLogDebug("TlsFree() failed: %08x", ::GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
DWORD m_slot;
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxTlsKey)
|
||||
};
|
||||
|
||||
#endif // _WX_MSW_TLS_H_
|
||||
|
@ -508,6 +508,11 @@ private:
|
||||
static size_t LenToImpl(size_t len) { return len; }
|
||||
static size_t PosFromImpl(size_t pos) { return pos; }
|
||||
|
||||
// we don't want to define this as an empty inline function as it could
|
||||
// result in noticeable (and quite unnecessary in non-UTF-8 build) slowdown
|
||||
// in debug build where the inline functions are not effectively inlined
|
||||
#define wxSTRING_INVALIDATE_INDEX_CACHE()
|
||||
|
||||
#else // wxUSE_UNICODE_UTF8
|
||||
|
||||
static wxCharBuffer ImplStr(const char* str,
|
||||
@ -522,14 +527,63 @@ private:
|
||||
static SubstrBufFromWC ImplStr(const wchar_t* str, size_t n)
|
||||
{ return ConvertStr(str, n, wxMBConvUTF8()); }
|
||||
|
||||
// this is an extremely simple cache used by PosToImpl()
|
||||
struct PosToImplCache
|
||||
{
|
||||
const wxString *str;
|
||||
size_t pos,
|
||||
impl;
|
||||
};
|
||||
|
||||
static PosToImplCache ms_cache;
|
||||
|
||||
size_t PosToImpl(size_t pos) const
|
||||
{
|
||||
if ( pos == 0 || pos == npos )
|
||||
return pos;
|
||||
else
|
||||
return (begin() + pos).impl() - m_impl.begin();
|
||||
|
||||
PosToImplCache& cache = ms_cache;
|
||||
if ( this == cache.str )
|
||||
{
|
||||
if ( pos == cache.pos )
|
||||
return cache.impl;
|
||||
|
||||
// TODO: is it worth complicating this function even further by going
|
||||
// backwards from the last position? it might be if we're just
|
||||
// before it...
|
||||
if ( cache.pos > pos )
|
||||
{
|
||||
cache.pos =
|
||||
cache.impl = 0;
|
||||
}
|
||||
}
|
||||
else // data for this string not cached
|
||||
{
|
||||
cache.str = this;
|
||||
cache.pos =
|
||||
cache.impl = 0;
|
||||
}
|
||||
|
||||
wxStringImpl::const_iterator i(m_impl.begin() + cache.impl);
|
||||
for ( size_t n = cache.pos; n < pos; n++ )
|
||||
wxStringOperations::IncIter(i);
|
||||
|
||||
cache.pos = pos;
|
||||
return cache.impl = i - m_impl.begin();
|
||||
}
|
||||
|
||||
void InvalidatePosToImplCache()
|
||||
{
|
||||
PosToImplCache& cache = ms_cache;
|
||||
if ( cache.str == this )
|
||||
{
|
||||
cache.pos =
|
||||
cache.impl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define wxSTRING_INVALIDATE_INDEX_CACHE() InvalidatePosToImplCache()
|
||||
|
||||
void PosLenToImpl(size_t pos, size_t len, size_t *implPos, size_t *implLen) const;
|
||||
|
||||
size_t LenToImpl(size_t len) const
|
||||
@ -737,6 +791,10 @@ public:
|
||||
size_t IterToImplPos(wxString::iterator i) const
|
||||
{ return wxStringImpl::const_iterator(i.impl()) - m_impl.begin(); }
|
||||
|
||||
iterator GetNthIter(size_t n)
|
||||
{ return iterator(this, m_impl.begin() + PosToImpl(n)); }
|
||||
const_iterator GetNthIter(size_t n) const
|
||||
{ return const_iterator(this, m_impl.begin() + PosToImpl(n)); }
|
||||
#else // !wxUSE_UNICODE_UTF8
|
||||
|
||||
class WXDLLIMPEXP_BASE iterator
|
||||
@ -788,6 +846,9 @@ public:
|
||||
const_iterator(const wxString *WXUNUSED(str), underlying_iterator ptr)
|
||||
: m_cur(ptr) {}
|
||||
};
|
||||
|
||||
iterator GetNthIter(size_t n) { return begin() + n; }
|
||||
const_iterator GetNthIter(size_t n) const { return begin() + n; }
|
||||
#endif // wxUSE_UNICODE_UTF8/!wxUSE_UNICODE_UTF8
|
||||
|
||||
#undef WX_STR_ITERATOR_TAG
|
||||
@ -1071,6 +1132,8 @@ public:
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( nSize < len )
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
// we can't use wxStringImpl::resize() for truncating the string as it
|
||||
// counts in bytes, not characters
|
||||
erase(nSize);
|
||||
@ -1110,11 +1173,7 @@ public:
|
||||
wxASSERT_MSG( empty(), _T("string not empty after call to Empty()?") );
|
||||
}
|
||||
// empty the string and free memory
|
||||
void Clear()
|
||||
{
|
||||
wxString tmp(wxEmptyString);
|
||||
swap(tmp);
|
||||
}
|
||||
void Clear() { clear(); }
|
||||
|
||||
// contents test
|
||||
// Is an ascii value
|
||||
@ -1127,17 +1186,32 @@ public:
|
||||
// data access (all indexes are 0 based)
|
||||
// read access
|
||||
wxUniChar at(size_t n) const
|
||||
{ return *(begin() + n); } // FIXME-UTF8: optimize?
|
||||
{ return wxStringOperations::DecodeChar(m_impl.begin() + PosToImpl(n)); }
|
||||
wxUniChar GetChar(size_t n) const
|
||||
{ return at(n); }
|
||||
// read/write access
|
||||
wxUniCharRef at(size_t n)
|
||||
{ return *(begin() + n); } // FIXME-UTF8: optimize?
|
||||
{ return *GetNthIter(n); }
|
||||
wxUniCharRef GetWritableChar(size_t n)
|
||||
{ return at(n); }
|
||||
// write access
|
||||
void SetChar(size_t n, wxUniChar ch)
|
||||
{ at(n) = ch; }
|
||||
void SetChar(size_t n, wxUniChar ch)
|
||||
{
|
||||
wxUniCharRef ref(at(n));
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
// if the new character takes the same number of bytes as the old one,
|
||||
// we can avoid invalidating the index cache and it's an important case
|
||||
// as it is exercised by a simple for loop using indices
|
||||
if ( wxStringOperations::GetUtf8CharLength(ref)
|
||||
!= wxStringOperations::GetUtf8CharLength(ch) )
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
}
|
||||
#endif // wxUSE_UNICODE_UTF8
|
||||
|
||||
ref = ch;
|
||||
}
|
||||
|
||||
// get last character
|
||||
wxUniChar Last() const
|
||||
@ -1426,20 +1500,33 @@ public:
|
||||
// overloaded assignment
|
||||
// from another wxString
|
||||
wxString& operator=(const wxString& stringSrc)
|
||||
{ if (&stringSrc != this) m_impl = stringSrc.m_impl; return *this; }
|
||||
{
|
||||
if ( this != &stringSrc )
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl = stringSrc.m_impl;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& operator=(const wxCStrData& cstr)
|
||||
{ return *this = cstr.AsString(); }
|
||||
// from a character
|
||||
wxString& operator=(wxUniChar ch)
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl = wxStringOperations::EncodeChar(ch);
|
||||
else
|
||||
#endif
|
||||
#endif // wxUSE_UNICODE_UTF8
|
||||
m_impl = (wxStringCharType)ch;
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& operator=(wxUniCharRef ch)
|
||||
{ return operator=((wxUniChar)ch); }
|
||||
wxString& operator=(char ch)
|
||||
@ -1452,15 +1539,48 @@ public:
|
||||
// so we need to compensate in that case
|
||||
#if wxUSE_STL_BASED_WXSTRING
|
||||
wxString& operator=(const char *psz)
|
||||
{ if (psz) m_impl = ImplStr(psz); else Clear(); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
if ( psz )
|
||||
m_impl = ImplStr(psz);
|
||||
else
|
||||
clear();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& operator=(const wchar_t *pwz)
|
||||
{ if (pwz) m_impl = ImplStr(pwz); else Clear(); return *this; }
|
||||
#else
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
if ( pwz )
|
||||
m_impl = ImplStr(pwz);
|
||||
else
|
||||
clear();
|
||||
|
||||
return *this;
|
||||
}
|
||||
#else // !wxUSE_STL_BASED_WXSTRING
|
||||
wxString& operator=(const char *psz)
|
||||
{ m_impl = ImplStr(psz); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl = ImplStr(psz);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& operator=(const wchar_t *pwz)
|
||||
{ m_impl = ImplStr(pwz); return *this; }
|
||||
#endif
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl = ImplStr(pwz);
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif // wxUSE_STL_BASED_WXSTRING/!wxUSE_STL_BASED_WXSTRING
|
||||
|
||||
wxString& operator=(const unsigned char *psz)
|
||||
{ return operator=((const char*)psz); }
|
||||
|
||||
@ -1600,7 +1720,7 @@ public:
|
||||
const wxChar *fmt = _T("%") wxLongLongFmtSpec _T("u");
|
||||
return (*this) << Format(fmt , ull);
|
||||
}
|
||||
#endif
|
||||
#endif // wxLongLong_t && !wxLongLongIsLong
|
||||
// insert a float into string
|
||||
wxString& operator<<(float f)
|
||||
{ return (*this) << Format(_T("%f"), f); }
|
||||
@ -1875,7 +1995,7 @@ public:
|
||||
#endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
|
||||
|
||||
// use Cmp()
|
||||
inline int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
|
||||
int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
|
||||
{ return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
|
||||
|
||||
// use length()
|
||||
@ -2020,36 +2140,71 @@ public:
|
||||
|
||||
// same as `this_string = str'
|
||||
wxString& assign(const wxString& str)
|
||||
{ m_impl = str.m_impl; return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl = str.m_impl;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& assign(const wxString& str, size_t len)
|
||||
{
|
||||
m_impl.assign(str.m_impl, 0, str.LenToImpl(len));
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.assign(str.m_impl, 0, str.LenToImpl(len));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// same as ` = str[pos..pos + n]
|
||||
wxString& assign(const wxString& str, size_t pos, size_t n)
|
||||
{
|
||||
size_t from, len;
|
||||
str.PosLenToImpl(pos, n, &from, &len);
|
||||
m_impl.assign(str.m_impl, from, len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
str.PosLenToImpl(pos, n, &from, &len);
|
||||
m_impl.assign(str.m_impl, from, len);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// same as `= first n (or all if n == npos) characters of sz'
|
||||
wxString& assign(const char *sz)
|
||||
{ m_impl.assign(ImplStr(sz)); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.assign(ImplStr(sz));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& assign(const wchar_t *sz)
|
||||
{ m_impl.assign(ImplStr(sz)); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.assign(ImplStr(sz));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& assign(const char *sz, size_t n)
|
||||
{
|
||||
SubstrBufFromMB str(ImplStr(sz, n));
|
||||
m_impl.assign(str.data, str.len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromMB str(ImplStr(sz, n));
|
||||
m_impl.assign(str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& assign(const wchar_t *sz, size_t n)
|
||||
{
|
||||
SubstrBufFromWC str(ImplStr(sz, n));
|
||||
m_impl.assign(str.data, str.len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromWC str(ImplStr(sz, n));
|
||||
m_impl.assign(str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& assign(const wxCStrData& str)
|
||||
@ -2068,6 +2223,8 @@ public:
|
||||
// same as `= n copies of ch'
|
||||
wxString& assign(size_t n, wxUniChar ch)
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl.assign(wxStringOperations::EncodeNChars(n, ch));
|
||||
@ -2088,7 +2245,13 @@ public:
|
||||
|
||||
// assign from first to last
|
||||
wxString& assign(const_iterator first, const_iterator last)
|
||||
{ m_impl.assign(first.impl(), last.impl()); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.assign(first.impl(), last.impl());
|
||||
|
||||
return *this;
|
||||
}
|
||||
#if WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
|
||||
wxString& assign(const char *first, const char *last)
|
||||
{ return assign(first, last - first); }
|
||||
@ -2121,35 +2284,61 @@ public:
|
||||
|
||||
// insert another string
|
||||
wxString& insert(size_t nPos, const wxString& str)
|
||||
{ insert(begin() + nPos, str.begin(), str.end()); return *this; }
|
||||
{ insert(GetNthIter(nPos), str.begin(), str.end()); return *this; }
|
||||
// insert n chars of str starting at nStart (in str)
|
||||
wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
|
||||
{
|
||||
size_t from, len;
|
||||
str.PosLenToImpl(nStart, n, &from, &len);
|
||||
m_impl.insert(PosToImpl(nPos), str.m_impl, from, len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
str.PosLenToImpl(nStart, n, &from, &len);
|
||||
m_impl.insert(PosToImpl(nPos), str.m_impl, from, len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// insert first n (or all if n == npos) characters of sz
|
||||
wxString& insert(size_t nPos, const char *sz)
|
||||
{ m_impl.insert(PosToImpl(nPos), ImplStr(sz)); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.insert(PosToImpl(nPos), ImplStr(sz));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& insert(size_t nPos, const wchar_t *sz)
|
||||
{ m_impl.insert(PosToImpl(nPos), ImplStr(sz)); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.insert(PosToImpl(nPos), ImplStr(sz)); return *this;
|
||||
}
|
||||
|
||||
wxString& insert(size_t nPos, const char *sz, size_t n)
|
||||
{
|
||||
SubstrBufFromMB str(ImplStr(sz, n));
|
||||
m_impl.insert(PosToImpl(nPos), str.data, str.len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromMB str(ImplStr(sz, n));
|
||||
m_impl.insert(PosToImpl(nPos), str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& insert(size_t nPos, const wchar_t *sz, size_t n)
|
||||
{
|
||||
SubstrBufFromWC str(ImplStr(sz, n));
|
||||
m_impl.insert(PosToImpl(nPos), str.data, str.len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromWC str(ImplStr(sz, n));
|
||||
m_impl.insert(PosToImpl(nPos), str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// insert n copies of ch
|
||||
wxString& insert(size_t nPos, size_t n, wxUniChar ch)
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl.insert(PosToImpl(nPos), wxStringOperations::EncodeNChars(n, ch));
|
||||
@ -2158,8 +2347,11 @@ public:
|
||||
m_impl.insert(PosToImpl(nPos), n, (wxStringCharType)ch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator insert(iterator it, wxUniChar ch)
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( !ch.IsAscii() )
|
||||
{
|
||||
@ -2171,8 +2363,14 @@ public:
|
||||
#endif
|
||||
return iterator(this, m_impl.insert(it.impl(), (wxStringCharType)ch));
|
||||
}
|
||||
|
||||
void insert(iterator it, const_iterator first, const_iterator last)
|
||||
{ m_impl.insert(it.impl(), first.impl(), last.impl()); }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.insert(it.impl(), first.impl(), last.impl());
|
||||
}
|
||||
|
||||
#if WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
|
||||
void insert(iterator it, const char *first, const char *last)
|
||||
{ insert(it - begin(), first, last - first); }
|
||||
@ -2184,6 +2382,8 @@ public:
|
||||
|
||||
void insert(iterator it, size_type n, wxUniChar ch)
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl.insert(IterToImplPos(it), wxStringOperations::EncodeNChars(n, ch));
|
||||
@ -2195,139 +2395,225 @@ public:
|
||||
// delete characters from nStart to nStart + nLen
|
||||
wxString& erase(size_type pos = 0, size_type n = npos)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(pos, n, &from, &len);
|
||||
m_impl.erase(from, len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
PosLenToImpl(pos, n, &from, &len);
|
||||
m_impl.erase(from, len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// delete characters from first up to last
|
||||
iterator erase(iterator first, iterator last)
|
||||
{ return iterator(this, m_impl.erase(first.impl(), last.impl())); }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
return iterator(this, m_impl.erase(first.impl(), last.impl()));
|
||||
}
|
||||
|
||||
iterator erase(iterator first)
|
||||
{ return iterator(this, m_impl.erase(first.impl())); }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
return iterator(this, m_impl.erase(first.impl()));
|
||||
}
|
||||
|
||||
#ifdef wxSTRING_BASE_HASNT_CLEAR
|
||||
void clear() { erase(); }
|
||||
#else
|
||||
void clear() { m_impl.clear(); }
|
||||
void clear()
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
// replaces the substring of length nLen starting at nStart
|
||||
wxString& replace(size_t nStart, size_t nLen, const char* sz)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, ImplStr(sz));
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, ImplStr(sz));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(size_t nStart, size_t nLen, const wchar_t* sz)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, ImplStr(sz));
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, ImplStr(sz));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// replaces the substring of length nLen starting at nStart
|
||||
wxString& replace(size_t nStart, size_t nLen, const wxString& str)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, str.m_impl);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, str.m_impl);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// replaces the substring with nCount copies of ch
|
||||
wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxUniChar ch)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl.replace(from, len, wxStringOperations::EncodeNChars(nCount, ch));
|
||||
else
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl.replace(from, len, wxStringOperations::EncodeNChars(nCount, ch));
|
||||
else
|
||||
#endif
|
||||
m_impl.replace(from, len, nCount, (wxStringCharType)ch);
|
||||
return *this;
|
||||
m_impl.replace(from, len, nCount, (wxStringCharType)ch);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// replaces a substring with another substring
|
||||
wxString& replace(size_t nStart, size_t nLen,
|
||||
const wxString& str, size_t nStart2, size_t nLen2)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from2, len2;
|
||||
str.PosLenToImpl(nStart2, nLen2, &from2, &len2);
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
|
||||
m_impl.replace(from, len, str.m_impl, from2, len2);
|
||||
return *this;
|
||||
size_t from2, len2;
|
||||
str.PosLenToImpl(nStart2, nLen2, &from2, &len2);
|
||||
|
||||
m_impl.replace(from, len, str.m_impl, from2, len2);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// replaces the substring with first nCount chars of sz
|
||||
wxString& replace(size_t nStart, size_t nLen,
|
||||
const char* sz, size_t nCount)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromMB str(ImplStr(sz, nCount));
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
|
||||
m_impl.replace(from, len, str.data, str.len);
|
||||
return *this;
|
||||
SubstrBufFromMB str(ImplStr(sz, nCount));
|
||||
|
||||
m_impl.replace(from, len, str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(size_t nStart, size_t nLen,
|
||||
const wchar_t* sz, size_t nCount)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromWC str(ImplStr(sz, nCount));
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
|
||||
m_impl.replace(from, len, str.data, str.len);
|
||||
return *this;
|
||||
SubstrBufFromWC str(ImplStr(sz, nCount));
|
||||
|
||||
m_impl.replace(from, len, str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(size_t nStart, size_t nLen,
|
||||
const wxString& s, size_t nCount)
|
||||
{
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, s.m_impl.c_str(), s.LenToImpl(nCount));
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t from, len;
|
||||
PosLenToImpl(nStart, nLen, &from, &len);
|
||||
m_impl.replace(from, len, s.m_impl.c_str(), s.LenToImpl(nCount));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last, const char* s)
|
||||
{ m_impl.replace(first.impl(), last.impl(), ImplStr(s)); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.replace(first.impl(), last.impl(), ImplStr(s));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last, const wchar_t* s)
|
||||
{ m_impl.replace(first.impl(), last.impl(), ImplStr(s)); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.replace(first.impl(), last.impl(), ImplStr(s));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last, const char* s, size_type n)
|
||||
{
|
||||
SubstrBufFromMB str(ImplStr(s, n));
|
||||
m_impl.replace(first.impl(), last.impl(), str.data, str.len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromMB str(ImplStr(s, n));
|
||||
m_impl.replace(first.impl(), last.impl(), str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last, const wchar_t* s, size_type n)
|
||||
{
|
||||
SubstrBufFromWC str(ImplStr(s, n));
|
||||
m_impl.replace(first.impl(), last.impl(), str.data, str.len);
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
SubstrBufFromWC str(ImplStr(s, n));
|
||||
m_impl.replace(first.impl(), last.impl(), str.data, str.len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last, const wxString& s)
|
||||
{ m_impl.replace(first.impl(), last.impl(), s.m_impl); return *this; }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.replace(first.impl(), last.impl(), s.m_impl);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last, size_type n, wxUniChar ch)
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl.replace(first.impl(), last.impl(),
|
||||
wxStringOperations::EncodeNChars(n, ch));
|
||||
else
|
||||
if ( !ch.IsAscii() )
|
||||
m_impl.replace(first.impl(), last.impl(),
|
||||
wxStringOperations::EncodeNChars(n, ch));
|
||||
else
|
||||
#endif
|
||||
m_impl.replace(first.impl(), last.impl(), n, (wxStringCharType)ch);
|
||||
return *this;
|
||||
m_impl.replace(first.impl(), last.impl(), n, (wxStringCharType)ch);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last,
|
||||
const_iterator first1, const_iterator last1)
|
||||
{
|
||||
m_impl.replace(first.impl(), last.impl(), first1.impl(), last1.impl());
|
||||
return *this;
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.replace(first.impl(), last.impl(), first1.impl(), last1.impl());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
wxString& replace(iterator first, iterator last,
|
||||
const char *first1, const char *last1)
|
||||
{ replace(first, last, first1, last1 - first1); return *this; }
|
||||
@ -2337,7 +2623,11 @@ public:
|
||||
|
||||
// swap two strings
|
||||
void swap(wxString& str)
|
||||
{ m_impl.swap(str.m_impl); }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.swap(str.m_impl);
|
||||
}
|
||||
|
||||
// find a substring
|
||||
size_t find(const wxString& str, size_t nStart = 0) const
|
||||
@ -2673,11 +2963,23 @@ private:
|
||||
#if !wxUSE_STL_BASED_WXSTRING
|
||||
// helpers for wxStringBuffer and wxStringBufferLength
|
||||
wxStringCharType *DoGetWriteBuf(size_t nLen)
|
||||
{ return m_impl.DoGetWriteBuf(nLen); }
|
||||
{
|
||||
return m_impl.DoGetWriteBuf(nLen);
|
||||
}
|
||||
|
||||
void DoUngetWriteBuf()
|
||||
{ m_impl.DoUngetWriteBuf(); }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.DoUngetWriteBuf();
|
||||
}
|
||||
|
||||
void DoUngetWriteBuf(size_t nLen)
|
||||
{ m_impl.DoUngetWriteBuf(nLen); }
|
||||
{
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
m_impl.DoUngetWriteBuf(nLen);
|
||||
}
|
||||
#endif // !wxUSE_STL_BASED_WXSTRING
|
||||
|
||||
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
|
||||
|
72
include/wx/tls.h
Normal file
72
include/wx/tls.h
Normal file
@ -0,0 +1,72 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/tls.h
|
||||
// Purpose: Implementation of thread local storage
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2008-08-08
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_TLS_H_
|
||||
#define _WX_TLS_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// check for compiler support of thread-specific variables
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef HAVE___THREAD_KEYWORD
|
||||
#define wxHAS_COMPILER_TLS
|
||||
#define wxTHREAD_SPECIFIC_DECL __thread
|
||||
#elif wxCHECK_VISUALC_VERSION(7)
|
||||
#define wxHAS_COMPILER_TLS
|
||||
#define wxTHREAD_SPECIFIC_DECL __declspec(thread)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// define wxTLS_TYPE()
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef wxHAS_COMPILER_TLS
|
||||
#define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
|
||||
#else // !wxHAS_COMPILER_TLS
|
||||
#ifdef __WXMSW__
|
||||
#include "wx/msw/tls.h"
|
||||
#elif defined(__UNIX__)
|
||||
#include "wx/unix/tls.h"
|
||||
#else
|
||||
// TODO: we could emulate TLS for such platforms...
|
||||
#error Neither compiler nor OS support thread-specific variables.
|
||||
#endif
|
||||
|
||||
// wxTlsValue<T> represents a thread-specific value of type T
|
||||
template <typename T>
|
||||
class wxTlsValue
|
||||
{
|
||||
public:
|
||||
typedef T ValueType;
|
||||
|
||||
wxTlsValue() { *this = static_cast<T>(0); }
|
||||
|
||||
wxTlsValue& operator=(T value)
|
||||
{
|
||||
m_key.Set(wxUIntToPtr(value));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator T() const { return wxPtrToUInt(m_key.Get()); }
|
||||
|
||||
private:
|
||||
wxTlsKey m_key;
|
||||
|
||||
DECLARE_NO_COPY_TEMPLATE_CLASS(wxTlsValue, T)
|
||||
};
|
||||
|
||||
#define wxTLS_TYPE(T) wxTlsValue<T>
|
||||
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
|
||||
|
||||
#endif // _WX_TLS_H_
|
||||
|
70
include/wx/unix/tls.h
Normal file
70
include/wx/unix/tls.h
Normal file
@ -0,0 +1,70 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/unix/tls.h
|
||||
// Purpose: Pthreads implementation of wxTlsValue<>
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2008-08-08
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_UNIX_TLS_H_
|
||||
#define _WX_UNIX_TLS_H_
|
||||
|
||||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxTlsKey is a helper class encapsulating the TLS value index
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class wxTlsKey
|
||||
{
|
||||
public:
|
||||
// ctor allocates a new key
|
||||
wxTlsKey()
|
||||
{
|
||||
int rc = pthread_key_create(&m_key, NULL);
|
||||
if ( rc )
|
||||
wxLogSysError(_("Creating TLS key failed"), rc);
|
||||
}
|
||||
|
||||
// return true if the key was successfully allocated
|
||||
bool IsOk() const { return m_key != 0; }
|
||||
|
||||
// get the key value, there is no error return
|
||||
void *Get() const
|
||||
{
|
||||
return pthread_getspecific(m_key);
|
||||
}
|
||||
|
||||
// change the key value, return true if ok
|
||||
bool Set(void *value)
|
||||
{
|
||||
int rc = pthread_setspecific(m_key, value);
|
||||
if ( rc )
|
||||
{
|
||||
wxLogSysError(_("Failed to set TLS value"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// free the key
|
||||
~wxTlsKey()
|
||||
{
|
||||
if ( IsOk() )
|
||||
pthread_key_delete(m_key);
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_key_t m_key;
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxTlsKey)
|
||||
};
|
||||
|
||||
#endif // _WX_UNIX_TLS_H_
|
||||
|
27
interface/wx/tls.h
Normal file
27
interface/wx/tls.h
Normal file
@ -0,0 +1,27 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/tls.h
|
||||
// Purpose: wxTLS_TYPE()
|
||||
// Author: Vadim Zeitlin
|
||||
// RCS-ID: $Id$
|
||||
// Licence: wxWindows license
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Macro to be used for thread-specific variables declarations.
|
||||
|
||||
This macro can be used to define thread-specific variables of the specified
|
||||
@a type. Such variables must be global or static. Example of use:
|
||||
@code
|
||||
struct PerThreadData
|
||||
{
|
||||
... data which will be different for every thread ...
|
||||
};
|
||||
|
||||
static wxTLS_TYPE(PerThreadData *) s_threadPtr;
|
||||
@endcode
|
||||
|
||||
Currently only types of size less than size of a pointer are supported.
|
||||
This limitation will be lifted in the future.
|
||||
*/
|
||||
#define wxTLS_TYPE(type)
|
||||
|
@ -756,6 +756,10 @@
|
||||
* Define if you have pthread_cleanup_push/pop()
|
||||
*/
|
||||
#undef wxHAVE_PTHREAD_CLEANUP
|
||||
/*
|
||||
* Define if compiler has __thread keyword.
|
||||
*/
|
||||
#undef HAVE___THREAD_KEYWORD
|
||||
|
||||
/* compatibility */
|
||||
/*
|
||||
|
@ -58,6 +58,10 @@
|
||||
//According to STL _must_ be a -1 size_t
|
||||
const size_t wxString::npos = (size_t) -1;
|
||||
|
||||
#if wxUSE_UNICODE_UTF8
|
||||
wxString::PosToImplCache wxString::ms_cache;
|
||||
#endif // wxUSE_UNICODE_UTF8
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// global functions
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1237,6 +1241,8 @@ size_t wxString::Replace(const wxString& strOld,
|
||||
wxCHECK_MSG( !strOld.empty(), 0,
|
||||
_T("wxString::Replace(): invalid parameter") );
|
||||
|
||||
wxSTRING_INVALIDATE_INDEX_CACHE();
|
||||
|
||||
size_t uiCount = 0; // count of replacements made
|
||||
|
||||
// optimize the special common case: replacement of one character by
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#include "wx/tls.h"
|
||||
|
||||
#if defined(__UNIX__)
|
||||
#define HAVE_PTHREAD
|
||||
#include <pthread.h>
|
||||
@ -171,3 +173,18 @@ BENCHMARK_FUNC(BoostTLS)
|
||||
}
|
||||
|
||||
#endif // HAVE_BOOST_THREAD
|
||||
|
||||
BENCHMARK_FUNC(wxTLS)
|
||||
{
|
||||
static wxTLS_TYPE(int) s_global;
|
||||
|
||||
for ( int n = 0; n < NUM_ITER; n++ )
|
||||
{
|
||||
if ( n % 2 )
|
||||
s_global = 0;
|
||||
else
|
||||
s_global = n;
|
||||
}
|
||||
|
||||
return !s_global;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user