Photon microGUI widgets library 0.6.0
nullptr.h
1#ifndef _STDEX_NULLPTR_H
2#define _STDEX_NULLPTR_H
3
4#if _MSC_VER > 1000
5#pragma once
6#endif // _MSC_VER > 1000
7
8#include <climits>
9
10// searching for NULL
11#include <cstddef>
12#ifndef NULL
13 #include <cstdio>
14#endif
15#ifndef NULL
16 #include <cstdlib>
17#endif
18#ifndef NULL
19 #include <cstring>
20#endif
21#ifndef NULL
22 #include <ctime>
23#endif
24#ifndef NULL
25 #include <clocale>
26#endif
27
28#ifdef NULL
29 #define STDEX_NULL NULL
30#else
31 #define STDEX_NULL (void*)0
32#endif
33
34namespace stdex
35{
36 namespace detail
37 {
38 namespace nullptr_detail
39 {
40 typedef char _yes_type;
41 struct _no_type
42 {
43 char padding[8];
44 };
45
46 struct _dummy_class {};
47
48 _yes_type _is_convertable_to_void_ptr_tester(void*);
49 _no_type _is_convertable_to_void_ptr_tester(...);
50
51 typedef void(nullptr_detail::_dummy_class::*_dummy_class_f)(int);
52 typedef int (nullptr_detail::_dummy_class::*_dummy_class_f_const)(double&) const;
53
54 _yes_type _is_convertable_to_member_function_ptr_tester(_dummy_class_f);
55 _no_type _is_convertable_to_member_function_ptr_tester(...);
56
57 _yes_type _is_convertable_to_const_member_function_ptr_tester(_dummy_class_f_const);
58 _no_type _is_convertable_to_const_member_function_ptr_tester(...);
59
60 template<class _Tp>
61 _yes_type _is_convertable_to_ptr_tester(_Tp*);
62 template<class>
63 _no_type _is_convertable_to_ptr_tester(...);
64
65 template<class _Tp>
66 _yes_type _is_convertable_to_int_tester(_Tp);
67 _no_type _is_convertable_to_int_tester(void*);
68
69 /*template<int> struct sfinae_true
70 {
71 typedef _yes_type type;
72 };
73
74 template<class T>
75 typename sfinae_true<((T)(STDEX_NULL) == (T)(STDEX_NULL))>::type _nullptr_can_be_ct_constant(int);
76 template<class>
77 _no_type _nullptr_can_be_ct_constant(...);*/
78
79 class _nullptr_t_as_class_impl {
80 public:
81 // Required in order to create const nullptr_t objects without an
82 // explicit initializer in GCC 4.5, a la:
83 //
84 // const std::nullptr_t nullptr;
85 _nullptr_t_as_class_impl() { }
86 _nullptr_t_as_class_impl(int) { }
87
88 // Make nullptr convertible to any pointer type.
89 template<class _Tp> operator _Tp*() const { return 0; }
90 // Make nullptr convertible to any member pointer type.
91 template<class _Cp, class _Tp> operator _Tp _Cp::*() { return 0; }
92 bool operator==(_nullptr_t_as_class_impl) const { return true; }
93 bool operator!=(_nullptr_t_as_class_impl) const { return false; }
94 private:
95 // Do not allow taking the address of nullptr.
96 void operator&();
97
98 void *_padding;
99 };
100
101 class _nullptr_t_as_class_impl1 {
102 public:
103 // Required in order to create const nullptr_t objects without an
104 // explicit initializer in GCC 4.5, a la:
105 //
106 // const std::nullptr_t nullptr;
107 _nullptr_t_as_class_impl1() { }
108 _nullptr_t_as_class_impl1(int) { }
109
110 // Make nullptr convertible to any pointer type.
111 template<class _Tp> operator _Tp*() const { return 0; }
112
113 bool operator==(_nullptr_t_as_class_impl1) const { return true; }
114 bool operator!=(_nullptr_t_as_class_impl1) const { return false; }
115 private:
116 // Do not allow taking the address of nullptr.
117 void operator&();
118
119
120
121 void *_padding;
122 };
123
124 namespace ptrdiff_detail
125 {
126 using std::ptrdiff_t;
127 }
128
129 template<class _T1, class _T2>
130 struct _sizeof_cmp
131 {
132 static const bool value = sizeof(_T1) == sizeof(_T2);
133 };
134
135 template<bool>
136 struct _pointer_as_long_type { typedef const long type; };
137 template<>
138 struct _pointer_as_long_type<false> { typedef const long type; };
139 template<bool>
140 struct _pointer_as_short_type { typedef const short type; };
141 template<>
142 struct _pointer_as_short_type<false> { typedef _pointer_as_long_type<_sizeof_cmp<long, void*>::value>::type type; };
143 template<bool>
144 struct _pointer_as_int_type { typedef const int type; };
145 template<>
146 struct _pointer_as_int_type<false> { typedef _pointer_as_short_type<_sizeof_cmp<short, void*>::value>::type type; };
147
148 template<bool>
149 struct _pointer_as_ulong_type { typedef const unsigned long type; };
150 template<>
151 struct _pointer_as_ulong_type<false> { typedef const unsigned long type; };
152 template<bool>
153 struct _pointer_as_ushort_type { typedef const unsigned short type; };
154 template<>
155 struct _pointer_as_ushort_type<false> { typedef _pointer_as_long_type<_sizeof_cmp<unsigned long, void*>::value>::type type; };
156 template<bool>
157 struct _pointer_as_uint_type { typedef const unsigned int type; };
158 template<>
159 struct _pointer_as_uint_type<false> { typedef _pointer_as_short_type<_sizeof_cmp<unsigned short, void*>::value>::type type; };
160
161 template<bool>
162 struct _pointer_as_integral_type_impl { typedef _pointer_as_int_type<_sizeof_cmp<int, void*>::value>::type type; };
163 template<>
164 struct _pointer_as_integral_type_impl<false> { typedef _pointer_as_uint_type<_sizeof_cmp<int, void*>::value>::type type; };
165
166 struct _ptrdiff_is_signed
167 {
168 static const bool value = (ptrdiff_detail::ptrdiff_t)(-1) < (ptrdiff_detail::ptrdiff_t)(0);
169 };
170
171 struct _pointer_is_signed
172 {
173 static const bool value = true;
174 };
175
176 template<bool>
177 struct _pointer_as_ptrdiff_type { typedef const ptrdiff_detail::ptrdiff_t type; };
178 template<>
179 struct _pointer_as_ptrdiff_type<false>:
180 _pointer_as_integral_type_impl<_ptrdiff_is_signed::value>
181 { };
182
183
184 template<bool>
185 struct _nullptr_as_ptrdiff_type:
186 _pointer_as_ptrdiff_type<_sizeof_cmp<ptrdiff_detail::ptrdiff_t, void*>::value>
187 { };
188
189 template<>
190 struct _nullptr_as_ptrdiff_type<false>:
191 _pointer_as_integral_type_impl<_pointer_is_signed::value>
192 { };
193
194 typedef _pointer_as_integral_type_impl<false>::type _nullptr_t_as_uint;
195 typedef _pointer_as_integral_type_impl<true>::type _nullptr_t_as_int;
196 typedef _nullptr_as_ptrdiff_type<(_ptrdiff_is_signed::value == _pointer_is_signed::value)>::type _nullptr_t_as_integral;
197
198 template<bool>
199 struct _nullptr_t_as_enum_chooser;
200
201 template<class _EnumType, bool>
202 struct _nullptr_t_as_enum_chooser_helper
203 {
204 typedef _EnumType type;
205 };
206
207 template<class _EnumType>
208 struct _nullptr_t_as_enum_chooser_helper<_EnumType, false>
209 {
210 enum type
211 {
212 _nullptr_val = _EnumType::_nullptr_val,
213 _max_nullptr = _EnumType::_max_nullptr + 1
214 };
215 };
216
217 template<>
218 struct _nullptr_t_as_enum_chooser<true>
219 {
220 enum _type
221 {
222 _nullptr_val = _nullptr_t_as_integral(STDEX_NULL),
223 _max_nullptr = _nullptr_t_as_integral((_nullptr_t_as_uint(1) << (CHAR_BIT * sizeof(void*) - 2)) / 2)
224 };
225
226 typedef
227 _nullptr_t_as_enum_chooser_helper<
228 _type,
229 _sizeof_cmp<_type, void*>::value
230 >::type type;
231 };
232
233 template<>
234 struct _nullptr_t_as_enum_chooser<false>
235 {
236 enum type
237 {
238 _nullptr_val = _nullptr_t_as_integral(STDEX_NULL),
239 _max_nullptr = _nullptr_t_as_uint(1) << (CHAR_BIT * sizeof(void*) - 1)
240 };
241 };
242
243 typedef _nullptr_t_as_enum_chooser<_pointer_is_signed::value>::type _nullptr_t_as_enum;
244
245 typedef void* _nullptr_t_as_void;
246 } // namespace nullptr_detail
247
248 namespace nullptr_comparison_detail
249 {
250 template<class _T1, class _T2>
251 nullptr_detail::_no_type operator==(_T1, _T2);
252
253 template<class _Tp>
254 struct _nullptr_can_be_compared_to_ptr
255 {
256 static const int *_ptr;
257 static const bool value = sizeof(((_Tp) (STDEX_NULL)) == _ptr) != sizeof(nullptr_detail::_no_type);
258 };
259 } // namespace nullptr_comparison_detail
260
261 template<class _Tp>
262 struct _nullptr_can_be_ct_constant_impl
263 {
264 // idk how to check for compile time constantness of type in general for any c++98 compiler, so...
265 static const bool value = false;// (sizeof(nullptr_detail::_nullptr_can_be_ct_constant<T>(0)) == sizeof(nullptr_detail::_yes_type));
266 };
267
268 namespace nullptr_detail
269 {
270 template<class _Tp>
271 struct _is_convertable_to_void_ptr_impl
272 {
273 static const bool value = (sizeof(_is_convertable_to_void_ptr_tester((_Tp) (STDEX_NULL))) == sizeof(_yes_type));
274 };
275
276 struct _NULL_is_convertable_to_int
277 {
278 static const bool value =
279 (sizeof(_is_convertable_to_int_tester(STDEX_NULL)) == sizeof(_yes_type));
280 };
281
282 template<class _Tp>
283 struct _is_convertable_to_member_function_ptr_impl
284 {
285 static const bool value =
286 (sizeof(_is_convertable_to_member_function_ptr_tester((_Tp) (STDEX_NULL))) == sizeof(_yes_type)) &&
287 (sizeof(_is_convertable_to_const_member_function_ptr_tester((_Tp) (STDEX_NULL))) == sizeof(_yes_type));
288 };
289
290 template<class NullPtrType, class _Tp>
291 struct _is_convertable_to_any_ptr_impl_helper
292 {
293 static const bool value = (sizeof(_is_convertable_to_ptr_tester<_Tp>((NullPtrType) (STDEX_NULL))) == sizeof(_yes_type));
294 };
295 }
296
297 using nullptr_detail::_is_convertable_to_void_ptr_impl;
298 using nullptr_detail::_is_convertable_to_member_function_ptr_impl;
299 using nullptr_detail::_is_convertable_to_any_ptr_impl_helper;
300
301 template<class _Tp>
302 struct _is_convertable_to_any_ptr_impl
303 {
304
305
306 static const bool value = _is_convertable_to_any_ptr_impl_helper<_Tp, int>::value &&
307 _is_convertable_to_any_ptr_impl_helper<_Tp, float>::value &&
308 _is_convertable_to_any_ptr_impl_helper<_Tp, bool>::value &&
309 _is_convertable_to_any_ptr_impl_helper<_Tp, const bool>::value &&
310 _is_convertable_to_any_ptr_impl_helper<_Tp, volatile float>::value &&
311 _is_convertable_to_any_ptr_impl_helper<_Tp, volatile const double>::value &&
312 _is_convertable_to_any_ptr_impl_helper<_Tp, nullptr_detail::_dummy_class>::value;
313 };
314
315 template<class _Tp>
316 struct _is_convertable_to_ptr_impl
317 {
318 static const bool value = (
319 _is_convertable_to_void_ptr_impl<_Tp>::value == bool(true) &&
320 _is_convertable_to_any_ptr_impl<_Tp>::value == bool(true) &&
321 _is_convertable_to_member_function_ptr_impl<_Tp>::value == bool(true)
322 );
323 };
324
325 template<class _Tp>
326 struct _is_equal_size_to_void_ptr
327 {
328 static const bool value = (sizeof(_Tp) == sizeof(void*));
329 };
330
331 struct _member_ptr_is_same_as_ptr
332 {
333 struct test {};
334 typedef void(test::*member_ptr_type)(void);
335 static const bool value = _is_convertable_to_void_ptr_impl<member_ptr_type>::value;
336 };
337
338 template<bool>
339 struct _nullptr_t_as_class_chooser
340 {
341 typedef nullptr_detail::_nullptr_t_as_class_impl type;
342 };
343
344 template<>
345 struct _nullptr_t_as_class_chooser<false>
346 {
347 typedef nullptr_detail::_nullptr_t_as_class_impl1 type;
348 };
349
350 template<bool>
351 struct _nullptr_choose_as_int
352 {
353 typedef nullptr_detail::_nullptr_t_as_integral type;
354 };
355
356 template<bool>
357 struct _nullptr_choose_as_enum
358 {
359 typedef nullptr_detail::_nullptr_t_as_enum type;
360 };
361
362 template<bool>
363 struct _nullptr_choose_as_class
364 {
365 typedef _nullptr_t_as_class_chooser<_member_ptr_is_same_as_ptr::value>::type type;
366 };
367
368 template<>
369 struct _nullptr_choose_as_int<false>
370 {
371 typedef nullptr_detail::_nullptr_t_as_void type;
372 };
373
374 template<class _NullptrType, bool>
375 struct _nullptr_t_can_be_compared_to_ptr_impl
376 {
377 static const bool value =
378 nullptr_comparison_detail::_nullptr_can_be_compared_to_ptr<_NullptrType>::value;
379 };
380
381 template<class _NullptrType>
382 struct _nullptr_t_can_be_compared_to_ptr_impl<_NullptrType, false>
383 {
384 static const bool value = false;
385 };
386
387 template<class _NullptrType>
388 struct _nullptr_t_can_be_compared_to_ptr
389 {
390 static const bool value =
391 _nullptr_t_can_be_compared_to_ptr_impl<_NullptrType, _is_convertable_to_ptr_impl<_NullptrType>::value>::value;
392 };
393
394 template<>
395 struct _nullptr_choose_as_enum<false>
396 {
397 struct _as_int
398 {
399 typedef nullptr_detail::_nullptr_t_as_integral _nullptr_t_as_integral;
400
401 static const bool _is_convertable_to_ptr = _is_convertable_to_ptr_impl<_nullptr_t_as_integral>::value;
402 static const bool _equal_void_ptr = _is_equal_size_to_void_ptr<_nullptr_t_as_integral>::value;
403 static const bool _can_be_compared_to_ptr = _nullptr_t_can_be_compared_to_ptr<_nullptr_t_as_integral>::value;
404 };
405
406 typedef _nullptr_choose_as_int<
407 (nullptr_detail::_NULL_is_convertable_to_int::value == bool(true)) &&
408 (_as_int::_is_convertable_to_ptr == bool(true) && _as_int::_equal_void_ptr == bool(true) && _as_int::_can_be_compared_to_ptr == bool(true))
409 >::type type;
410 };
411
412 template<>
413 struct _nullptr_choose_as_class<false>
414 {
415 struct _as_enum
416 {
417 typedef nullptr_detail::_nullptr_t_as_enum _nullptr_t_as_enum;
418
419 static const bool _is_convertable_to_ptr = _is_convertable_to_ptr_impl<_nullptr_t_as_enum>::value;
420 static const bool _equal_void_ptr = _is_equal_size_to_void_ptr<_nullptr_t_as_enum>::value;
421 static const bool _can_be_ct_constant = true;//_nullptr_can_be_ct_constant_impl<_nullptr_t_as_enum>::value;
422 };
423
424 typedef _nullptr_choose_as_enum<
425 (_as_enum::_is_convertable_to_ptr == bool(true) && _as_enum::_equal_void_ptr == bool(true) && _as_enum::_can_be_ct_constant == bool(true))
426 >::type type;
427 };
428
429 struct _nullptr_chooser
430 {
431
432
433 struct _as_class
434 {
435 typedef _nullptr_t_as_class_chooser<_member_ptr_is_same_as_ptr::value>::type _nullptr_t_as_class;
436
437 static const bool _equal_void_ptr = _is_equal_size_to_void_ptr<_nullptr_t_as_class>::value;
438 static const bool _can_be_ct_constant = _nullptr_can_be_ct_constant_impl<_nullptr_t_as_class>::value;
439 };
440
441 typedef _nullptr_choose_as_class<
442 (_as_class::_equal_void_ptr == bool(true) && _as_class::_can_be_ct_constant == bool(true))
443 >::type type;
444 };
445 } // namespace detail
446
447 typedef detail::_nullptr_chooser::type nullptr_t;
448
449} // namespace stdex
450
451#ifdef nullptr
452 #undef nullptr
453#endif
454
455#define nullptr (stdex::nullptr_t)(STDEX_NULL)
456
457
458#endif // _STDEX_NULLPTR_H