anystr.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/anystr.h
  3. // Purpose: wxAnyStrPtr class declaration
  4. // Author: Vadim Zeitlin
  5. // Created: 2009-03-23
  6. // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
  7. // Licence: wxWindows licence
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #ifndef _WX_ANYSTR_H_
  10. #define _WX_ANYSTR_H_
  11. #include "wx/string.h"
  12. // ----------------------------------------------------------------------------
  13. // wxAnyStrPtr
  14. //
  15. // Notice that this is an internal and intentionally not documented class. It
  16. // is only used by wxWidgets itself to ensure compatibility with previous
  17. // versions and shouldn't be used by user code. When you see a function
  18. // returning it you should just know that you can treat it as a string pointer.
  19. // ----------------------------------------------------------------------------
  20. // This is a helper class convertible to either narrow or wide string pointer.
  21. // It is similar to wxCStrData but, unlike it, can be NULL which is required to
  22. // represent the return value of wxDateTime::ParseXXX() methods for example.
  23. //
  24. // NB: this class is fully inline and so doesn't need to be DLL-exported
  25. class wxAnyStrPtr
  26. {
  27. public:
  28. // ctors: this class must be created from the associated string or using
  29. // its default ctor for an invalid NULL-like object; notice that it is
  30. // immutable after creation.
  31. // ctor for invalid pointer
  32. wxAnyStrPtr()
  33. : m_str(NULL)
  34. {
  35. }
  36. // ctor for valid pointer into the given string (whose lifetime must be
  37. // greater than ours and which should remain constant while we're used)
  38. wxAnyStrPtr(const wxString& str, const wxString::const_iterator& iter)
  39. : m_str(&str),
  40. m_iter(iter)
  41. {
  42. }
  43. // default copy ctor is ok and so is default dtor, in particular we do not
  44. // free the string
  45. // various operators meant to make this class look like a superposition of
  46. // char* and wchar_t*
  47. // this one is needed to allow boolean expressions involving these objects,
  48. // e.g. "if ( FuncReturningAnyStrPtr() && ... )" (unfortunately using
  49. // unspecified_bool_type here wouldn't help with ambiguity between all the
  50. // different conversions to pointers)
  51. operator bool() const { return m_str != NULL; }
  52. // at least VC6 and VC7 also need this one or they complain about ambiguity
  53. // for !anystr expressions
  54. bool operator!() const { return !((bool)*this); }
  55. // and these are the conversions operator which allow to assign the result
  56. // of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*)
  57. operator const char *() const
  58. {
  59. if ( !m_str )
  60. return NULL;
  61. // check if the string is convertible to char at all
  62. //
  63. // notice that this pointer points into wxString internal buffer
  64. // containing its char* representation and so it can be kept for as
  65. // long as wxString is not modified -- which is long enough for our
  66. // needs
  67. const char *p = m_str->c_str().AsChar();
  68. if ( *p )
  69. {
  70. // find the offset of the character corresponding to this iterator
  71. // position in bytes: we don't have any direct way to do it so we
  72. // need to redo the conversion again for the part of the string
  73. // before the iterator to find its length in bytes in current
  74. // locale
  75. //
  76. // NB: conversion won't fail as it succeeded for the entire string
  77. p += strlen(wxString(m_str->begin(), m_iter).mb_str());
  78. }
  79. //else: conversion failed, return "" as we can't do anything else
  80. return p;
  81. }
  82. operator const wchar_t *() const
  83. {
  84. if ( !m_str )
  85. return NULL;
  86. // no complications with wide strings (as long as we discount
  87. // surrogates as we do for now)
  88. //
  89. // just remember that this works as long as wxString keeps an internal
  90. // buffer with its wide wide char representation, just as with AsChar()
  91. // above
  92. return m_str->c_str().AsWChar() + (m_iter - m_str->begin());
  93. }
  94. // Because the objects of this class are only used as return type for
  95. // functions which can return NULL we can skip providing dereferencing
  96. // operators: the code using this class must test it for NULL first and if
  97. // it does anything else with it it has to assign it to either char* or
  98. // wchar_t* itself, before dereferencing.
  99. //
  100. // IOW this
  101. //
  102. // if ( *FuncReturningAnyStrPtr() )
  103. //
  104. // is invalid because it could crash. And this
  105. //
  106. // const char *p = FuncReturningAnyStrPtr();
  107. // if ( p && *p )
  108. //
  109. // already works fine.
  110. private:
  111. // the original string and the position in it we correspond to, if the
  112. // string is NULL this object is NULL pointer-like
  113. const wxString * const m_str;
  114. const wxString::const_iterator m_iter;
  115. wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr);
  116. };
  117. #endif // _WX_ANYSTR_H_