ReactOS  0.4.15-dev-1150-g593bcce
_tools.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003
3  * Francois Dumont
4  *
5  * This material is provided "as is", with absolutely no warranty expressed
6  * or implied. Any use is at your own risk.
7  *
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.
13  *
14  */
15 
16 /* NOTE: This is an internal header file, included by other STL headers.
17  * You should not attempt to use it directly.
18  */
19 
20 #ifndef _STLP_POINTERS_SPEC_TOOLS_H
21 #define _STLP_POINTERS_SPEC_TOOLS_H
22 
23 #ifndef _STLP_TYPE_TRAITS_H
24 # include <stl/type_traits.h>
25 #endif
26 
28 
29 //Some usefull declarations:
30 template <class _Tp> struct less;
31 
33 
34 template <class _StorageT, class _ValueT, class _BinaryPredicate>
36 
37 /*
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
42  */
44 { _VoidPointerShim(void*); };
46 { _ConstVoidPointerShim(const void*); };
48 { _VolatileVoidPointerShim(volatile void*); };
50 { _ConstVolatileVoidPointerShim(const volatile void*); };
51 
52 //The dispatch functions:
53 template <class _Tp>
54 char _UseVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
55 char _UseVoidPtrStorageType(const __true_type& /*POD*/, ...);
57 
58 template <class _Tp>
59 char _UseConstVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
60 char _UseConstVoidPtrStorageType(const __true_type& /*POD*/, ...);
62 
63 template <class _Tp>
64 char _UseVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
65 char _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...);
67 
68 template <class _Tp>
69 char _UseConstVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
70 char _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...);
72 
73 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
74 /* Thanks to class partial specialization the pointer specialization feature can even be used in
75  * presence of incomplete type:
76  * struct MyStruct {
77  * typedef vector<MyStruct> MyStructContainer;
78  * typedef MyStructContainer::iterator MyStructIterator;
79  * };
80  */
81 
82 template <class _Tp>
83 struct _StorageType {
84  typedef _Tp _QualifiedType;
85  typedef _Tp _Type;
86  enum { use_const_volatile_void_ptr = 0 };
87 };
88 
89 template <class _Tp>
90 struct _StorageType<_Tp*> {
91  // Even if we detect a pointer type we use dispatch function to consider if it can be stored as a void*.
92  // For instance function pointer might not necessarily be convertible to void*.
94  __STATIC_CAST(_Tp*, 0))) == sizeof(char*)) };
96  typedef typename __select<use_void_ptr,
97  void*,
98  _Tp*>::_Ret _QualifiedType;
99  typedef _QualifiedType _Type;
100 };
101 
102 template <class _Tp>
103 struct _StorageType<_Tp const*> {
105  __STATIC_CAST(const _Tp*, 0))) == sizeof(char*)) };
107  typedef typename __select<use_void_ptr,
108  const void*,
109  const _Tp*>::_Ret _QualifiedType;
110  typedef typename __select<use_void_ptr,
111  void*,
112  const _Tp*>::_Ret _Type;
113 };
114 
115 template <class _Tp>
116 struct _StorageType<_Tp volatile*> {
118  __STATIC_CAST(_Tp volatile*, 0))) == sizeof(char*)) };
120  typedef typename __select<use_void_ptr,
121  volatile void*,
122  volatile _Tp*>::_Ret _QualifiedType;
123  typedef typename __select<use_void_ptr,
124  void*,
125  volatile _Tp*>::_Ret _Type;
126 };
127 
128 template <class _Tp>
129 struct _StorageType<_Tp const volatile*> {
131  __STATIC_CAST(_Tp const volatile*, 0))) == sizeof(char*)) };
133  typedef typename __select<use_void_ptr,
134  const volatile void*,
135  const volatile _Tp*>::_Ret _QualifiedType;
136  typedef typename __select<use_void_ptr,
137  void*,
138  const volatile _Tp*>::_Ret _Type;
139 };
140 #else
141 template <class _Tp>
142 struct _StorageType {
144 
145 #if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
146  static _Tp __null_rep();
147 #else
148  static _Tp __null_rep;
149 #endif
150  enum { use_void_ptr = (sizeof(_UseVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
151  enum { use_const_void_ptr = (sizeof(_UseConstVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
152  enum { use_volatile_void_ptr = (sizeof(_UseVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
154 
155  typedef typename __select<!use_const_volatile_void_ptr,
156  _Tp,
157  typename __select<use_void_ptr,
158  void*,
159  typename __select<use_const_void_ptr,
160  const void*,
162  volatile void*,
163  const volatile void*>::_Ret >::_Ret >::_Ret >::_Ret _QualifiedType;
164 
165 #if !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
166  /* If the compiler do not support the iterator_traits structure we cannot wrap
167  * iterators pass to container template methods. The iterator dereferenced value
168  * has to be storable without any cast in the chosen storage type. To guaranty
169  * that the void pointer has to be correctly qualified.
170  */
172 #else
173  /* With iterator_traits we can wrap passed iterators and make the necessary casts.
174  * We can always use a simple void* storage type:
175  */
176  typedef typename __select<use_const_volatile_void_ptr,
177  void*,
178  _Tp>::_Ret _Type;
179 #endif
180 };
181 #endif
182 
183 template <class _Tp, class _Compare>
186  typedef typename _StorageTypeInfo::_Type _SType;
187 
188  //We need to also check that the comparison functor used to instanciate the assoc container
189  //is the default Standard less implementation:
194  typedef typename __select<is_default_less && ptr_type,
196  _Compare>::_Ret _CompareStorageType;
197 };
198 
199 
200 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
201 /*
202  * Base struct to deal with qualifiers
203  */
204 template <class _StorageT, class _QualifiedStorageT>
205 struct _VoidCastTraitsAux {
206  typedef _QualifiedStorageT void_cv_type;
207  typedef _StorageT void_type;
208 
209  static void_type * uncv_ptr(void_cv_type *__ptr)
210  { return __ptr; }
211  static void_type const* uncv_cptr(void_cv_type const*__ptr)
212  { return __ptr; }
213  static void_type ** uncv_pptr(void_cv_type **__ptr)
214  { return __ptr; }
215  static void_type & uncv_ref(void_cv_type & __ref)
216  { return __ref; }
217  static void_type const& uncv_cref(void_cv_type const& __ref)
218  { return __ref; }
219  static void_cv_type* cv_ptr(void_type *__ptr)
220  { return __ptr; }
221  static void_cv_type const* cv_cptr(void_type const*__ptr)
222  { return __ptr; }
223  static void_cv_type ** cv_pptr(void_type **__ptr)
224  { return __ptr; }
225  static void_cv_type & cv_ref(void_type & __ref)
226  { return __ref; }
227  static void_cv_type const& cv_cref(void_type const& __ref)
228  { return __ref; }
229 };
230 
231 template <class _VoidCVType>
232 struct _VoidCastTraitsAuxBase {
233  typedef _VoidCVType* void_cv_type;
234  typedef void* void_type;
235 
236  static void_type* uncv_ptr(void_cv_type *__ptr)
237  { return __CONST_CAST(void_type*, __ptr); }
238  static void_type const* uncv_cptr(void_cv_type const*__ptr)
239  { return __CONST_CAST(void_type const*, __ptr); }
240  static void_type** uncv_pptr(void_cv_type **__ptr)
241  { return __CONST_CAST(void_type**, __ptr); }
242  static void_type& uncv_ref(void_cv_type &__ref)
243  { return __CONST_CAST(void_type&, __ref); }
244  static void_type const& uncv_cref(void_cv_type const& __ptr)
245  { return __CONST_CAST(void_type const&, __ptr); }
246  // The reverse versions
247  static void_cv_type * cv_ptr(void_type *__ptr)
248  { return __CONST_CAST(void_cv_type *, __ptr); }
249  static void_cv_type const* cv_cptr(void_type const*__ptr)
250  { return __CONST_CAST(void_cv_type const*, __ptr); }
251  static void_cv_type ** cv_pptr(void_type **__ptr)
252  { return __CONST_CAST(void_cv_type**, __ptr); }
253  static void_cv_type & cv_ref(void_type &__ref)
254  { return __CONST_CAST(void_cv_type &, __ref); }
255  static void_cv_type const& cv_cref(void_type const& __ref)
256  { return __CONST_CAST(void_cv_type const&, __ref); }
257 };
258 
260 struct _VoidCastTraitsAux<void*, const void*> : _VoidCastTraitsAuxBase<void const>
261 {};
263 struct _VoidCastTraitsAux<void*, volatile void*> : _VoidCastTraitsAuxBase<void volatile>
264 {};
266 struct _VoidCastTraitsAux<void*, const volatile void*> : _VoidCastTraitsAuxBase<void const volatile>
267 {};
268 
269 template <class _StorageT, class _ValueT>
270 struct _CastTraits {
271  typedef _ValueT value_type;
272  typedef typename _StorageType<_ValueT>::_QualifiedType _QualifiedStorageT;
273  typedef _VoidCastTraitsAux<_StorageT, _QualifiedStorageT> cv_traits;
274  typedef typename cv_traits::void_type void_type;
275  typedef typename cv_traits::void_cv_type void_cv_type;
276 
277  static value_type * to_value_type_ptr(void_type *__ptr)
278  { return __REINTERPRET_CAST(value_type *, cv_traits::cv_ptr(__ptr)); }
279  static value_type const* to_value_type_cptr(void_type const*__ptr)
280  { return __REINTERPRET_CAST(value_type const*, cv_traits::cv_cptr(__ptr)); }
281  static value_type ** to_value_type_pptr(void_type **__ptr)
282  { return __REINTERPRET_CAST(value_type **, cv_traits::cv_pptr(__ptr)); }
283  static value_type & to_value_type_ref(void_type &__ref)
284  { return __REINTERPRET_CAST(value_type &, cv_traits::cv_ref(__ref)); }
285  static value_type const& to_value_type_cref(void_type const& __ptr)
286  { return __REINTERPRET_CAST(value_type const&, cv_traits::cv_cref(__ptr)); }
287  // Reverse versions
288  static void_type * to_storage_type_ptr(value_type *__ptr)
289  { return cv_traits::uncv_ptr(__REINTERPRET_CAST(void_cv_type *, __ptr)); }
290  static void_type const* to_storage_type_cptr(value_type const*__ptr)
291  { return cv_traits::uncv_cptr(__REINTERPRET_CAST(void_cv_type const*, __ptr)); }
292  static void_type ** to_storage_type_pptr(value_type **__ptr)
293  { return cv_traits::uncv_pptr(__REINTERPRET_CAST(void_cv_type **, __ptr)); }
294  static void_type const& to_storage_type_cref(value_type const& __ref)
295  { return cv_traits::uncv_cref(__REINTERPRET_CAST(void_cv_type const&, __ref)); }
296 
297  //Method used to treat set container template method extension
298  static void_type const& to_storage_type_crefT(value_type const& __ref)
299  { return to_storage_type_cref(__ref); }
300 };
301 
302 template <class _Tp>
303 struct _CastTraits<_Tp, _Tp> {
304  typedef _Tp storage_type;
305  typedef _Tp value_type;
306 
307  static value_type * to_value_type_ptr(storage_type *__ptr)
308  { return __ptr; }
309  static value_type const* to_value_type_cptr(storage_type const*__ptr)
310  { return __ptr; }
311  static value_type ** to_value_type_pptr(storage_type **__ptr)
312  { return __ptr; }
313  static value_type & to_value_type_ref(storage_type &__ref)
314  { return __ref; }
315  static value_type const& to_value_type_cref(storage_type const&__ref)
316  { return __ref; }
317  // Reverse versions
319  { return __ptr; }
320  static storage_type const* to_storage_type_cptr(value_type const*__ptr)
321  { return __ptr; }
322  static storage_type ** to_storage_type_pptr(value_type **__ptr)
323  { return __ptr; }
324  static storage_type const& to_storage_type_cref(value_type const& __ref)
325  { return __ref; }
326 
327  //Method used to treat set container template method extension
328  template <class _Tp1>
329  static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref)
330  { return __ref; }
331 };
332 
333 #define _STLP_USE_ITERATOR_WRAPPER
334 
335 template <class _StorageT, class _ValueT, class _Iterator>
336 struct _IteWrapper {
337  typedef _CastTraits<_StorageT, _ValueT> cast_traits;
338  typedef iterator_traits<_Iterator> _IteTraits;
339 
340  typedef typename _IteTraits::iterator_category iterator_category;
341  typedef _StorageT value_type;
342  typedef typename _IteTraits::difference_type difference_type;
343  typedef value_type* pointer;
344  typedef value_type const& const_reference;
345  //This wrapper won't be used for input so to avoid surprise
346  //the reference type will be a const reference:
347  typedef const_reference reference;
348 
349  typedef _IteWrapper<_StorageT, _ValueT, _Iterator> _Self;
350  typedef _Self _Ite;
351 
352  _IteWrapper(_Iterator &__ite) : _M_ite(__ite) {}
353 
354  const_reference operator*() const { return cast_traits::to_storage_type_cref(*_M_ite); }
355 
356  _Self& operator= (_Self const& __rhs) {
357  _M_ite = __rhs._M_ite;
358  return *this;
359  }
360 
361  _Self& operator++() {
362  ++_M_ite;
363  return *this;
364  }
365 
366  _Self& operator--() {
367  --_M_ite;
368  return *this;
369  }
370 
371  _Self& operator += (difference_type __offset) {
372  _M_ite += __offset;
373  return *this;
374  }
375  difference_type operator -(_Self const& __other) const
376  { return _M_ite - __other._M_ite; }
377 
378  bool operator == (_Self const& __other) const
379  { return _M_ite == __other._M_ite; }
380 
381  bool operator != (_Self const& __other) const
382  { return _M_ite != __other._M_ite; }
383 
384  bool operator < (_Self const& __rhs) const
385  { return _M_ite < __rhs._M_ite; }
386 
387 private:
388  _Iterator _M_ite;
389 };
390 
391 template <class _Tp, class _Iterator>
392 struct _IteWrapper<_Tp, _Tp, _Iterator>
393 { typedef _Iterator _Ite; };
394 
395 #else
396 
397 /*
398  * In this config the storage type is qualified in respect of the
399  * value_type qualification. Simple reinterpret_cast is enough.
400  */
401 template <class _StorageT, class _ValueT>
402 struct _CastTraits {
403  typedef _StorageT storage_type;
404  typedef _ValueT value_type;
405 
407  { return __REINTERPRET_CAST(value_type*, __ptr); }
408  static value_type const* to_value_type_cptr(storage_type const*__ptr)
409  { return __REINTERPRET_CAST(value_type const*, __ptr); }
411  { return __REINTERPRET_CAST(value_type **, __ptr); }
413  { return __REINTERPRET_CAST(value_type&, __ref); }
414  static value_type const& to_value_type_cref(storage_type const&__ref)
415  { return __REINTERPRET_CAST(value_type const&, __ref); }
416  // Reverse versions
418  { return __REINTERPRET_CAST(storage_type*, __ptr); }
419  static storage_type const* to_storage_type_cptr(value_type const*__ptr)
420  { return __REINTERPRET_CAST(storage_type const*, __ptr); }
422  { return __REINTERPRET_CAST(storage_type **, __ptr); }
423  static storage_type const& to_storage_type_cref(value_type const&__ref)
424  { return __REINTERPRET_CAST(storage_type const&, __ref); }
425  template <class _Tp1>
426  static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref)
427  { return __ref; }
428 };
429 
430 #endif
431 
432 //Wrapper functors:
433 template <class _StorageT, class _ValueT, class _UnaryPredicate>
436 
437  _UnaryPredWrapper (_UnaryPredicate const& __pred) : _M_pred(__pred) {}
438 
439  bool operator () (_StorageT const& __ref) const
440  { return _M_pred(cast_traits::to_value_type_cref(__ref)); }
441 
442 private:
443  _UnaryPredicate _M_pred;
444 };
445 
446 template <class _StorageT, class _ValueT, class _BinaryPredicate>
447 struct _BinaryPredWrapper {
449 
451  _BinaryPredWrapper (_BinaryPredicate const& __pred) : _M_pred(__pred) {}
452 
453  _BinaryPredicate get_pred() const { return _M_pred; }
454 
455  bool operator () (_StorageT const& __fst, _StorageT const& __snd) const
457 
458  //Cast operator used to transparently access underlying predicate
459  //in set::key_comp() method
460  operator _BinaryPredicate() const
461  { return _M_pred; }
462 
463 private:
464  _BinaryPredicate _M_pred;
465 };
466 
468 
470 
471 #endif /* _STLP_POINTERS_SPEC_TOOLS_H */
__type_traits< _Tp >::is_POD_type _PODType
Definition: _tools.h:143
static _Tp1 const & to_storage_type_crefT(_Tp1 const &__ref)
Definition: _tools.h:426
static value_type const & to_value_type_cref(storage_type const &__ref)
Definition: _tools.h:414
char _UseConstVolatileVoidPtrStorageType(const __false_type &, const _Tp &)
complex< _Tp > _STLP_CALL operator *(const _Tp &__x, const complex< _Tp > &__z)
Definition: _complex.h:644
_QualifiedType _Type
Definition: _tools.h:171
static storage_type * to_storage_type_ptr(value_type *__ptr)
Definition: _tools.h:417
GLsizei const GLvoid * pointer
Definition: glext.h:5848
_ConstVolatileVoidPointerShim(const volatile void *)
#define __STATIC_CAST(__x, __y)
Definition: features.h:585
_UnaryPredicate _M_pred
Definition: _tools.h:443
_STLP_INLINE_LOOP _InputIter _Predicate __pred
Definition: _algo.h:68
_StorageType< _Tp > _StorageTypeInfo
Definition: _tools.h:185
__select< is_default_less &&ptr_type, _BinaryPredWrapper< _KeyStorageType, _Tp, _Compare >, _Compare >::_Ret _CompareStorageType
Definition: _tools.h:196
bool operator()(_StorageT const &__ref) const
Definition: _tools.h:439
#define _STLP_MOVE_TO_PRIV_NAMESPACE
Definition: features.h:524
_IsSTLportClass< _Compare >::_Ret _STLportLess
Definition: _tools.h:191
static value_type ** to_value_type_pptr(storage_type **__ptr)
Definition: _tools.h:410
bool operator()(_StorageT const &__fst, _StorageT const &__snd) const
Definition: _tools.h:455
static value_type & to_value_type_ref(storage_type &__ref)
Definition: _tools.h:412
_UnaryPredWrapper(_UnaryPredicate const &__pred)
Definition: _tools.h:437
char _UseConstVoidPtrStorageType(const __false_type &, const _Tp &)
_CastTraits< _StorageT, _ValueT > cast_traits
Definition: _tools.h:448
_Tp2 _Ret
Definition: type_manips.h:150
_StorageTypeInfo::_Type _SType
Definition: _tools.h:186
static value_type * to_value_type_ptr(storage_type *__ptr)
Definition: _tools.h:406
_VoidPointerShim(void *)
__select< is_default_less, _SType, _Tp >::_Ret _KeyStorageType
Definition: _tools.h:193
#define volatile
Definition: prototyp.h:117
#define _STLP_MOVE_TO_STD_NAMESPACE
Definition: features.h:525
__select<!use_const_volatile_void_ptr, _Tp, typename __select< use_void_ptr, void *, typename __select< use_const_void_ptr, const void *, typename __select< use_volatile_void_ptr, volatile void *, const volatile void * >::_Ret >::_Ret >::_Ret >::_Ret _QualifiedType
Definition: _tools.h:163
_BinaryPredicate get_pred() const
Definition: _tools.h:453
bool operator !=(const SortClass &lhs, const SortClass &rhs)
Definition: SortClass.h:70
_BinaryPredWrapper(_BinaryPredicate const &__pred)
Definition: _tools.h:451
_ValueT value_type
Definition: _tools.h:404
bool operator<(const TKeyDef &t1, const TKeyDef &t2)
Definition: tkeydef.cpp:126
_StorageT storage_type
Definition: _tools.h:403
bool operator==(const TKeyDef &t1, const TKeyDef &t2)
Definition: tkeydef.cpp:122
GLint reference
Definition: glext.h:11729
_VolatileVoidPointerShim(volatile void *)
#define __REINTERPRET_CAST(__x, __y)
Definition: features.h:586
#define _STLP_TEMPLATE_NULL
Definition: features.h:652
_BinaryPredicate _M_pred
Definition: _tools.h:464
rope< _CharT, _Alloc > & operator+=(rope< _CharT, _Alloc > &__left, const rope< _CharT, _Alloc > &__right)
Definition: _rope.h:2202
#define __CONST_CAST(__x, __y)
Definition: features.h:584
#define _STLP_END_NAMESPACE
Definition: features.h:503
static value_type const * to_value_type_cptr(storage_type const *__ptr)
Definition: _tools.h:408
static storage_type const * to_storage_type_cptr(value_type const *__ptr)
Definition: _tools.h:419
char _UseVoidPtrStorageType(const __false_type &, const _Tp &)
#define const
Definition: zconf.h:230
#define _STLP_BEGIN_NAMESPACE
Definition: features.h:501
static storage_type ** to_storage_type_pptr(value_type **__ptr)
Definition: _tools.h:421
_CastTraits< _StorageT, _ValueT > cast_traits
Definition: _tools.h:435
static storage_type const & to_storage_type_cref(value_type const &__ref)
Definition: _tools.h:423
char _UseVolatileVoidPtrStorageType(const __false_type &, const _Tp &)
static _Tp __null_rep()
_ConstVoidPointerShim(const void *)