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