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