/* * 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. */ #pragma once #include #include //#include // for intmax_t (not provided on MSVS 2005) namespace thrust { namespace detail { // XXX good enough for the platforms we care about typedef long long intmax_t; template struct is_signed : integral_constant::is_signed> {}; // end is_signed template struct num_digits : eval_if< std::numeric_limits::is_specialized, integral_constant< int, std::numeric_limits::digits >, integral_constant< int, sizeof(T) * std::numeric_limits::digits - (is_signed::value ? 1 : 0) > >::type {}; // end num_digits template struct integer_difference //: eval_if< // sizeof(Integer) >= sizeof(intmax_t), // eval_if< // is_signed::value, // identity_, // identity_ // >, // eval_if< // sizeof(Integer) < sizeof(std::ptrdiff_t), // identity_, // identity_ // > // > { private: // XXX workaround a pedantic warning in old versions of g++ // which complains about &&ing with a constant value template struct and_ { static const bool value = false; }; template struct and_ { static const bool value = y; }; public: typedef typename eval_if< and_< std::numeric_limits::is_signed, // digits is the number of no-sign bits (!std::numeric_limits::is_bounded || (int(std::numeric_limits::digits) + 1 >= num_digits::value)) >::value, identity_, eval_if< int(std::numeric_limits::digits) + 1 < num_digits::value, identity_, eval_if< int(std::numeric_limits::digits) + 1 < num_digits::value, identity_, identity_ > > >::type type; }; // end integer_difference template struct numeric_difference : eval_if< is_integral::value, integer_difference, identity_ > {}; // end numeric_difference template __host__ __device__ typename numeric_difference::type numeric_distance(Number x, Number y) { typedef typename numeric_difference::type difference_type; return difference_type(y) - difference_type(x); } // end numeric_distance } // end detail } // end thrust