Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_strref.h
Go to the documentation of this file.
1
32#ifndef _RWSTD_RW_STRREF_H_INCLUDED
33#define _RWSTD_RW_STRREF_H_INCLUDED
34
35#ifndef _RWSTD_RW_ALLOCATOR_H_INCLUDED
36# include <rw/_allocator.h>
37#endif // _RWSTD_RW_ALLOCATOR_H_INCLUDED
38
39#ifndef _RWSTD_RW_MUTEX_H_INCLUDED
40# include <rw/_mutex.h>
41#endif // _RWSTD_RW_MUTEX_H_INCLUDED
42
43#ifndef _RWSTD_RW_SPECIALIZED_H_INCLUDED
44# include <rw/_specialized.h>
45#endif // _RWSTD_RW_SPECIALIZED_H_INCLUDED
46
47#ifndef _RWSTD_RW_TRAITS_H_INCLUDED
48# include <rw/_traits.h>
49#endif // _RWSTD_RW_TRAITS_H_INCLUDED
50
51
52#if !defined(_RWSTD_STRING_REF_OFFSET)
53# define _RWSTD_STRING_REF_OFFSET 1
54#endif
55
56#if !defined(_RWSTD_STRING_REF_INT)
57# define _RWSTD_STRING_REF_INT long
58#endif
59
60#if !defined (_RWSTD_NO_ATOMIC_OPS) && !defined (_RWSTD_NO_STRING_ATOMIC_OPS)
61 // disable string mutex when atomic operations are available
62# ifndef _RWSTD_NO_STRING_MUTEX
63# define _RWSTD_NO_STRING_MUTEX
64# endif // _RWSTD_NO_STRING_MUTEX
65#endif // _RWSTD_NO_ATOMIC_OPS && !_RWSTD_NO_STRING_ATOMIC_OPS
66
67
69
70
71// chooses either a single global mutex or a mutex per string object
72// or no mutex at all when atomic test-and-set instruction is available
73#if !defined (_RWSTD_REENTRANT) || defined (_RWSTD_NO_STRING_MUTEX)
74# define _RWSTD_STRING_MUTEX(ignore) false
75#elif defined (_RWSTD_ONE_STRING_MUTEX)
76# define _RWSTD_STRING_MUTEX(ignore) __rw_string_mutex
77#else
78# define _RWSTD_STRING_MUTEX(pstr) pstr->_C_mutex
79#endif
80
81
82template <class _CharT,
83 class _Traits = char_traits<_CharT>,
84 class _Allocator = allocator<_CharT> >
85class basic_string;
86
87
88} // namespace std
89
90
92
93
94#if defined (_RWSTD_REENTRANT) \
95 && defined (_RWSTD_ONE_STRING_MUTEX) \
96 && !defined (_RWSTD_NO_STRING_MUTEX)
97
98extern __rw_mutex _RWSTD_EXPORT __rw_string_mutex;
99
100#endif // _REENTRANT && _ONE_STRING_MUTEX && !NO_STRING_MUTEX
101
102
103template <class _CharT, class _Traits , class _Allocator>
104struct __string_ref
105{
106 typedef _CharT char_type;
107 typedef _Allocator allocator_type;
108 typedef typename allocator_type::size_type size_type;
109 typedef _STD::basic_string<_CharT, _Traits, _Allocator> string_type;
110
111#if defined (_RWSTD_REENTRANT) \
112 && !defined (_RWSTD_ONE_STRING_MUTEX) \
113 && !defined (_RWSTD_NO_STRING_MUTEX) \
114 && !defined (_RWSTD_NO_STATIC_MUTEX_INIT)
115
116 void _C_init (size_type __cap, size_type __size) {
117
118 _C_cap = __cap;
119 _C_size._C_size = __size;
120
121# ifndef _RWSTD_NO_STRING_REF_COUNT
122
123 _C_refs = 1 - _RWSTD_STRING_REF_OFFSET;
124
125 if (0 != _RWSTD_MUTEX_INIT (this->_C_mutex._C_mutex))
126 _RW::__rw_throw (_RWSTD_ERROR_RUNTIME_ERROR,
127 "synchronization error");
128
129# endif // _RWSTD_NO_STRING_REF_COUNT
130
131 }
132
133 void _C_destroy () {
134# ifndef _RWSTD_NO_STRING_REF_COUNT
135 _RWSTD_MUTEX_DESTROY (this->_C_mutex._C_mutex);
136# endif
137 }
138
139#else
140
141 void _C_init (size_type __cap, size_type __size) {
142
143# ifndef _RWSTD_NO_STRING_REF_COUNT
144 _C_refs = 1 - _RWSTD_STRING_REF_OFFSET;
145# endif // _RWSTD_NO_STRING_REF_COUNT
146
147 _C_cap = __cap;
148 _C_size._C_size = __size;
149 }
150
151 void _C_destroy () { }
152
153#endif // _RWSTD_REENTRANT && !_RWSTD_ONE_STRING_MUTEX &&
154 // !_RWSTD_NO_STRING_MUTEX && !_RWSTD_NO_STATIC_MUTEX_INIT
155
156
157 int _C_get_ref () const {
158
159# ifndef _RWSTD_NO_STRING_REF_COUNT
160
161 return _C_refs + _RWSTD_STRING_REF_OFFSET;
162
163#else // if defined (_RWSTD_NO_STRING_REF_COUNT)
164
165 return 0;
166
167#endif // _RWSTD_NO_STRING_REF_COUNT
168
169 }
170
171 void _C_unref () {
172
173#ifndef _RWSTD_NO_STRING_REF_COUNT
174
175 // not thread-safe (see caller)
176 if (this != string_type::_C_nullref ())
177 _C_refs = -_RWSTD_STRING_REF_OFFSET;
178
179#endif // _RWSTD_NO_STRING_REF_COUNT
180 }
181
182 int _C_inc_ref () {
183
184#ifndef _RWSTD_NO_STRING_REF_COUNT
185
186 return this == string_type::_C_nullref () ? 1 :
188 _RWSTD_STRING_MUTEX (this));
189#else // if defined (_RWSTD_NO_STRING_REF_COUNT)
190 return 0 + (this != string_type::_C_nullref ());
191#endif // _RWSTD_NO_STRING_REF_COUNT
192
193 }
194
195 int _C_dec_ref () {
196
197#ifndef _RWSTD_NO_STRING_REF_COUNT
198
199 return this == string_type::_C_nullref () ? 1 :
202 _RWSTD_STRING_MUTEX (this));
203
204#else // if defined (_RWSTD_NO_STRING_REF_COUNT)
205 return 0 + (this == string_type::_C_nullref ());
206#endif // _RWSTD_NO_STRING_REF_COUNT
207
208 }
209
210 size_type size () const {
211 return _C_size._C_size;
212 }
213
214 size_type capacity () const {
215 return _C_cap;
216 }
217
218 char_type* data () {
219 return _RWSTD_REINTERPRET_CAST (char_type*, this + 1);
220 }
221
222 const char_type* data () const {
223 return _RWSTD_REINTERPRET_CAST (const char_type*, this + 1);
224 }
225
226#ifndef _RWSTD_NO_STRING_REF_COUNT
227
228# if defined (_RWSTD_REENTRANT) \
229 && !defined (_RWSTD_ONE_STRING_MUTEX) \
230 && !defined (_RWSTD_NO_STRING_MUTEX)
231
232 __rw_mutex_base _C_mutex;
233
234# endif // _REENTRANT && !_ONE_STRING_MUTEX && !_NO_STRING_MUTEX
235
236 // reference count:
237 // 1 less than the number of references to the string body
238 // _RWSTD_STRING_REF_OFFSET less if _RWSTD_NO_STRING_MUTEX is defined
239 // -1 if reference counting is disabled
240 int _C_refs;
241
242#endif // _RWSTD_NO_STRING_REF_COUNT
243
244 size_type _C_cap; // Size of allocated memory
245
246 union {
247 size_type _C_size; // Number of actual data values stored
248 _CharT _C_dummy; // force the alignment of the first char
249 } _C_size; // named to work around an HP aCC 3.30 bug
250};
251
252
253// representation of the null string; will be a POD wherever possible
254// (will not be POD if the reference contains a mutex with a UD-ctor)
255template <class _CharT, class _Traits , class _Allocator>
256struct __null_ref
257 : __string_ref<_CharT, _Traits , _Allocator>
258{
259 // string reference immediately followed by a single terminating null
260 _CharT _C_eos;
261};
262
263
264#ifdef _RWSTD_NO_COLLAPSE_TEMPLATE_STATICS
265
266extern _RWSTD_EXPORT unsigned long __nullref [];
267
268#endif // _RWSTD_NO_COLLAPSE_TEMPLATE_STATICS
269
270} // namespace __rw
271
272
273#endif // _RWSTD_RW_STRREF_H_INCLUDED
const char *const data[]
#define _RWSTD_EXPORT
Definition _defs.h:485
#define _RWSTD_REINTERPRET_CAST(T, x)
Definition _defs.h:535
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_STRING_ATOMIC_PREDECREMENT(x, mutex)
Definition _defs.h:709
#define _RWSTD_STRING_ATOMIC_PREINCREMENT(x, mutex)
Definition _defs.h:707
#define _RWSTD_ERROR_RUNTIME_ERROR
Definition _error.h:94
#define _RWSTD_MUTEX_DESTROY(mutex)
Definition _mutex-dce.h:40
#define _RWSTD_MUTEX_INIT(mutex)
Definition _mutex-dce.h:38
#define _RWSTD_STRING_REF_OFFSET
Definition _strref.h:53
#define _RWSTD_STRING_MUTEX(ignore)
Definition json.h:5363