/* * Copyright 2008-2012 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*! \file type_traits.h * \brief Temporarily define some type traits * until nvcc can compile tr1::type_traits. */ #pragma once #include // XXX nvcc 2.2 closed beta can't compile type_traits //// find type_traits // //#ifdef __GNUC__ // //#if __GNUC__ == 4 && __GNUC_MINOR__ == 2 //#include //#elif __GNUC__ == 4 && __GNUC_MINOR__ > 2 //#include //#endif // GCC version // //#endif // GCC // //#ifdef _MSC_VER //#include //#endif // MSVC namespace thrust { // forward declaration of device_reference template class device_reference; namespace detail { /// helper classes [4.3]. template struct integral_constant { static const _Tp value = __v; typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; }; /// typedef for true_type typedef integral_constant true_type; /// typedef for true_type typedef integral_constant false_type; //template struct is_integral : public std::tr1::is_integral {}; template struct is_integral : public false_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template<> struct is_integral : public true_type {}; template struct is_floating_point : public false_type {}; template<> struct is_floating_point : public true_type {}; template<> struct is_floating_point : public true_type {}; template<> struct is_floating_point : public true_type {}; template struct is_arithmetic : public is_integral {}; template<> struct is_arithmetic : public true_type {}; template<> struct is_arithmetic : public true_type {}; template<> struct is_arithmetic : public true_type {}; template<> struct is_arithmetic : public true_type {}; template struct is_pointer : public false_type {}; template struct is_pointer : public true_type {}; template struct is_device_ptr : public false_type {}; template struct is_void : public false_type {}; template<> struct is_void : public true_type {}; template<> struct is_void : public true_type {}; namespace tt_detail { } // end tt_detail template struct is_pod : public integral_constant< bool, is_void::value || is_pointer::value || is_arithmetic::value #if THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC // use intrinsic type traits || __is_pod(T) #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC // only use the intrinsic for >= 4.3 #if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) || __is_pod(T) #endif // GCC VERSION #endif // THRUST_HOST_COMPILER > {}; template struct has_trivial_constructor : public integral_constant< bool, is_pod::value #if THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC || __has_trivial_constructor(T) #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC // only use the intrinsic for >= 4.3 #if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) || __has_trivial_constructor(T) #endif // GCC VERSION #endif // THRUST_HOST_COMPILER > {}; template struct has_trivial_copy_constructor : public integral_constant< bool, is_pod::value #if THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC || __has_trivial_copy(T) #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC // only use the intrinsic for >= 4.3 #if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) || __has_trivial_copy(T) #endif // GCC VERSION #endif // THRUST_HOST_COMPILER > {}; template struct has_trivial_destructor : public is_pod {}; template struct is_const : public false_type {}; template struct is_const : public true_type {}; template struct is_volatile : public false_type {}; template struct is_volatile : public true_type {}; template struct add_const { typedef T const type; }; // end add_const template struct remove_const { typedef T type; }; // end remove_const template struct remove_const { typedef T type; }; // end remove_const template struct add_volatile { typedef volatile T type; }; // end add_volatile template struct remove_volatile { typedef T type; }; // end remove_volatile template struct remove_volatile { typedef T type; }; // end remove_volatile template struct add_cv { typedef const volatile T type; }; // end add_cv template struct remove_cv { typedef typename remove_const::type>::type type; }; // end remove_cv template struct is_reference : public false_type {}; template struct is_reference : public true_type {}; template struct is_device_reference : public false_type {}; template struct is_device_reference< thrust::device_reference > : public true_type {}; // NB: Careful with reference to void. template::value || is_reference<_Tp>::value)> struct __add_reference_helper { typedef _Tp& type; }; template struct __add_reference_helper<_Tp, true> { typedef _Tp type; }; template struct add_reference : public __add_reference_helper<_Tp>{}; template struct remove_reference { typedef T type; }; // end remove_reference template struct remove_reference { typedef T type; }; // end remove_reference template struct is_same : public false_type { }; // end is_same template struct is_same : public true_type { }; // end is_same template struct lazy_is_same : is_same { }; // end lazy_is_same template struct is_different : public true_type { }; // end is_different template struct is_different : public false_type { }; // end is_different template struct lazy_is_different : is_different { }; // end lazy_is_different namespace tt_detail { template struct is_int_or_cref { typedef typename remove_reference::type type_sans_ref; static const bool value = (is_integral::value || (is_integral::value && is_const::value && !is_volatile::value)); }; // end is_int_or_cref __THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING_BEGIN __THRUST_DISABLE_MSVC_FORCING_VALUE_TO_BOOL_BEGIN template struct is_convertible_sfinae { private: typedef char one_byte; typedef struct { char two_chars[2]; } two_bytes; static one_byte test(To); static two_bytes test(...); static From m_from; public: static const bool value = sizeof(test(m_from)) == sizeof(one_byte); }; // end is_convertible_sfinae __THRUST_DISABLE_MSVC_FORCING_VALUE_TO_BOOL_END __THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING_END template struct is_convertible_needs_simple_test { static const bool from_is_void = is_void::value; static const bool to_is_void = is_void::value; static const bool from_is_float = is_floating_point::type>::value; static const bool to_is_int_or_cref = is_int_or_cref::value; static const bool value = (from_is_void || to_is_void || (from_is_float && to_is_int_or_cref)); }; // end is_convertible_needs_simple_test template::value> struct is_convertible { static const bool value = (is_void::value || (is_int_or_cref::value && !is_void::value)); }; // end is_convertible template struct is_convertible { static const bool value = (is_convertible_sfinae::type, To>::value); }; // end is_convertible } // end tt_detail template struct is_convertible : public integral_constant::value> { }; // end is_convertible template struct is_one_convertible_to_the_other : public integral_constant< bool, is_convertible::value || is_convertible::value > {}; // mpl stuff template struct or_ : public integral_constant< bool, Condition1::value || Condition2::value || Condition3::value || Condition4::value || Condition5::value || Condition6::value || Condition7::value || Condition8::value || Condition9::value || Condition10::value > { }; // end or_ template struct and_ : public integral_constant { }; // end and_ template struct not_ : public integral_constant { }; // end not_ template struct eval_if { }; // end eval_if template struct eval_if { typedef typename Then::type type; }; // end eval_if template struct eval_if { typedef typename Else::type type; }; // end eval_if template // struct identity // XXX WAR nvcc's confusion with thrust::identity struct identity_ { typedef T type; }; // end identity template struct enable_if {}; template struct enable_if {typedef T type;}; template struct lazy_enable_if {}; template struct lazy_enable_if {typedef typename T::type type;}; template struct disable_if : enable_if {}; template struct lazy_disable_if : lazy_enable_if {}; template struct enable_if_convertible : enable_if< is_convertible::value, T > {}; template struct disable_if_convertible : disable_if< is_convertible::value, T > {}; template struct enable_if_different : enable_if::value, Result> {}; template struct is_numeric : and_< is_convertible, is_convertible > { }; // end is_numeric template struct is_reference_to_const : false_type {}; template struct is_reference_to_const : true_type {}; // make_unsigned follows namespace tt_detail { template struct make_unsigned_simple; template<> struct make_unsigned_simple { typedef unsigned char type; }; template<> struct make_unsigned_simple { typedef signed char type; }; template<> struct make_unsigned_simple { typedef unsigned char type; }; template<> struct make_unsigned_simple { typedef unsigned short type; }; template<> struct make_unsigned_simple { typedef unsigned short type; }; template<> struct make_unsigned_simple { typedef unsigned int type; }; template<> struct make_unsigned_simple { typedef unsigned int type; }; template<> struct make_unsigned_simple { typedef unsigned long int type; }; template<> struct make_unsigned_simple { typedef unsigned long int type; }; template<> struct make_unsigned_simple { typedef unsigned long long int type; }; template<> struct make_unsigned_simple { typedef unsigned long long int type; }; template struct make_unsigned_base { // remove cv typedef typename remove_cv::type remove_cv_t; // get the simple unsigned type typedef typename make_unsigned_simple::type unsigned_remove_cv_t; // add back const, volatile, both, or neither to the simple result typedef typename eval_if< is_const::value && is_volatile::value, // add cv back add_cv, // check const & volatile individually eval_if< is_const::value, // add c back add_const, eval_if< is_volatile::value, // add v back add_volatile, // original type was neither cv, return the simple unsigned result identity_ > > >::type type; }; } // end tt_detail template struct make_unsigned : tt_detail::make_unsigned_base {}; struct largest_available_float { #if defined(__CUDA_ARCH__) # if (__CUDA_ARCH__ < 130) typedef float type; # else typedef double type; # endif #else typedef double type; #endif }; // T1 wins if they are both the same size template struct larger_type : thrust::detail::eval_if< (sizeof(T2) > sizeof(T1)), thrust::detail::identity_, thrust::detail::identity_ > {}; namespace is_base_of_ns { typedef char yes; typedef struct { char two_chars[2]; } no; template struct host { operator Base*() const; operator Derived*(); }; // end host template struct impl { template static yes check(Derived *, T); static no check(Base*, int); static const bool value = sizeof(check(host(), int())) == sizeof(yes); }; // end impl } // end is_base_of_ns template struct is_base_of : integral_constant< bool, is_base_of_ns::impl::value > {}; template struct enable_if_base_of : enable_if< is_base_of::value, Result > {}; namespace is_assignable_ns { template class is_assignable { typedef char yes_type; typedef struct { char array[2]; } no_type; template static typename add_reference::type declval(); template struct helper { typedef void * type; }; template static yes_type test(typename helper() = declval())>::type); template static no_type test(...); public: static const bool value = sizeof(test(0)) == 1; }; // end is_assignable } // end is_assignable_ns template struct is_assignable : integral_constant< bool, is_assignable_ns::is_assignable::value > {}; template struct is_copy_assignable : is_assignable< typename add_reference::type, typename add_reference::type>::type > {}; } // end detail } // end thrust #include