/* * 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 // inspired by Roman Perepelitsa's presentation from comp.lang.c++.moderated // based on the implementation here: http://www.rsdn.ru/forum/cpp/2759773.1.aspx namespace thrust { namespace detail { namespace is_call_possible_detail { template class void_exp_result {}; template U const& operator,(U const&, void_exp_result); template U& operator,(U&, void_exp_result); template struct clone_constness { typedef dest_type type; }; template struct clone_constness { typedef const dest_type type; }; } // end is_call_possible_detail } // end detail } // end thrust #define __THRUST_DEFINE_IS_CALL_POSSIBLE(trait_name, member_function_name) \ __THRUST_DEFINE_HAS_MEMBER_FUNCTION(trait_name##_has_member, member_function_name) \ \ template \ struct trait_name \ { \ private: \ struct yes {}; \ struct no { yes m[2]; }; \ struct derived : public T \ { \ using T::member_function_name; \ no member_function_name(...) const; \ }; \ \ typedef typename thrust::detail::is_call_possible_detail::clone_constness::type derived_type; \ \ template \ struct return_value_check \ { \ static yes deduce(Result); \ static no deduce(...); \ static no deduce(no); \ static no deduce(thrust::detail::is_call_possible_detail::void_exp_result); \ }; \ \ template \ struct return_value_check \ { \ static yes deduce(...); \ static no deduce(no); \ }; \ \ template \ struct impl \ { \ static const bool value = false; \ }; \ \ template \ struct impl \ { \ static typename add_reference::type test_me; \ static typename add_reference::type arg; \ \ static const bool value = \ sizeof( \ return_value_check::deduce( \ (test_me.member_function_name(arg), thrust::detail::is_call_possible_detail::void_exp_result()) \ ) \ ) == sizeof(yes); \ }; \ \ template \ struct impl \ { \ static typename add_reference::type test_me; \ static typename add_reference::type arg1; \ static typename add_reference::type arg2; \ \ static const bool value = \ sizeof( \ return_value_check::deduce( \ (test_me.member_function_name(arg1,arg2), thrust::detail::is_call_possible_detail::void_exp_result()) \ ) \ ) == sizeof(yes); \ }; \ \ template \ struct impl \ { \ static typename add_reference::type test_me; \ static typename add_reference::type arg1; \ static typename add_reference::type arg2; \ static typename add_reference::type arg3; \ \ static const bool value = \ sizeof( \ return_value_check::deduce( \ (test_me.member_function_name(arg1,arg2,arg3), thrust::detail::is_call_possible_detail::void_exp_result()) \ ) \ ) == sizeof(yes); \ }; \ \ template \ struct impl \ { \ static typename add_reference::type test_me; \ static typename add_reference::type arg1; \ static typename add_reference::type arg2; \ static typename add_reference::type arg3; \ static typename add_reference::type arg4; \ \ static const bool value = \ sizeof( \ return_value_check::deduce( \ (test_me.member_function_name(arg1,arg2,arg3,arg4), thrust::detail::is_call_possible_detail::void_exp_result()) \ ) \ ) == sizeof(yes); \ }; \ \ public: \ static const bool value = impl::value, Signature>::value; \ typedef thrust::detail::integral_constant type; \ };