1#ifndef _STDEX_NULLPTR_H
2#define _STDEX_NULLPTR_H
29 #define STDEX_NULL NULL
31 #define STDEX_NULL (void*)0
38 namespace nullptr_detail
40 typedef char _yes_type;
46 struct _dummy_class {};
48 _yes_type _is_convertable_to_void_ptr_tester(
void*);
49 _no_type _is_convertable_to_void_ptr_tester(...);
51 typedef void(nullptr_detail::_dummy_class::*_dummy_class_f)(int);
52 typedef int (nullptr_detail::_dummy_class::*_dummy_class_f_const)(
double&)
const;
54 _yes_type _is_convertable_to_member_function_ptr_tester(_dummy_class_f);
55 _no_type _is_convertable_to_member_function_ptr_tester(...);
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(...);
61 _yes_type _is_convertable_to_ptr_tester(_Tp*);
63 _no_type _is_convertable_to_ptr_tester(...);
66 _yes_type _is_convertable_to_int_tester(_Tp);
67 _no_type _is_convertable_to_int_tester(
void*);
79 class _nullptr_t_as_class_impl {
85 _nullptr_t_as_class_impl() { }
86 _nullptr_t_as_class_impl(
int) { }
89 template<
class _Tp>
operator _Tp*()
const {
return 0; }
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; }
101 class _nullptr_t_as_class_impl1 {
107 _nullptr_t_as_class_impl1() { }
108 _nullptr_t_as_class_impl1(
int) { }
111 template<
class _Tp>
operator _Tp*()
const {
return 0; }
113 bool operator==(_nullptr_t_as_class_impl1)
const {
return true; }
114 bool operator!=(_nullptr_t_as_class_impl1)
const {
return false; }
124 namespace ptrdiff_detail
126 using std::ptrdiff_t;
129 template<
class _T1,
class _T2>
132 static const bool value =
sizeof(_T1) ==
sizeof(_T2);
136 struct _pointer_as_long_type {
typedef const long type; };
138 struct _pointer_as_long_type<false> {
typedef const long type; };
140 struct _pointer_as_short_type {
typedef const short type; };
142 struct _pointer_as_short_type<false> {
typedef _pointer_as_long_type<_sizeof_cmp<long, void*>::value>::type type; };
144 struct _pointer_as_int_type {
typedef const int type; };
146 struct _pointer_as_int_type<false> {
typedef _pointer_as_short_type<_sizeof_cmp<short, void*>::value>::type type; };
149 struct _pointer_as_ulong_type {
typedef const unsigned long type; };
151 struct _pointer_as_ulong_type<false> {
typedef const unsigned long type; };
153 struct _pointer_as_ushort_type {
typedef const unsigned short type; };
155 struct _pointer_as_ushort_type<false> {
typedef _pointer_as_long_type<_sizeof_cmp<unsigned long, void*>::value>::type type; };
157 struct _pointer_as_uint_type {
typedef const unsigned int type; };
159 struct _pointer_as_uint_type<false> {
typedef _pointer_as_short_type<_sizeof_cmp<unsigned short, void*>::value>::type type; };
162 struct _pointer_as_integral_type_impl {
typedef _pointer_as_int_type<_sizeof_cmp<int, void*>::value>::type type; };
164 struct _pointer_as_integral_type_impl<false> {
typedef _pointer_as_uint_type<_sizeof_cmp<int, void*>::value>::type type; };
166 struct _ptrdiff_is_signed
168 static const bool value = (ptrdiff_detail::ptrdiff_t)(-1) < (ptrdiff_detail::ptrdiff_t)(0);
171 struct _pointer_is_signed
173 static const bool value =
true;
177 struct _pointer_as_ptrdiff_type {
typedef const ptrdiff_detail::ptrdiff_t type; };
179 struct _pointer_as_ptrdiff_type<false>:
180 _pointer_as_integral_type_impl<_ptrdiff_is_signed::value>
185 struct _nullptr_as_ptrdiff_type:
186 _pointer_as_ptrdiff_type<_sizeof_cmp<ptrdiff_detail::ptrdiff_t, void*>::value>
190 struct _nullptr_as_ptrdiff_type<false>:
191 _pointer_as_integral_type_impl<_pointer_is_signed::value>
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;
199 struct _nullptr_t_as_enum_chooser;
201 template<
class _EnumType,
bool>
202 struct _nullptr_t_as_enum_chooser_helper
204 typedef _EnumType type;
207 template<
class _EnumType>
208 struct _nullptr_t_as_enum_chooser_helper<_EnumType, false>
212 _nullptr_val = _EnumType::_nullptr_val,
213 _max_nullptr = _EnumType::_max_nullptr + 1
218 struct _nullptr_t_as_enum_chooser<true>
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)
227 _nullptr_t_as_enum_chooser_helper<
229 _sizeof_cmp<_type, void*>::value
234 struct _nullptr_t_as_enum_chooser<false>
238 _nullptr_val = _nullptr_t_as_integral(STDEX_NULL),
239 _max_nullptr = _nullptr_t_as_uint(1) << (CHAR_BIT *
sizeof(
void*) - 1)
243 typedef _nullptr_t_as_enum_chooser<_pointer_is_signed::value>::type _nullptr_t_as_enum;
245 typedef void* _nullptr_t_as_void;
248 namespace nullptr_comparison_detail
250 template<
class _T1,
class _T2>
251 nullptr_detail::_no_type operator==(_T1, _T2);
254 struct _nullptr_can_be_compared_to_ptr
256 static const int *_ptr;
257 static const bool value =
sizeof(((_Tp) (STDEX_NULL)) == _ptr) !=
sizeof(nullptr_detail::_no_type);
262 struct _nullptr_can_be_ct_constant_impl
265 static const bool value =
false;
268 namespace nullptr_detail
271 struct _is_convertable_to_void_ptr_impl
273 static const bool value = (
sizeof(_is_convertable_to_void_ptr_tester((_Tp) (STDEX_NULL))) ==
sizeof(_yes_type));
276 struct _NULL_is_convertable_to_int
278 static const bool value =
279 (
sizeof(_is_convertable_to_int_tester(STDEX_NULL)) ==
sizeof(_yes_type));
283 struct _is_convertable_to_member_function_ptr_impl
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));
290 template<
class NullPtrType,
class _Tp>
291 struct _is_convertable_to_any_ptr_impl_helper
293 static const bool value = (
sizeof(_is_convertable_to_ptr_tester<_Tp>((NullPtrType) (STDEX_NULL))) ==
sizeof(_yes_type));
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;
302 struct _is_convertable_to_any_ptr_impl
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;
316 struct _is_convertable_to_ptr_impl
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)
326 struct _is_equal_size_to_void_ptr
328 static const bool value = (
sizeof(_Tp) ==
sizeof(
void*));
331 struct _member_ptr_is_same_as_ptr
334 typedef void(test::*member_ptr_type)(void);
335 static const bool value = _is_convertable_to_void_ptr_impl<member_ptr_type>::value;
339 struct _nullptr_t_as_class_chooser
341 typedef nullptr_detail::_nullptr_t_as_class_impl type;
345 struct _nullptr_t_as_class_chooser<false>
347 typedef nullptr_detail::_nullptr_t_as_class_impl1 type;
351 struct _nullptr_choose_as_int
353 typedef nullptr_detail::_nullptr_t_as_integral type;
357 struct _nullptr_choose_as_enum
359 typedef nullptr_detail::_nullptr_t_as_enum type;
363 struct _nullptr_choose_as_class
365 typedef _nullptr_t_as_class_chooser<_member_ptr_is_same_as_ptr::value>::type type;
369 struct _nullptr_choose_as_int<false>
371 typedef nullptr_detail::_nullptr_t_as_void type;
374 template<
class _NullptrType,
bool>
375 struct _nullptr_t_can_be_compared_to_ptr_impl
377 static const bool value =
378 nullptr_comparison_detail::_nullptr_can_be_compared_to_ptr<_NullptrType>::value;
381 template<
class _NullptrType>
382 struct _nullptr_t_can_be_compared_to_ptr_impl<_NullptrType, false>
384 static const bool value =
false;
387 template<
class _NullptrType>
388 struct _nullptr_t_can_be_compared_to_ptr
390 static const bool value =
391 _nullptr_t_can_be_compared_to_ptr_impl<_NullptrType, _is_convertable_to_ptr_impl<_NullptrType>::value>::value;
395 struct _nullptr_choose_as_enum<false>
399 typedef nullptr_detail::_nullptr_t_as_integral _nullptr_t_as_integral;
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;
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))
413 struct _nullptr_choose_as_class<false>
417 typedef nullptr_detail::_nullptr_t_as_enum _nullptr_t_as_enum;
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;
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))
429 struct _nullptr_chooser
435 typedef _nullptr_t_as_class_chooser<_member_ptr_is_same_as_ptr::value>::type _nullptr_t_as_class;
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;
441 typedef _nullptr_choose_as_class<
442 (_as_class::_equal_void_ptr == bool(
true) && _as_class::_can_be_ct_constant == bool(
true))
447 typedef detail::_nullptr_chooser::type nullptr_t;
455#define nullptr (stdex::nullptr_t)(STDEX_NULL)