// not by the compiler), the global s_cache variable could be not yet
// initialized when a ctor of another global object is executed and if that
// ctor uses any wxString methods, bad things happen
- //
- // also note that for the same reason this function _is_ MT-safe: we know
- // it's going to be called during the program startup (currently during
- // globals initialization but even if they ever stop using wxString, it would
- // still be called by wxInitialize()), i.e. before any threads are created
static Cache& GetCache()
{
static wxTLS_TYPE(Cache) s_cache;
static Cache::Element *GetCacheEnd() { return GetCacheBegin() + Cache::SIZE; }
static unsigned& LastUsedCacheElement() { return GetCache().lastUsed; }
+ // this helper struct is used to ensure that GetCache() is called during
+ // static initialization time, i.e. before any threads creation, as otherwise
+ // the static s_cache construction inside GetCache() wouldn't be MT-safe
+ friend struct wxStrCacheInitializer;
+
+ // this is used in debug builds only to provide a convenient function,
+ // callable from a debugger, to show the cache contents
friend struct wxStrCacheDumper;
// uncomment this to have access to some profiling statistics on program
lenhits; // number of cache hits in length()
} ms_cacheStats;
- friend struct ShowCacheStats;
+ friend struct wxStrCacheStatsDumper;
#define wxCACHE_PROFILE_FIELD_INC(field) ms_cacheStats.field++
#define wxCACHE_PROFILE_FIELD_ADD(field, val) ms_cacheStats.field += (val)
// used for length caching only so far, i.e. it doesn't count as a hit
// from our point of view
if ( cache->pos )
+ {
wxCACHE_PROFILE_FIELD_INC(poshits);
+ }
if ( pos == cache->pos )
return cache->impl;
#else
#define WX_STR_ITERATOR_TAG std::random_access_iterator_tag
#endif
- #define WX_STR_ITERATOR_CATEGORY typedef WX_STR_ITERATOR_TAG iterator_category;
+ #define WX_DEFINE_ITERATOR_CATEGORY(cat) typedef cat iterator_category;
#else
// not defining iterator_category at all in this case is better than defining
// it as some dummy type -- at least it results in more intelligible error
// messages
- #define WX_STR_ITERATOR_CATEGORY
+ #define WX_DEFINE_ITERATOR_CATEGORY(cat)
#endif
#define WX_STR_ITERATOR_IMPL(iterator_name, pointer_type, reference_type) \
private: \
typedef wxStringImpl::iterator_name underlying_iterator; \
public: \
- WX_STR_ITERATOR_CATEGORY \
+ WX_DEFINE_ITERATOR_CATEGORY(WX_STR_ITERATOR_TAG) \
typedef wxUniChar value_type; \
typedef int difference_type; \
typedef reference_type reference; \
public:
typedef T iterator_type;
- typedef typename T::iterator_category iterator_category;
+ WX_DEFINE_ITERATOR_CATEGORY(typename T::iterator_category)
typedef typename T::value_type value_type;
typedef typename T::difference_type difference_type;
typedef typename T::reference reference;