Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_meta_rel.h
Go to the documentation of this file.
1
30#ifndef _RWSTD_RW_META_REL_H_INCLUDED
31#define _RWSTD_RW_META_REL_H_INCLUDED
32
33#include <rw/_defs.h>
34
35#ifndef _RWSTD_TT_IS_CONVERTIBLE
36# include <rw/_meta_arr.h>
37# include <rw/_meta_ptr.h>
38# include <rw/_meta_ref.h>
39# include <rw/_meta_cat.h>
40# include <rw/_meta_cv.h>
41#endif // _RWSTD_TT_IS_CONVERTIBLE
42
43#ifndef _RWSTD_TT_IS_BASE_OF
44# include <rw/_meta_cv.h>
45# include <rw/_meta_ptr.h>
46#endif //_RWSTD_TT_IS_BASE_OF
47
49
50template <class _TypeT, class _TypeU>
51struct __rw_is_same : __rw_false_type
52{
53};
54
55template <class _TypeT>
56struct __rw_is_same<_TypeT, _TypeT> : __rw_true_type
57{
58};
59
60#define _RWSTD_IS_SAME(T,U) _RW::__rw_is_same<T,U>::value
61
62
63#ifndef _RWSTD_TT_IS_BASE_OF
64
65//
66// Primary template handles case that either of _Base or _Derived
67// is not a class type.
68//
69template <class _Base, class _Derived,
70 bool = __rw_is_class<_Base>::value
71 && __rw_is_class<_Derived>::value>
72struct __rw_is_base_of_impl
73{
74 enum { _C_value = 0 };
75};
76
77//
78// This specialization is for the case that _Base and
79// _Derived are class types, but not the same type.
80//
81// This little gem was taken from a comp.lang.c++.moderated post
82// by Rani Sharoni [see http://tinyurl.com/6pdv3k]
83//
84template <class _Base, class _Derived>
85struct __rw_is_base_of_impl<_Base, _Derived, true>
86{
87 struct _C_no { };
88 struct _C_yes { _C_no __pad [2]; };
89
90 struct _C_nest
91 {
92 operator const volatile _Base& () const;
93 operator const volatile _Derived& ();
94
95 // the template is used so that the compiler will prefer the
96 // non-template _C_is, in case that the conversion would be
97 // ambiguous (as it is in the case where the types are unrelated).
98 template <class _TypeT>
99 static _C_yes _C_is (const volatile _Derived&, _TypeT);
100 static _C_no _C_is (const volatile _Base& , int);
101 };
102
103 enum { _C_value =
104 _RW::__rw_is_same<const volatile _Base,
105 const volatile _Derived&>::value
106 || sizeof (_C_yes) == sizeof (_C_nest::_C_is (_C_nest (), 0))
107 };
108};
109
110//
111// This specialization is for the case that _Base and
112// _Derived are the same class type.
113//
114template <class _TypeT>
115struct __rw_is_base_of_impl<_TypeT, _TypeT, true>
116{
117 enum { _C_value = 1 };
118};
119
120# define _RWSTD_IS_BASE_OF(T,U) \
121 _RW::__rw_is_base_of_impl<T,U>::_C_value
122
123#elif defined (_MSC_VER)
124# define _RWSTD_IS_BASE_OF(T,U) \
125 ( _RW::__rw_is_class<T>::value \
126 && _RW::__rw_is_class<U>::value \
127 && _RWSTD_TT_IS_BASE_OF(T,U))
128#else
129# define _RWSTD_IS_BASE_OF(T,U) _RWSTD_TT_IS_BASE_OF(T,U)
130#endif // _RWSTD_TT_IS_BASE_OF
131
132template <class _Base, class _Derived>
133struct __rw_is_base_of
134 : __rw_integral_constant<bool, _RWSTD_IS_BASE_OF(_Base,_Derived)>
135{
136 //_RWSTD_ASSERT ( _RWSTD_IS_CLASS (_Base)
137 // && _RWSTD_IS_CLASS (_Derived)
138 // && !_RWSTD_IS_SAME(_Base, _Derived)
139 // ||
140};
141
142
143#if !defined (_RWSTD_TT_IS_CONVERTIBLE)
144
145template <class _From, class _To>
146struct __rw_is_convertible_impl
147{
148 struct _C_no { };
149 struct _C_yes { _C_no __pad [2]; };
150
151 struct _Dummy
152 {
153 template <class _Anything>
154 _Dummy (_Anything);
155 };
156
157 template <class _TypeT>
158 static _C_no _C_is (_Dummy, _TypeT);
159 static _C_yes _C_is (_To, int);
160
161 static _From _C_make ();
162
163 enum { _C_value = sizeof (_C_yes) == sizeof (_C_is (_C_make (), 0)) };
164};
165
166template <class _TypeT, class _TypeU,
167 bool = __rw_is_array<_TypeT>::value,
168 bool = __rw_is_function<_TypeT>::value>
169struct __rw_is_convertible_3
170{
171 // _TypeT is neither an array nor a function type, so just do a
172 // straight conversion test
173 enum { _C_value = __rw_is_convertible_impl<_TypeT, _TypeU>::_C_value };
174};
175
176template <class _TypeT, class _TypeU>
177struct __rw_is_convertible_3<_TypeT, _TypeU, true, false>
178{
179 // _TypeT is an array type, see if we can convert it to a _TypeU*
180 typedef typename __rw_remove_extent<_TypeT>::type _TypeV;
181 typedef typename __rw_add_pointer<_TypeV>::type _TypeT_Ptr;
182
183 enum { _C_value =
184 __rw_is_convertible_impl<_TypeT_Ptr, _TypeU>::_C_value };
185};
186
187template <class _TypeT, class _TypeU>
188struct __rw_is_convertible_3<_TypeT, _TypeU, false, true>
189{
190 // _TypeT is an function type, try to convert to reference or pointer
191 typedef typename __rw_add_lvalue_reference<_TypeT>::type _TypeT_Ref;
192 typedef typename __rw_add_pointer<_TypeT>::type _TypeT_Ptr;
193
194 enum { _C_value =
195 __rw_is_convertible_impl<_TypeT_Ref, _TypeU>::_C_value
196 || __rw_is_convertible_impl<_TypeT_Ptr, _TypeU>::_C_value };
197};
198
199template <class _TypeT, class _TypeU,
200 bool = __rw_is_array<_TypeU>::value
201 || __rw_is_function<_TypeU>::value>
202struct __rw_is_convertible_2
203{
204 // _TypeU is neither an array nor a function type
205 enum { _C_value = __rw_is_convertible_3<_TypeT, _TypeU>::_C_value };
206};
207
208template <class _TypeT, class _TypeU>
209struct __rw_is_convertible_2<_TypeT, _TypeU, true>
210{
211 // _TypeU is either an array or a function type, and we can't convert to
212 // either of those.
213 enum { _C_value = 0 };
214};
215
216template <class _TypeT, class _TypeU, bool = __rw_is_void<_TypeT>::value,
217 bool = __rw_is_void<_TypeU>::value>
218struct __rw_is_convertible_1
219{
220 // void-to-non-void or non-void to void
221 enum { _C_value = 0 };
222};
223
224template <class _TypeT, class _TypeU>
225struct __rw_is_convertible_1<_TypeT, _TypeU, false, false>
226{
227 // neither is _TypeT or _TypeU is (possibly cv-qualified) void
228 enum { _C_value = __rw_is_convertible_2<_TypeT,_TypeU>::_C_value };
229};
230
231template <class _TypeT, class _TypeU>
232struct __rw_is_convertible_1<_TypeT, _TypeU, true, true>
233{
234 // both _TypeT and _TypeU are (possibly cv-qualified) void
235 enum { _C_value = 1 };
236};
237
238# define _RWSTD_IS_CONVERTIBLE(T,U) \
239 _RW::__rw_is_convertible_1<T,U>::_C_value
240
241#elif defined (_MSC_VER)
242
243template <class _TypeT, class _TypeU>
244struct __rw_is_convertible_1
245{
246 enum { _C_value =
247 __rw_is_void<_TypeT>::value && __rw_is_void<_TypeU>::value
248 || _RWSTD_TT_IS_CONVERTIBLE(_TypeT, _TypeU) };
249};
250
251# define _RWSTD_IS_CONVERTIBLE(T,U) \
252 _RW::__rw_is_convertible_1<T,U>::_C_value
253
254#else
255# define _RWSTD_IS_CONVERTIBLE(T,U) _RWSTD_TT_IS_CONVERTIBLE(T,U)
256#endif // _RWSTD_TT_IS_CONVERTIBLE
257
258template <class _TypeT, class _TypeU>
259struct __rw_is_convertible
260 : __rw_integral_constant<bool, _RWSTD_IS_CONVERTIBLE(_TypeT,_TypeU)>
261{
262 //_RWSTD_COMPILE_ASSERT ( _RWSTD_IS_COMPLETE (_TypeT)
263 // || _RWSTD_IS_ARRAY (_TypeT)
264 // || _RWSTD_IS_VOID (_TypeT));
265};
266
267} // namespace __rw
268
269
270#endif // _RWSTD_RW_META_REL_H_INCLUDED
271
T value(const T &val)
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define true
Definition stdbool.h:25
#define false
Definition stdbool.h:26