]>
Commit | Line | Data |
---|---|---|
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 | #ifdef __VISUALC6__ | |
65 | // FIXME-VC6: it also needs this one or it complains about ambiguity | |
66 | bool operator!() const { return !((bool)*this); } | |
67 | #endif // __VISUALC6__ | |
68 | ||
69 | ||
70 | // and these are the conversions operator which allow to assign the result | |
71 | // of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*) | |
72 | operator const char *() const | |
73 | { | |
74 | if ( !m_str ) | |
75 | return NULL; | |
76 | ||
77 | // check if the string is convertible to char at all | |
78 | // | |
79 | // notice that this pointer points into wxString internal buffer | |
80 | // containing its char* representation and so it can be kept for as | |
81 | // long as wxString is not modified -- which is long enough for our | |
82 | // needs | |
83 | const char *p = m_str->c_str().AsChar(); | |
84 | if ( *p ) | |
85 | { | |
86 | // find the offset of the character corresponding to this iterator | |
87 | // position in bytes: we don't have any direct way to do it so we | |
88 | // need to redo the conversion again for the part of the string | |
89 | // before the iterator to find its length in bytes in current | |
90 | // locale | |
91 | // | |
92 | // NB: conversion won't fail as it succeeded for the entire string | |
93 | p += strlen(wxString(m_str->begin(), m_iter).mb_str()); | |
94 | } | |
95 | //else: conversion failed, return "" as we can't do anything else | |
96 | ||
97 | return p; | |
98 | } | |
99 | ||
100 | operator const wchar_t *() const | |
101 | { | |
102 | if ( !m_str ) | |
103 | return NULL; | |
104 | ||
105 | // no complications with wide strings (as long as we discount | |
106 | // surrogates as we do for now) | |
107 | // | |
108 | // just remember that this works as long as wxString keeps an internal | |
109 | // buffer with its wide wide char representation, just as with AsChar() | |
110 | // above | |
111 | return m_str->c_str().AsWChar() + (m_iter - m_str->begin()); | |
112 | } | |
113 | ||
114 | // Because the objects of this class are only used as return type for | |
115 | // functions which can return NULL 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 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 offset in it we correspond to, if the string | |
133 | // 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_CLASS(wxAnyStrPtr); | |
138 | }; | |
139 | ||
140 | // FIXME-VC6: expressions involving logical operations are not compiled | |
141 | // correctly without these operators | |
142 | #ifdef __VISUALC6__ | |
143 | inline bool operator||(const wxAnyStrPtr& p, bool v) { return (bool)p || v; } | |
144 | inline bool operator||(bool v, const wxAnyStrPtr& p) { return v || (bool)p; } | |
145 | inline bool operator&&(const wxAnyStrPtr& p, bool v) { return (bool)p && v; } | |
146 | inline bool operator&&(bool v, const wxAnyStrPtr& p) { return v && (bool)p; } | |
147 | #endif // __VISUALC6__ | |
148 | ||
149 | #endif // _WX_ANYSTR_H_ | |
150 |