2 * Copyright (c) 1997-1999
3 * Silicon Graphics Computer Systems, Inc.
11 * This material is provided "as is", with absolutely no warranty expressed
12 * or implied. Any use is at your own risk.
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.
22 #ifndef _STLP_STRING_BASE_H
23 #define _STLP_STRING_BASE_H
25 // ------------------------------------------------------------
26 // Class _String_base.
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_start_of_storage._M_data.
38 _STLP_MOVE_TO_PRIV_NAMESPACE
40 template <class _Tp
, class _Alloc
>
42 typedef _String_base
<_Tp
, _Alloc
> _Self
;
44 _STLP_FORCE_ALLOCATORS(_Tp
, _Alloc
)
46 //dums: Some compiler(MSVC6) require it to be public not simply protected!
47 enum {_DEFAULT_SIZE
= 4 * sizeof( void * )};
48 //This is needed by the full move framework
49 typedef _Alloc allocator_type
;
50 typedef _STLP_alloc_proxy
<_Tp
*, _Tp
, allocator_type
> _AllocProxy
;
51 typedef size_t size_type
;
53 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
55 _Tp
* _M_end_of_storage
;
56 _Tp _M_static_buf
[_DEFAULT_SIZE
];
59 _Tp
* _M_end_of_storage
;
60 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
62 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
63 bool _M_using_static_buf() const
64 { return (_M_start_of_storage
._M_data
== _M_buffers
._M_static_buf
); }
65 _Tp
const* _M_Start() const { return _M_start_of_storage
._M_data
; }
66 _Tp
* _M_Start() { return _M_start_of_storage
._M_data
; }
67 _Tp
const* _M_End() const
68 { return _M_using_static_buf() ? _M_buffers
._M_static_buf
+ _DEFAULT_SIZE
: _M_buffers
._M_end_of_storage
; }
70 { return _M_using_static_buf() ? _M_buffers
._M_static_buf
+ _DEFAULT_SIZE
: _M_buffers
._M_end_of_storage
; }
71 size_type
_M_capacity() const
72 { return _M_using_static_buf() ? _DEFAULT_SIZE
: _M_buffers
._M_end_of_storage
- _M_start_of_storage
._M_data
; }
73 size_type
_M_rest() const
74 { return _M_using_static_buf() ? _DEFAULT_SIZE
- (_M_finish
- _M_buffers
._M_static_buf
) : _M_buffers
._M_end_of_storage
- _M_finish
; }
76 _Tp
const* _M_Start() const { return _M_start_of_storage
._M_data
; }
77 _Tp
* _M_Start() { return _M_start_of_storage
._M_data
; }
78 _Tp
const* _M_End() const { return _M_end_of_storage
; }
79 _Tp
* _M_End() { return _M_end_of_storage
; }
80 size_type
_M_capacity() const
81 { return _M_end_of_storage
- _M_start_of_storage
._M_data
; }
82 size_type
_M_rest() const
83 { return _M_end_of_storage
- _M_finish
; }
84 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
87 _AllocProxy _M_start_of_storage
;
89 _Tp
const* _M_Finish() const {return _M_finish
;}
90 _Tp
* _M_Finish() {return _M_finish
;}
92 // Precondition: 0 < __n <= max_size().
93 void _M_allocate_block(size_t __n
= _DEFAULT_SIZE
);
94 void _M_deallocate_block() {
95 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
96 if (!_M_using_static_buf() && (_M_start_of_storage
._M_data
!= 0))
97 _M_start_of_storage
.deallocate(_M_start_of_storage
._M_data
, _M_buffers
._M_end_of_storage
- _M_start_of_storage
._M_data
);
99 if (_M_start_of_storage
._M_data
!= 0)
100 _M_start_of_storage
.deallocate(_M_start_of_storage
._M_data
, _M_end_of_storage
- _M_start_of_storage
._M_data
);
101 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
104 size_t max_size() const {
105 const size_type __string_max_size
= size_type(-1) / sizeof(_Tp
);
106 typename
allocator_type::size_type __alloc_max_size
= _M_start_of_storage
.max_size();
107 return (min
)(__alloc_max_size
, __string_max_size
) - 1;
110 _String_base(const allocator_type
& __a
)
111 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
112 : _M_finish(_M_buffers
._M_static_buf
), _M_start_of_storage(__a
, _M_buffers
._M_static_buf
)
114 : _M_end_of_storage(0), _M_finish(0), _M_start_of_storage(__a
, (_Tp
*)0)
118 _String_base(const allocator_type
& __a
, size_t __n
)
119 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
120 : _M_finish(_M_buffers
._M_static_buf
), _M_start_of_storage(__a
, _M_buffers
._M_static_buf
) {
122 : _M_end_of_storage(0), _M_finish(0), _M_start_of_storage(__a
, (_Tp
*)0) {
124 _M_allocate_block(__n
);
127 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
128 void _M_move_src (_Self
&src
) {
129 if (src
._M_using_static_buf()) {
130 _M_buffers
= src
._M_buffers
;
131 _M_finish
= _M_buffers
._M_static_buf
+ (src
._M_finish
- src
._M_start_of_storage
._M_data
);
132 _M_start_of_storage
._M_data
= _M_buffers
._M_static_buf
;
135 _M_start_of_storage
._M_data
= src
._M_start_of_storage
._M_data
;
136 _M_finish
= src
._M_finish
;
137 _M_buffers
._M_end_of_storage
= src
._M_buffers
._M_end_of_storage
;
138 src
._M_start_of_storage
._M_data
= 0;
143 #if !defined (_STLP_NO_MOVE_SEMANTIC)
144 _String_base(__move_source
<_Self
> src
)
145 # if defined (_STLP_USE_SHORT_STRING_OPTIM)
146 : _M_start_of_storage(__move_source
<_AllocProxy
>(src
.get()._M_start_of_storage
)) {
147 _M_move_src(src
.get());
149 : _M_end_of_storage(src
.get()._M_end_of_storage
), _M_finish(src
.get()._M_finish
),
150 _M_start_of_storage(__move_source
<_AllocProxy
>(src
.get()._M_start_of_storage
)) {
151 src
.get()._M_start_of_storage
._M_data
= 0;
156 ~_String_base() { _M_deallocate_block(); }
158 void _M_reset(_Tp
*__start
, _Tp
*__finish
, _Tp
*__end_of_storage
) {
159 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
160 _M_buffers
._M_end_of_storage
= __end_of_storage
;
162 _M_end_of_storage
= __end_of_storage
;
164 _M_finish
= __finish
;
165 _M_start_of_storage
._M_data
= __start
;
168 void _M_swap(_Self
&__s
) {
169 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
170 if (_M_using_static_buf()) {
171 if (__s
._M_using_static_buf()) {
172 _STLP_STD::swap(_M_buffers
, __s
._M_buffers
);
173 _Tp
*__tmp
= _M_finish
;
174 _M_finish
= _M_start_of_storage
._M_data
+ (__s
._M_finish
- __s
._M_start_of_storage
._M_data
);
175 __s
._M_finish
= __s
._M_buffers
._M_static_buf
+ (__tmp
- _M_start_of_storage
._M_data
);
176 //We need to swap _M_start_of_storage for allocators with state:
177 _M_start_of_storage
.swap(__s
._M_start_of_storage
);
178 _M_start_of_storage
._M_data
= _M_buffers
._M_static_buf
;
179 __s
._M_start_of_storage
._M_data
= __s
._M_buffers
._M_static_buf
;
185 else if (__s
._M_using_static_buf()) {
186 _Tp
*__tmp
= _M_start_of_storage
._M_data
;
187 _Tp
*__tmp_finish
= _M_finish
;
188 _Tp
*__tmp_end_data
= _M_buffers
._M_end_of_storage
;
189 _M_buffers
= __s
._M_buffers
;
190 //We need to swap _M_start_of_storage for allocators with state:
191 _M_start_of_storage
.swap(__s
._M_start_of_storage
);
192 _M_start_of_storage
._M_data
= _M_buffers
._M_static_buf
;
193 _M_finish
= _M_buffers
._M_static_buf
+ (__s
._M_finish
- __s
._M_buffers
._M_static_buf
);
194 __s
._M_buffers
._M_end_of_storage
= __tmp_end_data
;
195 __s
._M_start_of_storage
._M_data
= __tmp
;
196 __s
._M_finish
= __tmp_finish
;
199 _STLP_STD::swap(_M_buffers
._M_end_of_storage
, __s
._M_buffers
._M_end_of_storage
);
200 _M_start_of_storage
.swap(__s
._M_start_of_storage
);
201 _STLP_STD::swap(_M_finish
, __s
._M_finish
);
204 _STLP_STD::swap(_M_end_of_storage
, __s
._M_end_of_storage
);
205 _M_start_of_storage
.swap(__s
._M_start_of_storage
);
206 _STLP_STD::swap(_M_finish
, __s
._M_finish
);
210 void _STLP_FUNCTION_THROWS
_M_throw_length_error() const;
211 void _STLP_FUNCTION_THROWS
_M_throw_out_of_range() const;
214 #if defined (_STLP_USE_TEMPLATE_EXPORT)
215 _STLP_EXPORT_TEMPLATE_CLASS _String_base
<char, allocator
<char> >;
216 # if defined (_STLP_HAS_WCHAR_T)
217 _STLP_EXPORT_TEMPLATE_CLASS _String_base
<wchar_t, allocator
<wchar_t> >;
219 #endif /* _STLP_USE_TEMPLATE_EXPORT */
221 _STLP_MOVE_TO_STD_NAMESPACE
225 #endif /* _STLP_STRING_BASE_H */