5 * This material is provided "as is", with absolutely no warranty expressed
6 * or implied. Any use is at your own risk.
8 * Permission to use or copy this software for any purpose is hereby granted
9 * without fee, provided the above notices are retained on all copies.
10 * Permission to modify the code and to distribute modified code is granted,
11 * provided the above notices are retained, and a notice that the code was
12 * modified is included with the above copyright notice.
16 /* NOTE: This is an internal header file, included by other STL headers.
17 * You should not attempt to use it directly.
20 #ifndef _STLP_POINTERS_SPEC_TOOLS_H
21 #define _STLP_POINTERS_SPEC_TOOLS_H
23 #ifndef _STLP_TYPE_TRAITS_H
24 # include <stl/type_traits.h>
29 //Some usefull declarations:
30 template <class _Tp> struct less;
32 _STLP_MOVE_TO_PRIV_NAMESPACE
34 template <class _StorageT, class _ValueT, class _BinaryPredicate>
35 struct _BinaryPredWrapper;
38 * Since the compiler only allows at most one non-trivial
39 * implicit conversion we can make use of a shim class to
40 * be sure that functions below doesn't accept classes with
41 * implicit pointer conversion operators
43 struct _ConstVolatileVoidPointerShim
44 { _ConstVolatileVoidPointerShim(const volatile void*); };
46 //The dispatch functions:
47 struct _VoidPointerShim
48 { _VoidPointerShim(void*); };
49 struct _ConstVoidPointerShim
50 { _ConstVoidPointerShim(const void*); };
51 struct _VolatileVoidPointerShim
52 { _VolatileVoidPointerShim(volatile void*); };
55 char _UseVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
56 char _UseVoidPtrStorageType(const __true_type& /*POD*/, ...);
57 char* _UseVoidPtrStorageType(const __true_type& /*POD*/, _VoidPointerShim);
60 char _UseConstVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
61 char _UseConstVoidPtrStorageType(const __true_type& /*POD*/, ...);
62 char* _UseConstVoidPtrStorageType(const __true_type& /*POD*/, _ConstVoidPointerShim);
65 char _UseVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
66 char _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...);
67 char* _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, _VolatileVoidPointerShim);
70 char _UseConstVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
71 char _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...);
72 char* _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, _ConstVolatileVoidPointerShim);
76 typedef typename __type_traits<_Tp>::is_POD_type _PODType;
77 static _Tp __null_rep();
79 enum { use_void_ptr = (sizeof(_UseVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
80 enum { use_const_void_ptr = (sizeof(_UseConstVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
81 enum { use_volatile_void_ptr = (sizeof(_UseVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
82 enum { use_const_volatile_void_ptr = (sizeof(_UseConstVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
84 typedef typename __select<!use_const_volatile_void_ptr,
86 typename __select<use_void_ptr,
88 typename __select<use_const_void_ptr,
90 typename __select<use_volatile_void_ptr,
92 const volatile void*>::_Ret >::_Ret >::_Ret >::_Ret _QualifiedType;
94 #if !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
95 /* If the compiler do not support the iterator_traits structure we cannot wrap
96 * iterators pass to container template methods. The iterator dereferenced value
97 * has to be storable without any cast in the chosen storage type. To guaranty
98 * that the void pointer has to be correctly qualified.
100 typedef _QualifiedType _Type;
102 /* With iterator_traits we can wrap passed iterators and make the necessary casts.
103 * We can always use a simple void* storage type:
105 typedef typename __select<use_const_volatile_void_ptr,
111 template <class _Tp, class _Compare>
112 struct _AssocStorageTypes {
113 typedef _StorageType<_Tp> _StorageTypeInfo;
114 typedef typename _StorageTypeInfo::_Type _SType;
116 //We need to also check that the comparison functor used to instanciate the assoc container
117 //is the default Standard less implementation:
118 typedef typename _IsSTLportClass<_Compare>::_Ret _STLportLess;
119 enum { is_default_less = __type2bool<_STLportLess>::_Ret };
121 typedef typename __select<is_default_less, _SType, _Tp>::_Ret _KeyStorageType;
122 enum { ptr_type = _StorageTypeInfo::use_const_volatile_void_ptr };
123 typedef typename __select<is_default_less && ptr_type,
124 _BinaryPredWrapper<_KeyStorageType, _Tp, _Compare>,
125 _Compare>::_Ret _CompareStorageType;
129 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
131 * Base struct to deal with qualifiers
133 template <class _StorageT, class _QualifiedStorageT>
134 struct _VoidCastTraitsAux {
135 typedef _QualifiedStorageT void_cv_type;
136 typedef _StorageT void_type;
138 static void_type * uncv_ptr(void_cv_type *__ptr)
140 static void_type const* uncv_cptr(void_cv_type const*__ptr)
142 static void_type ** uncv_pptr(void_cv_type **__ptr)
144 static void_type & uncv_ref(void_cv_type & __ref)
146 static void_type const& uncv_cref(void_cv_type const& __ref)
148 static void_cv_type* cv_ptr(void_type *__ptr)
150 static void_cv_type const* cv_cptr(void_type const*__ptr)
152 static void_cv_type ** cv_pptr(void_type **__ptr)
154 static void_cv_type & cv_ref(void_type & __ref)
156 static void_cv_type const& cv_cref(void_type const& __ref)
160 template <class _VoidCVType>
161 struct _VoidCastTraitsAuxBase {
162 typedef _VoidCVType* void_cv_type;
163 typedef void* void_type;
165 static void_type* uncv_ptr(void_cv_type *__ptr)
166 { return __CONST_CAST(void_type*, __ptr); }
167 static void_type const* uncv_cptr(void_cv_type const*__ptr)
168 { return __CONST_CAST(void_type const*, __ptr); }
169 static void_type** uncv_pptr(void_cv_type **__ptr)
170 { return __CONST_CAST(void_type**, __ptr); }
171 static void_type& uncv_ref(void_cv_type &__ref)
172 { return __CONST_CAST(void_type&, __ref); }
173 static void_type const& uncv_cref(void_cv_type const& __ptr)
174 { return __CONST_CAST(void_type const&, __ptr); }
175 // The reverse versions
176 static void_cv_type * cv_ptr(void_type *__ptr)
177 { return __CONST_CAST(void_cv_type *, __ptr); }
178 static void_cv_type const* cv_cptr(void_type const*__ptr)
179 { return __CONST_CAST(void_cv_type const*, __ptr); }
180 static void_cv_type ** cv_pptr(void_type **__ptr)
181 { return __CONST_CAST(void_cv_type**, __ptr); }
182 static void_cv_type & cv_ref(void_type &__ref)
183 { return __CONST_CAST(void_cv_type &, __ref); }
184 static void_cv_type const& cv_cref(void_type const& __ref)
185 { return __CONST_CAST(void_cv_type const&, __ref); }
189 struct _VoidCastTraitsAux<void*, const void*> : _VoidCastTraitsAuxBase<void const>
192 struct _VoidCastTraitsAux<void*, volatile void*> : _VoidCastTraitsAuxBase<void volatile>
195 struct _VoidCastTraitsAux<void*, const volatile void*> : _VoidCastTraitsAuxBase<void const volatile>
198 template <class _StorageT, class _ValueT>
200 typedef _ValueT value_type;
201 typedef typename _StorageType<_ValueT>::_QualifiedType _QualifiedStorageT;
202 typedef _VoidCastTraitsAux<_StorageT, _QualifiedStorageT> cv_traits;
203 typedef typename cv_traits::void_type void_type;
204 typedef typename cv_traits::void_cv_type void_cv_type;
206 static value_type * to_value_type_ptr(void_type *__ptr)
207 { return __REINTERPRET_CAST(value_type *, cv_traits::cv_ptr(__ptr)); }
208 static value_type const* to_value_type_cptr(void_type const*__ptr)
209 { return __REINTERPRET_CAST(value_type const*, cv_traits::cv_cptr(__ptr)); }
210 static value_type ** to_value_type_pptr(void_type **__ptr)
211 { return __REINTERPRET_CAST(value_type **, cv_traits::cv_pptr(__ptr)); }
212 static value_type & to_value_type_ref(void_type &__ref)
213 { return __REINTERPRET_CAST(value_type &, cv_traits::cv_ref(__ref)); }
214 static value_type const& to_value_type_cref(void_type const& __ptr)
215 { return __REINTERPRET_CAST(value_type const&, cv_traits::cv_cref(__ptr)); }
217 static void_type * to_storage_type_ptr(value_type *__ptr)
218 { return cv_traits::uncv_ptr(__REINTERPRET_CAST(void_cv_type *, __ptr)); }
219 static void_type const* to_storage_type_cptr(value_type const*__ptr)
220 { return cv_traits::uncv_cptr(__REINTERPRET_CAST(void_cv_type const*, __ptr)); }
221 static void_type ** to_storage_type_pptr(value_type **__ptr)
222 { return cv_traits::uncv_pptr(__REINTERPRET_CAST(void_cv_type **, __ptr)); }
223 static void_type const& to_storage_type_cref(value_type const& __ref)
224 { return cv_traits::uncv_cref(__REINTERPRET_CAST(void_cv_type const&, __ref)); }
226 //Method used to treat set container template method extension
227 static void_type const& to_storage_type_crefT(value_type const& __ref)
228 { return to_storage_type_cref(__ref); }
232 struct _CastTraits<_Tp, _Tp> {
233 typedef _Tp storage_type;
234 typedef _Tp value_type;
236 static value_type * to_value_type_ptr(storage_type *__ptr)
238 static value_type const* to_value_type_cptr(storage_type const*__ptr)
240 static value_type ** to_value_type_pptr(storage_type **__ptr)
242 static value_type & to_value_type_ref(storage_type &__ref)
244 static value_type const& to_value_type_cref(storage_type const&__ref)
247 static storage_type * to_storage_type_ptr(value_type *__ptr)
249 static storage_type const* to_storage_type_cptr(value_type const*__ptr)
251 static storage_type ** to_storage_type_pptr(value_type **__ptr)
253 static storage_type const& to_storage_type_cref(value_type const& __ref)
256 //Method used to treat set container template method extension
257 template <class _Tp1>
258 static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref)
262 #define _STLP_USE_ITERATOR_WRAPPER
264 template <class _StorageT, class _ValueT, class _Iterator>
266 typedef _CastTraits<_StorageT, _ValueT> cast_traits;
267 typedef iterator_traits<_Iterator> _IteTraits;
269 typedef typename _IteTraits::iterator_category iterator_category;
270 typedef _StorageT value_type;
271 typedef typename _IteTraits::difference_type difference_type;
272 typedef value_type* pointer;
273 typedef value_type const& const_reference;
274 //This wrapper won't be used for input so to avoid surprise
275 //the reference type will be a const reference:
276 typedef const_reference reference;
278 typedef _IteWrapper<_StorageT, _ValueT, _Iterator> _Self;
281 _IteWrapper(_Iterator &__ite) : _M_ite(__ite) {}
283 const_reference operator*() const { return cast_traits::to_storage_type_cref(*_M_ite); }
285 _Self& operator= (_Self const& __rhs) {
286 _M_ite = __rhs._M_ite;
290 _Self& operator++() {
295 _Self& operator--() {
300 _Self& operator += (difference_type __offset) {
304 difference_type operator -(_Self const& __other) const
305 { return _M_ite - __other._M_ite; }
307 bool operator == (_Self const& __other) const
308 { return _M_ite == __other._M_ite; }
310 bool operator != (_Self const& __other) const
311 { return _M_ite != __other._M_ite; }
313 bool operator < (_Self const& __rhs) const
314 { return _M_ite < __rhs._M_ite; }
320 template <class _Tp, class _Iterator>
321 struct _IteWrapper<_Tp, _Tp, _Iterator>
322 { typedef _Iterator _Ite; };
327 * In this config the storage type is qualified in respect of the
328 * value_type qualification. Simple reinterpret_cast is enough.
330 template <class _StorageT, class _ValueT>
332 typedef _StorageT storage_type;
333 typedef _ValueT value_type;
335 static value_type * to_value_type_ptr(storage_type *__ptr)
336 { return __REINTERPRET_CAST(value_type*, __ptr); }
337 static value_type const* to_value_type_cptr(storage_type const*__ptr)
338 { return __REINTERPRET_CAST(value_type const*, __ptr); }
339 static value_type ** to_value_type_pptr(storage_type **__ptr)
340 { return __REINTERPRET_CAST(value_type **, __ptr); }
341 static value_type & to_value_type_ref(storage_type &__ref)
342 { return __REINTERPRET_CAST(value_type&, __ref); }
343 static value_type const& to_value_type_cref(storage_type const&__ref)
344 { return __REINTERPRET_CAST(value_type const&, __ref); }
346 static storage_type * to_storage_type_ptr(value_type *__ptr)
347 { return __REINTERPRET_CAST(storage_type*, __ptr); }
348 static storage_type const* to_storage_type_cptr(value_type const*__ptr)
349 { return __REINTERPRET_CAST(storage_type const*, __ptr); }
350 static storage_type ** to_storage_type_pptr(value_type **__ptr)
351 { return __REINTERPRET_CAST(storage_type **, __ptr); }
352 static storage_type const& to_storage_type_cref(value_type const&__ref)
353 { return __REINTERPRET_CAST(storage_type const&, __ref); }
354 template <class _Tp1>
355 static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref)
362 template <class _StorageT, class _ValueT, class _UnaryPredicate>
363 struct _UnaryPredWrapper {
364 typedef _CastTraits<_StorageT, _ValueT> cast_traits;
366 _UnaryPredWrapper (_UnaryPredicate const& __pred) : _M_pred(__pred) {}
368 bool operator () (_StorageT const& __ref) const
369 { return _M_pred(cast_traits::to_value_type_cref(__ref)); }
372 _UnaryPredicate _M_pred;
375 template <class _StorageT, class _ValueT, class _BinaryPredicate>
376 struct _BinaryPredWrapper {
377 typedef _CastTraits<_StorageT, _ValueT> cast_traits;
379 _BinaryPredWrapper () {}
380 _BinaryPredWrapper (_BinaryPredicate const& __pred) : _M_pred(__pred) {}
382 _BinaryPredicate get_pred() const { return _M_pred; }
384 bool operator () (_StorageT const& __fst, _StorageT const& __snd) const
385 { return _M_pred(cast_traits::to_value_type_cref(__fst), cast_traits::to_value_type_cref(__snd)); }
387 //Cast operator used to transparently access underlying predicate
388 //in set::key_comp() method
389 operator _BinaryPredicate() const
393 _BinaryPredicate _M_pred;
396 _STLP_MOVE_TO_STD_NAMESPACE
400 #endif /* _STLP_POINTERS_SPEC_TOOLS_H */