Changeset 377 for trunk/nv/stl/type_traits.hh
- Timestamp:
- 05/28/15 17:34:27 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/stl/type_traits.hh
r376 r377 9 9 * @brief type traits 10 10 */ 11 // TODO: "......" function match version? 12 // TODO: remove typeinfo? 13 11 // TODO : "......" function match version? 12 // TODO : the following symbols are unimplemented: 13 // * is_constructible, is_trivially_constructible, is_nothrow_constructible 14 // * is_default_constructible, is_trivially_default_constructible, is_nothrow_default_constructible 15 // * is_copy_constructible, is_trivially_copy_constructible, is_copy_default_constructible 16 // * is_move_constructible, is_trivially_move_constructible, is_move_default_constructible 17 // * is_trivially_assignable, is_nothrow_assignable 18 // * is_trivially_copy_assignable, is_nothrow_copy_assignable 19 // * is_trivially_move_assignable, is_nothrow_move_assignable 20 // * is_destructible, is_trivially_destructible, is_nothrow_destructible 14 21 15 22 #ifndef NV_STL_TYPE_TRAITS_HH … … 17 24 18 25 #include <nv/core/common.hh> 19 20 namespace nv 21 { 22 23 template < typename T1, typename T2 > 24 struct is_same : false_type {}; 25 26 template < typename T > 27 struct is_same < T, T > : true_type {}; 28 29 template < typename T > 30 struct is_array : false_type {}; 31 32 template < typename T, size_t N > 33 struct is_array < T[N] > : true_type {}; 34 35 template < typename T > 36 struct is_array < T[] > : true_type {}; 37 38 template < typename T > 39 struct is_lvalue_reference : false_type {}; 40 41 template < typename T > 42 struct is_lvalue_reference < T& > : true_type{}; 43 44 template < typename T > 45 struct is_rvalue_reference : false_type {}; 46 47 template < typename T > 48 struct is_rvalue_reference < T&& > : true_type{}; 49 50 template < typename _Ty> 51 struct is_reference : integral_constant < bool, is_lvalue_reference<_Ty>::value || is_rvalue_reference<_Ty>::value > {}; 52 53 template < typename T > 54 struct is_enum : integral_constant < bool, __is_enum( T ) > {}; 55 56 // TODO: these seem to simple compared to MSVC/GCC - so we'll leave them in 57 // detail - research why it is so. 58 template < typename T > 59 struct is_const : false_type {}; 60 template < typename T > 61 struct is_const < T const > : true_type{}; 62 template < typename T > 63 struct is_volatile : false_type {}; 64 template < typename T > 65 struct is_volatile < T volatile > : true_type{}; 66 // TODO END 67 68 template< typename T > 69 struct remove_reference 70 { 71 typedef T type; 72 }; 73 74 template< typename T > 75 struct remove_reference < T& > 76 { 77 typedef T type; 78 }; 79 80 template< typename T > 81 struct remove_reference < T&& > 82 { 83 typedef T type; 84 }; 85 86 template< typename T > 87 struct remove_const 88 { 89 typedef T type; 90 }; 91 92 template< typename T > 93 struct remove_const < const T > 94 { 95 typedef T type; 96 }; 97 98 template< typename T > 99 struct remove_const < const T[] > 100 { 101 typedef T type[]; 102 }; 103 104 template< typename T, unsigned int N > 105 struct remove_const < const T[N] > 106 { 107 typedef T type[N]; 108 }; 109 110 template< typename T > 111 struct remove_volatile 112 { 113 typedef T type; 114 }; 115 116 template< typename T > 117 struct remove_volatile < volatile T > 118 { 119 typedef T type; 120 }; 121 122 template< typename T > 123 struct remove_volatile < volatile T[] > 124 { 125 typedef T type[]; 126 }; 127 128 template< typename T, unsigned int N > 129 struct remove_volatile < volatile T[N] > 130 { 131 typedef T type[N]; 132 }; 133 134 template< typename T > 135 struct remove_cv 136 { 137 typedef typename remove_const< typename remove_volatile<T>::type >::type 138 type; 139 }; 140 141 template< typename T > 142 struct remove_cvr 143 { 144 typedef typename remove_cv< typename remove_reference<T>::type >::type 145 type; 146 }; 147 148 template< typename T > 149 struct remove_pointer 150 { 151 typedef T type; 152 }; 153 154 template< typename T > struct remove_pointer < T* > { typedef T type; }; 155 template< typename T > struct remove_pointer < T* const > { typedef T type; }; 156 template< typename T > struct remove_pointer < T* volatile > { typedef T type; }; 157 template< typename T > struct remove_pointer < T* const volatile > { typedef T type; }; 158 159 template< typename T > 160 struct remove_extent 161 { 162 typedef T type; 163 }; 164 165 template< typename T, unsigned int N > 166 struct remove_extent < T[N] > 167 { 168 typedef T type; 169 }; 170 171 template< typename T > 172 struct remove_extent < T[] > 173 { 174 typedef T type; 175 }; 176 177 template< typename T > 178 struct remove_all_extents 179 { 180 typedef T type; 181 }; 182 183 template< typename T, unsigned int N > 184 struct remove_all_extents < T[N] > 185 { 186 typedef typename remove_all_extents<T>::type type; 187 }; 188 189 template< typename T > 190 struct remove_all_extents < T[] > 191 { 192 typedef typename remove_all_extents<T>::type type; 193 }; 194 195 template< typename T > 196 struct add_pointer 197 { 198 typedef typename remove_reference<T>::type *type; 199 }; 200 201 namespace detail 202 { 203 template< typename T, bool CONST, bool VOLATILE> 204 struct cv_selector; 205 206 template< typename T > 207 struct cv_selector < T, false, false > { typedef T type; }; 208 209 template< typename T > 210 struct cv_selector < T, true, false > { typedef const T type; }; 211 212 template< typename T > 213 struct cv_selector < T, false, true > { typedef volatile T type; }; 214 215 template< typename T > 216 struct cv_selector < T, true, true > { typedef const volatile T type; }; 217 218 template< typename SOURCE, typename TARGET, 219 bool CONST = is_const<SOURCE>::value, 220 bool VOLATILE = is_volatile<SOURCE>::value > 221 struct match_cv 222 { 223 typedef typename cv_selector< TARGET, CONST, VOLATILE >::type type; 224 }; 225 226 template < typename T > 227 struct is_void_impl : false_type{}; 228 229 template <> 230 struct is_void_impl< void > : true_type {}; 231 232 template< typename T > 233 struct is_integral_impl : false_type {}; 234 235 template<> struct is_integral_impl< bool > : true_type {}; 236 template<> struct is_integral_impl< char > : true_type {}; 237 template<> struct is_integral_impl< signed char > : true_type {}; 238 template<> struct is_integral_impl< unsigned char > : true_type {}; 239 template<> struct is_integral_impl< wchar_t > : true_type {}; 240 template<> struct is_integral_impl< signed short > : true_type {}; 241 template<> struct is_integral_impl< unsigned short > : true_type {}; 242 template<> struct is_integral_impl< signed int > : true_type {}; 243 template<> struct is_integral_impl< unsigned int > : true_type {}; 244 template<> struct is_integral_impl< signed long > : true_type {}; 245 template<> struct is_integral_impl< unsigned long > : true_type {}; 246 template<> struct is_integral_impl< signed long long > : true_type{}; 247 template<> struct is_integral_impl< unsigned long long > : true_type{}; 248 249 template< typename T > struct is_floating_point_impl : false_type {}; 250 251 template<> struct is_floating_point_impl< float > : true_type{}; 252 template<> struct is_floating_point_impl< double > : true_type{}; 253 template<> struct is_floating_point_impl< long double > : true_type{}; 254 255 template < typename T > 256 struct signed_type 257 { 258 typedef T type; 259 }; 260 261 template<> struct signed_type < char > { typedef signed char type; }; 262 template<> struct signed_type < unsigned char > { typedef signed char type; }; 263 template<> struct signed_type < unsigned short > { typedef signed short type; }; 264 template<> struct signed_type < unsigned int > { typedef signed int type; }; 265 template<> struct signed_type < unsigned long > { typedef signed long type; }; 266 template<> struct signed_type < unsigned long long > { typedef signed long long type; }; 267 268 template < typename T > 269 struct unsigned_type 270 { 271 typedef T type; 272 }; 273 274 template<> struct unsigned_type < char > { typedef unsigned char type; }; 275 template<> struct unsigned_type < signed char > { typedef unsigned char type; }; 276 template<> struct unsigned_type < signed short > { typedef unsigned short type; }; 277 template<> struct unsigned_type < signed int > { typedef unsigned int type; }; 278 template<> struct unsigned_type < signed long > { typedef unsigned long type; }; 279 template<> struct unsigned_type < signed long long > { typedef unsigned long long type; }; 280 281 template < typename T, bool IS_ENUM = is_enum< T >::value > 282 struct make_signed_impl; 283 284 template < typename T > 285 struct make_signed_impl < T, false > 286 { 287 private: 288 typedef signed_type<typename remove_cv<T>::type> signed_type_result; 289 public: 290 typedef match_cv< T, typename signed_type_result::type > type; 291 }; 292 293 template < typename T > 294 struct make_signed_impl < T, true > 295 { 296 private: 297 static const bool size1test = sizeof( T ) <= sizeof( signed char ); 298 static const bool size2test = sizeof( T ) <= sizeof( signed short ); 299 static const bool size4test = sizeof( T ) <= sizeof( signed int ); 300 typedef typename conditional<size4test, signed int, signed long>::type test4type; 301 typedef typename conditional<size2test, signed short, test4type>::type test2type; 302 public: 303 typedef typename conditional<size1test, signed char, test2type>::type type; 304 }; 305 306 template < typename T, bool IS_ENUM = is_enum< T >::value > 307 struct make_unsigned_impl; 308 309 template < typename T > 310 struct make_unsigned_impl < T, false > 311 { 312 private: 313 typedef unsigned_type<typename remove_cv<T>::type> unsigned_type_result; 314 public: 315 typedef match_cv< T, typename unsigned_type_result::type > type; 316 }; 317 318 template < typename T > 319 struct make_unsigned_impl < T, true > 320 { 321 private: 322 static const bool size1test = sizeof( T ) <= sizeof( unsigned char ); 323 static const bool size2test = sizeof( T ) <= sizeof( unsigned short ); 324 static const bool size4test = sizeof( T ) <= sizeof( unsigned int ); 325 typedef typename conditional<size4test, unsigned int, unsigned long>::type test4type; 326 typedef typename conditional<size2test, unsigned short, test4type>::type test2type; 327 public: 328 typedef typename conditional<size1test, unsigned char, test2type>::type type; 329 }; 330 } 331 332 template <typename T> struct is_signed : false_type {}; 333 334 template <> struct is_signed<signed char> : true_type {}; 335 template <> struct is_signed<const signed char> : true_type {}; 336 template <> struct is_signed<signed short> : true_type {}; 337 template <> struct is_signed<const signed short> : true_type {}; 338 template <> struct is_signed<signed int> : true_type {}; 339 template <> struct is_signed<const signed int> : true_type {}; 340 template <> struct is_signed<signed long> : true_type {}; 341 template <> struct is_signed<const signed long> : true_type {}; 342 template <> struct is_signed<signed long long> : true_type{}; 343 template <> struct is_signed<const signed long long> : true_type{}; 344 345 template <typename T> struct is_unsigned : false_type {}; 346 347 template <> struct is_unsigned<unsigned char> : true_type{}; 348 template <> struct is_unsigned<const unsigned char> : true_type{}; 349 template <> struct is_unsigned<unsigned short> : true_type{}; 350 template <> struct is_unsigned<const unsigned short> : true_type{}; 351 template <> struct is_unsigned<unsigned int> : true_type{}; 352 template <> struct is_unsigned<const unsigned int> : true_type{}; 353 template <> struct is_unsigned<unsigned long> : true_type{}; 354 template <> struct is_unsigned<const unsigned long> : true_type{}; 355 template <> struct is_unsigned<unsigned long long> : true_type{}; 356 template <> struct is_unsigned<const unsigned long long> : true_type{}; 357 358 template <> struct is_signed<char> : integral_constant<bool, ( char( 0 ) > char( -1 ) ) >{}; 359 template <> struct is_unsigned<char> : integral_constant<bool, ( char( 0 ) < char( -1 ) ) > {}; 360 361 362 template < typename T > 363 struct make_signed 364 { 365 typedef typename detail::make_signed_impl<T>::type type; 366 }; 367 368 template <> struct make_signed < bool > ; 369 370 template < typename T > 371 struct make_unsigned 372 { 373 typedef typename detail::make_unsigned_impl<T>::type type; 374 }; 375 376 template <> struct make_unsigned < bool > ; 377 378 template< typename T > 379 struct is_void : detail::is_void_impl < typename remove_cv<T>::type > 380 { 381 }; 382 383 template< typename T > 384 struct is_integral : detail::is_integral_impl< typename remove_cv<T>::type > 385 { 386 }; 387 388 template< typename T > 389 struct is_floating_point : detail::is_floating_point_impl< typename remove_cv<T>::type > 390 { 391 }; 392 393 template < typename T > 394 struct is_arithmetic : integral_constant < bool, 395 is_integral<T>::value || is_floating_point<T>::value > 396 { 397 }; 398 399 template <typename T> 400 struct is_fundamental : integral_constant < bool, 401 is_void<T>::value || is_integral<T>::value || is_floating_point<T>::value > 402 { 403 }; 404 405 #if NV_COMPILER == NV_MSVC || NV_COMPILER == NV_CLANG 406 template < typename T > 407 struct underlying_type 408 { 409 typedef __underlying_type( T ) type; 410 }; 411 #else 412 template< typename T > 413 struct underlying_type 414 { 415 typedef typename conditional < 416 T( -1 ) < T( 0 ), 417 typename make_signed< T >::type, 418 typename make_unsigned< T >::type 419 > ::type type; 420 }; 421 #endif 422 423 template <typename T> 424 struct is_empty : integral_constant < bool, __is_empty( T ) > {}; 425 426 template < typename T > 427 struct is_pod : integral_constant < bool, __is_pod( T ) > {}; 428 429 template < typename T > 430 struct has_trivial_constructor : integral_constant < bool, __has_trivial_constructor( T ) || __is_pod( T ) > {}; 431 432 #if NV_COMPILER == NV_MSVC 433 template < typename T > 434 struct has_trivial_copy : integral_constant < bool, ( __has_trivial_copy( T ) || __is_pod( T ) ) && !is_volatile<T>::value > {}; 435 #else 436 template < typename T > 437 struct has_trivial_copy : integral_constant < bool, ( __has_trivial_copy( T ) || __is_pod( T ) ) && ( !is_volatile<T>::value && !is_reference<T>::value ) > {}; 438 #endif 439 440 template < typename T > 441 struct has_trivial_assign : integral_constant < bool, ( __has_trivial_assign( T ) || __is_pod( T ) ) && ( !is_volatile<T>::value && !is_const<T>::value ) > {}; 442 443 template < typename T > 444 struct has_trivial_destructor : integral_constant < bool, __has_trivial_destructor( T ) || __is_pod( T ) > {}; 445 446 template < typename T > 447 struct has_virtual_destructor : integral_constant < bool, __has_virtual_destructor( T ) > {}; 448 449 450 namespace detail 451 { 452 453 template < typename F > 454 struct function_traits_impl 455 { 456 457 }; 458 459 template < typename R > 460 struct function_traits_impl< R (*)(void) > 461 { 462 typedef R (*type)(); 463 typedef R return_type; 464 typedef void class_type; 465 static const int arg_count = 0; 466 }; 467 468 template < typename R, typename... Args > 469 struct function_traits_impl < R(*)(Args...) > 470 { 471 typedef R(*type)( Args... ); 472 typedef R return_type; 473 typedef void class_type; 474 static const int arg_count = sizeof...(Args); 475 }; 476 477 template < class C, typename R > 478 struct function_traits_impl< R (C::*)() > 479 { 480 typedef R (*type)(); 481 typedef R return_type; 482 typedef C class_type; 483 static const int arg_count = 0; 484 }; 485 486 template < class C, typename R, typename... Args > 487 struct function_traits_impl < R(C::*)(Args...) > 488 { 489 typedef R(C::*type)(Args...); 490 typedef R return_type; 491 typedef C class_type; 492 static const int arg_count = sizeof...(Args); 493 }; 494 495 template< typename T, typename IS_ENUM > 496 struct base_underlying_type_impl 497 { 498 typedef T type; 499 }; 500 501 template< typename T > 502 struct base_underlying_type_impl < T, true_type > 503 { 504 typedef typename underlying_type<T>::type type; 505 }; 506 507 template < typename T > struct is_pointer_impl : false_type {}; 508 509 template < typename T > struct is_pointer_impl< T* > : true_type{}; 510 template < typename T > struct is_pointer_impl< T* const > : true_type{}; 511 template < typename T > struct is_pointer_impl< T* volatile > : true_type{}; 512 template < typename T > struct is_pointer_impl< T* const volatile > : true_type{}; 513 514 } 515 516 template < typename F > 517 struct function_traits : detail::function_traits_impl< F > 518 { 519 520 }; 521 522 template < typename T > 523 struct return_type 524 { 525 typedef typename function_traits< T >::return_type type; 526 }; 527 528 template < typename T > 529 struct memfn_class_type 530 { 531 typedef typename function_traits< T >::class_type type; 532 }; 533 534 template < typename T > 535 struct base_underlying_type 536 { 537 typedef typename detail::base_underlying_type_impl< T, typename is_enum<T>::type >::type type; 538 }; 539 540 template < typename F > struct is_function_pointer : false_type {}; 541 #if NV_COMPILER == NV_MSVC 542 template < typename R, typename... Args > struct is_function_pointer< R( __cdecl * )( Args... ) > : true_type{}; 543 template < typename R, typename... Args > struct is_function_pointer< R( __stdcall * )( Args... ) > : true_type{}; 544 template < typename R, typename... Args > struct is_function_pointer< R( __fastcall * )( Args... ) > : true_type{}; 545 template < typename R, typename... Args > struct is_function_pointer< R( __vectorcall * )( Args... ) > : true_type{}; 546 #else 547 template < typename R, typename... Args > struct is_function_pointer< R( *)( Args... ) > : true_type{}; 548 #endif 549 550 template < typename C > struct is_member_function_pointer : false_type {}; 551 #if NV_COMPILER == NV_MSVC 552 #define NV_IS_MEMFNPTR( call_conv ) \ 553 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( call_conv C::* )( Args... ) > : true_type{}; \ 554 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( call_conv C::* )( Args... ) const > : true_type{}; \ 555 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( call_conv C::* )( Args... ) volatile > : true_type{}; \ 556 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( call_conv C::* )( Args... ) const volatile > : true_type{}; 557 558 NV_IS_MEMFNPTR( __thiscall ) 559 NV_IS_MEMFNPTR( __cdecl ) 560 NV_IS_MEMFNPTR( __stdcall ) 561 NV_IS_MEMFNPTR( __fastcall ) 562 NV_IS_MEMFNPTR( __vectorcall ) 563 564 #undef NV_IS_MEMFNPTR 565 #else 566 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( C::* )( Args... ) > : true_type{}; 567 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( C::* )( Args... ) const > : true_type{}; 568 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( C::* )( Args... ) volatile > : true_type{}; 569 template < typename R, typename C, typename... Args > struct is_member_function_pointer< R( C::* )( Args... ) const volatile > : true_type{}; 570 #endif 571 572 template < typename F > struct is_member_pointer : integral_constant < bool, is_member_function_pointer<F>::value > {}; 573 template < typename C, typename R > struct is_member_pointer<R C::*> : true_type {}; 574 575 template < typename T > 576 struct is_pointer : integral_constant< bool, (detail::is_pointer_impl<T>::value) && !(is_member_pointer<T>::value) > {}; 577 578 template< typename T > 579 struct is_function : integral_constant< bool, is_function_pointer< typename remove_cv<T>::type *>::value > {}; 580 581 template< typename T > 582 struct is_function < T& > : false_type {}; 583 584 template< typename T > 585 struct is_function < T&& > : false_type {}; 586 587 template< typename T > 588 struct decay 589 { 590 typedef typename remove_reference<T>::type U; 591 typedef typename conditional < 592 is_array<U>::value, 593 typename remove_extent<U>::type*, 594 typename conditional < 595 is_function<U>::value, 596 typename add_pointer<U>::type, 597 typename remove_cv<U>::type 598 > ::type 599 > ::type type; 600 }; 601 602 #if NV_COMPILER == NV_MSVC 603 typedef double max_align_t; 604 #elif NV_PLATFORM == NV_APPLE 605 typedef long double max_align_t; 606 #else 607 namespace detail 608 { 609 class aligned_dummy; 610 typedef void( *aligned_fptr )( ); 611 typedef int( aligned_dummy::*aligned_memptr ); 612 typedef int ( aligned_dummy::*aligned_memfptr )( ); 613 } 614 615 union max_align_t 616 { 617 double dummy0; 618 long double dummy1; 619 void* dummy2; 620 long long dummy3; 621 detail::aligned_fptr dummy4; 622 detail::aligned_memptr dummy5; 623 detail::aligned_memfptr dummy6; 624 }; 625 #endif 626 627 #if NV_COMPILER == NV_CLANG 628 template< typename T, size_t Size, size_t Align > 629 struct aligned_array 630 { 631 typedef T alignas( Align ) type[Size]; 632 }; 633 #elif NV_COMPILER == NV_GNUC 634 template< typename T, size_t Size, size_t Align > 635 struct aligned_array 636 { 637 typedef T __attribute__((aligned( Align ))) type[Size]; 638 }; 639 #else 640 // TODO: remove this shit after moving to MSVC 2015 641 template< typename T, size_t Size, size_t Align > 642 struct aligned_array; 643 644 // According to LLVM ( https://llvm.org/svn/llvm-project/llvm/trunk/include/llvm/Support/AlignOf.h ) 645 // MSVC has problems with align below 16... 646 #define NV_ALIGNED_ARRAY(N) \ 647 template< typename T, size_t Size > \ 648 struct aligned_array< T, Size, N > \ 649 { \ 650 typedef __declspec( align(N) ) T type[Size]; \ 651 }; 652 653 NV_ALIGNED_ARRAY( 1 ) 654 NV_ALIGNED_ARRAY( 2 ) 655 NV_ALIGNED_ARRAY( 4 ) 656 NV_ALIGNED_ARRAY( 8 ) 657 NV_ALIGNED_ARRAY( 16 ) 658 NV_ALIGNED_ARRAY( 32 ) 659 NV_ALIGNED_ARRAY( 64 ) 660 NV_ALIGNED_ARRAY( 128 ) 661 662 #undef NV_ALIGNED_ARRAY 663 #endif 664 665 template< size_t Size, size_t Align = NV_ALIGN_OF( max_align_t ) > 666 struct aligned_storage 667 { 668 struct type 669 { 670 typename aligned_array< unsigned char, Size, Align >::type data; 671 }; 672 }; 673 674 } 26 #include <nv/stl/traits/common.hh> 27 #include <nv/stl/traits/primary.hh> 28 #include <nv/stl/traits/properties.hh> 29 #include <nv/stl/traits/alignment.hh> 30 #include <nv/stl/traits/transforms.hh> 31 #include <nv/stl/traits/function.hh> 675 32 676 33 #endif // NV_STL_TYPE_TRAITS_HH
Note: See TracChangeset
for help on using the changeset viewer.