williamr@4
|
1 |
/*
|
williamr@4
|
2 |
* Copyright (c) 1997-1999
|
williamr@4
|
3 |
* Silicon Graphics Computer Systems, Inc.
|
williamr@4
|
4 |
*
|
williamr@4
|
5 |
* Copyright (c) 1999
|
williamr@4
|
6 |
* Boris Fomitchev
|
williamr@4
|
7 |
*
|
williamr@4
|
8 |
* Copyright (c) 2003
|
williamr@4
|
9 |
* Francois Dumont
|
williamr@4
|
10 |
*
|
williamr@4
|
11 |
* This material is provided "as is", with absolutely no warranty expressed
|
williamr@4
|
12 |
* or implied. Any use is at your own risk.
|
williamr@4
|
13 |
*
|
williamr@4
|
14 |
* Permission to use or copy this software for any purpose is hereby granted
|
williamr@4
|
15 |
* without fee, provided the above notices are retained on all copies.
|
williamr@4
|
16 |
* Permission to modify the code and to distribute modified code is granted,
|
williamr@4
|
17 |
* provided the above notices are retained, and a notice that the code was
|
williamr@4
|
18 |
* modified is included with the above copyright notice.
|
williamr@4
|
19 |
*
|
williamr@4
|
20 |
*/
|
williamr@4
|
21 |
|
williamr@4
|
22 |
#ifndef _STLP_STRING_BASE_H
|
williamr@4
|
23 |
#define _STLP_STRING_BASE_H
|
williamr@4
|
24 |
|
williamr@4
|
25 |
// ------------------------------------------------------------
|
williamr@4
|
26 |
// Class _String_base.
|
williamr@4
|
27 |
|
williamr@4
|
28 |
// _String_base is a helper class that makes it it easier to write an
|
williamr@4
|
29 |
// exception-safe version of basic_string. The constructor allocates,
|
williamr@4
|
30 |
// but does not initialize, a block of memory. The destructor
|
williamr@4
|
31 |
// deallocates, but does not destroy elements within, a block of
|
williamr@4
|
32 |
// memory. The destructor assumes that _M_start either is null, or else
|
williamr@4
|
33 |
// points to a block of memory that was allocated using _String_base's
|
williamr@4
|
34 |
// allocator and whose size is _M_end_of_storage._M_data - _M_start.
|
williamr@4
|
35 |
|
williamr@4
|
36 |
_STLP_BEGIN_NAMESPACE
|
williamr@4
|
37 |
|
williamr@4
|
38 |
_STLP_MOVE_TO_PRIV_NAMESPACE
|
williamr@4
|
39 |
|
williamr@4
|
40 |
#ifndef _STLP_SHORT_STRING_SZ
|
williamr@4
|
41 |
# define _STLP_SHORT_STRING_SZ 16
|
williamr@4
|
42 |
#endif
|
williamr@4
|
43 |
|
williamr@4
|
44 |
template <class _Tp, class _Alloc>
|
williamr@4
|
45 |
class _String_base {
|
williamr@4
|
46 |
typedef _String_base<_Tp, _Alloc> _Self;
|
williamr@4
|
47 |
protected:
|
williamr@4
|
48 |
_STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
|
williamr@4
|
49 |
public:
|
williamr@4
|
50 |
//dums: Some compiler(MSVC6) require it to be public not simply protected!
|
williamr@4
|
51 |
enum {_DEFAULT_SIZE = _STLP_SHORT_STRING_SZ};
|
williamr@4
|
52 |
//This is needed by the full move framework
|
williamr@4
|
53 |
typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
|
williamr@4
|
54 |
typedef _STLP_alloc_proxy<_Tp*, _Tp, allocator_type> _AllocProxy;
|
williamr@4
|
55 |
typedef size_t size_type;
|
williamr@4
|
56 |
private:
|
williamr@4
|
57 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
58 |
union _Buffers {
|
williamr@4
|
59 |
_Tp* _M_dynamic_buf;
|
williamr@4
|
60 |
_Tp _M_static_buf[_DEFAULT_SIZE];
|
williamr@4
|
61 |
} _M_buffers;
|
williamr@4
|
62 |
#else
|
williamr@4
|
63 |
_Tp* _M_start;
|
williamr@4
|
64 |
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
|
williamr@4
|
65 |
protected:
|
williamr@4
|
66 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
67 |
bool _M_using_static_buf() const {
|
williamr@4
|
68 |
return (_M_end_of_storage._M_data == _M_buffers._M_static_buf + _DEFAULT_SIZE);
|
williamr@4
|
69 |
}
|
williamr@4
|
70 |
_Tp const* _M_Start() const {
|
williamr@4
|
71 |
return _M_using_static_buf()?_M_buffers._M_static_buf:_M_buffers._M_dynamic_buf;
|
williamr@4
|
72 |
}
|
williamr@4
|
73 |
_Tp* _M_Start() {
|
williamr@4
|
74 |
return _M_using_static_buf()?_M_buffers._M_static_buf:_M_buffers._M_dynamic_buf;
|
williamr@4
|
75 |
}
|
williamr@4
|
76 |
#else
|
williamr@4
|
77 |
_Tp const* _M_Start() const {return _M_start;}
|
williamr@4
|
78 |
_Tp* _M_Start() {return _M_start;}
|
williamr@4
|
79 |
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
|
williamr@4
|
80 |
|
williamr@4
|
81 |
_Tp* _M_finish;
|
williamr@4
|
82 |
_AllocProxy _M_end_of_storage;
|
williamr@4
|
83 |
|
williamr@4
|
84 |
_Tp const* _M_Finish() const {return _M_finish;}
|
williamr@4
|
85 |
_Tp* _M_Finish() {return _M_finish;}
|
williamr@4
|
86 |
|
williamr@4
|
87 |
// Precondition: 0 < __n <= max_size().
|
williamr@4
|
88 |
void _M_allocate_block(size_t __n = _DEFAULT_SIZE);
|
williamr@4
|
89 |
void _M_deallocate_block() {
|
williamr@4
|
90 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
91 |
if (!_M_using_static_buf() && (_M_buffers._M_dynamic_buf != 0))
|
williamr@4
|
92 |
_M_end_of_storage.deallocate(_M_buffers._M_dynamic_buf, _M_end_of_storage._M_data - _M_buffers._M_dynamic_buf);
|
williamr@4
|
93 |
#else
|
williamr@4
|
94 |
if (_M_start != 0)
|
williamr@4
|
95 |
_M_end_of_storage.deallocate(_M_start, _M_end_of_storage._M_data - _M_start);
|
williamr@4
|
96 |
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
|
williamr@4
|
97 |
}
|
williamr@4
|
98 |
|
williamr@4
|
99 |
size_t max_size() const {
|
williamr@4
|
100 |
const size_type __string_max_size = size_type(-1) / sizeof(_Tp);
|
williamr@4
|
101 |
typename allocator_type::size_type __alloc_max_size = _M_end_of_storage.max_size();
|
williamr@4
|
102 |
return (min)(__alloc_max_size, __string_max_size) - 1;
|
williamr@4
|
103 |
}
|
williamr@4
|
104 |
|
williamr@4
|
105 |
_String_base(const allocator_type& __a)
|
williamr@4
|
106 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
107 |
: _M_finish(_M_buffers._M_static_buf), _M_end_of_storage(__a, _M_buffers._M_static_buf + _DEFAULT_SIZE)
|
williamr@4
|
108 |
#else
|
williamr@4
|
109 |
: _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0)
|
williamr@4
|
110 |
#endif
|
williamr@4
|
111 |
{}
|
williamr@4
|
112 |
|
williamr@4
|
113 |
_String_base(const allocator_type& __a, size_t __n)
|
williamr@4
|
114 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
115 |
: _M_finish(_M_buffers._M_static_buf), _M_end_of_storage(__a, _M_buffers._M_static_buf + _DEFAULT_SIZE) {
|
williamr@4
|
116 |
#else
|
williamr@4
|
117 |
: _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0) {
|
williamr@4
|
118 |
#endif
|
williamr@4
|
119 |
_M_allocate_block(__n);
|
williamr@4
|
120 |
}
|
williamr@4
|
121 |
|
williamr@4
|
122 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
123 |
void _M_move_src (_Self &src) {
|
williamr@4
|
124 |
if (src._M_using_static_buf()) {
|
williamr@4
|
125 |
_M_buffers = src._M_buffers;
|
williamr@4
|
126 |
_M_finish = _M_buffers._M_static_buf + (src._M_finish - src._M_buffers._M_static_buf);
|
williamr@4
|
127 |
_M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
|
williamr@4
|
128 |
}
|
williamr@4
|
129 |
else {
|
williamr@4
|
130 |
_M_buffers._M_dynamic_buf = src._M_buffers._M_dynamic_buf;
|
williamr@4
|
131 |
_M_finish = src._M_finish;
|
williamr@4
|
132 |
_M_end_of_storage._M_data = src._M_end_of_storage._M_data;
|
williamr@4
|
133 |
src._M_buffers._M_dynamic_buf = 0;
|
williamr@4
|
134 |
}
|
williamr@4
|
135 |
}
|
williamr@4
|
136 |
#endif
|
williamr@4
|
137 |
|
williamr@4
|
138 |
_String_base(__move_source<_Self> src)
|
williamr@4
|
139 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
140 |
: _M_end_of_storage(__move_source<_AllocProxy>(src.get()._M_end_of_storage)) {
|
williamr@4
|
141 |
_M_move_src(src.get());
|
williamr@4
|
142 |
#else
|
williamr@4
|
143 |
: _M_start(src.get()._M_start), _M_finish(src.get()._M_finish),
|
williamr@4
|
144 |
_M_end_of_storage(__move_source<_AllocProxy>(src.get()._M_end_of_storage)) {
|
williamr@4
|
145 |
src.get()._M_start = 0;
|
williamr@4
|
146 |
#endif
|
williamr@4
|
147 |
}
|
williamr@4
|
148 |
|
williamr@4
|
149 |
~_String_base() { _M_deallocate_block(); }
|
williamr@4
|
150 |
|
williamr@4
|
151 |
void _M_reset(_Tp *__start, _Tp *__finish, _Tp *__end_of_storage) {
|
williamr@4
|
152 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
153 |
_M_buffers._M_dynamic_buf = __start;
|
williamr@4
|
154 |
#else
|
williamr@4
|
155 |
_M_start = __start;
|
williamr@4
|
156 |
#endif
|
williamr@4
|
157 |
_M_finish = __finish;
|
williamr@4
|
158 |
_M_end_of_storage._M_data = __end_of_storage;
|
williamr@4
|
159 |
}
|
williamr@4
|
160 |
|
williamr@4
|
161 |
void _M_destroy_back () {
|
williamr@4
|
162 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
163 |
if (!_M_using_static_buf())
|
williamr@4
|
164 |
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
|
williamr@4
|
165 |
_STLP_STD::_Destroy(_M_finish);
|
williamr@4
|
166 |
}
|
williamr@4
|
167 |
|
williamr@4
|
168 |
void _M_destroy_range(size_t __from_off = 0, size_t __to_off = 1) {
|
williamr@4
|
169 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
170 |
if (!_M_using_static_buf())
|
williamr@4
|
171 |
_STLP_STD::_Destroy_Range(_M_buffers._M_dynamic_buf + __from_off, _M_finish + __to_off);
|
williamr@4
|
172 |
#else
|
williamr@4
|
173 |
_STLP_STD::_Destroy_Range(_M_start + __from_off, _M_finish + __to_off);
|
williamr@4
|
174 |
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
|
williamr@4
|
175 |
}
|
williamr@4
|
176 |
|
williamr@4
|
177 |
void _M_destroy_ptr_range(_Tp *__f, _Tp *__l) {
|
williamr@4
|
178 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
179 |
if (!_M_using_static_buf())
|
williamr@4
|
180 |
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
|
williamr@4
|
181 |
_STLP_STD::_Destroy_Range(__f, __l);
|
williamr@4
|
182 |
}
|
williamr@4
|
183 |
|
williamr@4
|
184 |
void _M_Swap(_Self &__s) {
|
williamr@4
|
185 |
#if defined (_STLP_USE_SHORT_STRING_OPTIM)
|
williamr@4
|
186 |
if (_M_using_static_buf()) {
|
williamr@4
|
187 |
if (__s._M_using_static_buf()) {
|
williamr@4
|
188 |
_STLP_STD::swap(_M_buffers, __s._M_buffers);
|
williamr@4
|
189 |
_Tp *__tmp = _M_finish;
|
williamr@4
|
190 |
_M_finish = _M_buffers._M_static_buf + (__s._M_finish - __s._M_buffers._M_static_buf);
|
williamr@4
|
191 |
__s._M_finish = __s._M_buffers._M_static_buf + (__tmp - _M_buffers._M_static_buf);
|
williamr@4
|
192 |
//We need to swap _M_end_of_storage for allocators with state:
|
williamr@4
|
193 |
_M_end_of_storage.swap(__s._M_end_of_storage);
|
williamr@4
|
194 |
_M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
|
williamr@4
|
195 |
__s._M_end_of_storage._M_data = __s._M_buffers._M_static_buf + _DEFAULT_SIZE;
|
williamr@4
|
196 |
} else {
|
williamr@4
|
197 |
__s._M_Swap(*this);
|
williamr@4
|
198 |
return;
|
williamr@4
|
199 |
}
|
williamr@4
|
200 |
}
|
williamr@4
|
201 |
else if (__s._M_using_static_buf()) {
|
williamr@4
|
202 |
_Tp *__tmp = _M_buffers._M_dynamic_buf;
|
williamr@4
|
203 |
_Tp *__tmp_finish = _M_finish;
|
williamr@4
|
204 |
_Tp *__tmp_end_data = _M_end_of_storage._M_data;
|
williamr@4
|
205 |
_M_buffers = __s._M_buffers;
|
williamr@4
|
206 |
//We need to swap _M_end_of_storage for allocators with state:
|
williamr@4
|
207 |
_M_end_of_storage.swap(__s._M_end_of_storage);
|
williamr@4
|
208 |
_M_end_of_storage._M_data = _M_buffers._M_static_buf + _DEFAULT_SIZE;
|
williamr@4
|
209 |
_M_finish = _M_buffers._M_static_buf + (__s._M_finish - __s._M_buffers._M_static_buf);
|
williamr@4
|
210 |
__s._M_buffers._M_dynamic_buf = __tmp;
|
williamr@4
|
211 |
__s._M_end_of_storage._M_data = __tmp_end_data;
|
williamr@4
|
212 |
__s._M_finish = __tmp_finish;
|
williamr@4
|
213 |
}
|
williamr@4
|
214 |
else {
|
williamr@4
|
215 |
_STLP_STD::swap(_M_buffers._M_dynamic_buf, __s._M_buffers._M_dynamic_buf);
|
williamr@4
|
216 |
_M_end_of_storage.swap(__s._M_end_of_storage);
|
williamr@4
|
217 |
_STLP_STD::swap(_M_finish, __s._M_finish);
|
williamr@4
|
218 |
}
|
williamr@4
|
219 |
#else
|
williamr@4
|
220 |
_STLP_STD::swap(_M_start, __s._M_start);
|
williamr@4
|
221 |
_M_end_of_storage.swap(__s._M_end_of_storage);
|
williamr@4
|
222 |
_STLP_STD::swap(_M_finish, __s._M_finish);
|
williamr@4
|
223 |
#endif /* _STLP_USE_SHORT_STRING_OPTIM */
|
williamr@4
|
224 |
}
|
williamr@4
|
225 |
|
williamr@4
|
226 |
void _STLP_FUNCTION_THROWS _M_throw_length_error() const;
|
williamr@4
|
227 |
void _STLP_FUNCTION_THROWS _M_throw_out_of_range() const;
|
williamr@4
|
228 |
};
|
williamr@4
|
229 |
|
williamr@4
|
230 |
#undef _STLP_SHORT_STRING_SZ
|
williamr@4
|
231 |
|
williamr@4
|
232 |
#if defined (_STLP_USE_TEMPLATE_EXPORT)
|
williamr@4
|
233 |
_STLP_EXPORT_TEMPLATE_CLASS _String_base<char, allocator<char> >;
|
williamr@4
|
234 |
# if defined (_STLP_HAS_WCHAR_T)
|
williamr@4
|
235 |
_STLP_EXPORT_TEMPLATE_CLASS _String_base<wchar_t, allocator<wchar_t> >;
|
williamr@4
|
236 |
# endif
|
williamr@4
|
237 |
#endif /* _STLP_USE_TEMPLATE_EXPORT */
|
williamr@4
|
238 |
|
williamr@4
|
239 |
_STLP_MOVE_TO_STD_NAMESPACE
|
williamr@4
|
240 |
|
williamr@4
|
241 |
_STLP_END_NAMESPACE
|
williamr@4
|
242 |
|
williamr@4
|
243 |
#endif /* _STLP_STRING_BASE_H */
|
williamr@4
|
244 |
|
williamr@4
|
245 |
/*
|
williamr@4
|
246 |
* Local Variables:
|
williamr@4
|
247 |
* mode:C++
|
williamr@4
|
248 |
* End:
|
williamr@4
|
249 |
*/
|