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