/* * Copyright 2008-2013 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 generic/type_traits.h * \brief Introspection for free functions defined in generic. */ #pragma once #include #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header THRUST_NAMESPACE_BEGIN // forward declaration of any_system_tag for any_conversion below struct any_system_tag; namespace system { namespace detail { // we must define these traits outside of generic's namespace namespace generic_type_traits_ns { typedef char yes; typedef char (&no)[2]; struct any_conversion { template any_conversion(const T&); // add this extra constructor to disambiguate conversion from any_system_tag any_conversion(const any_system_tag&); }; namespace select_system_exists_ns { no select_system(const any_conversion&); no select_system(const any_conversion&, const any_conversion&); no select_system(const any_conversion&, const any_conversion&, const any_conversion&); no select_system(const any_conversion&, const any_conversion&, const any_conversion&, const any_conversion&); no select_system( const any_conversion&, const any_conversion&, const any_conversion&, const any_conversion&, const any_conversion&); no select_system(const any_conversion&, const any_conversion&, const any_conversion&, const any_conversion&, const any_conversion&, const any_conversion&); template yes check(const T&); no check(no); template struct select_system1_exists { static Tag& tag; static const bool value = sizeof(check(select_system(tag))) == sizeof(yes); }; template struct select_system2_exists { static Tag1& tag1; static Tag2& tag2; static const bool value = sizeof(check(select_system(tag1, tag2))) == sizeof(yes); }; template struct select_system3_exists { static Tag1& tag1; static Tag2& tag2; static Tag3& tag3; static const bool value = sizeof(check(select_system(tag1, tag2, tag3))) == sizeof(yes); }; template struct select_system4_exists { static Tag1& tag1; static Tag2& tag2; static Tag3& tag3; static Tag4& tag4; static const bool value = sizeof(check(select_system(tag1, tag2, tag3, tag4))) == sizeof(yes); }; template struct select_system5_exists { static Tag1& tag1; static Tag2& tag2; static Tag3& tag3; static Tag4& tag4; static Tag5& tag5; static const bool value = sizeof(check(select_system(tag1, tag2, tag3, tag4, tag5))) == sizeof(yes); }; template struct select_system6_exists { static Tag1& tag1; static Tag2& tag2; static Tag3& tag3; static Tag4& tag4; static Tag5& tag5; static Tag6& tag6; static const bool value = sizeof(check(select_system(tag1, tag2, tag3, tag4, tag5, tag6))) == sizeof(yes); }; } // namespace select_system_exists_ns } // namespace generic_type_traits_ns namespace generic { template struct select_system1_exists : generic_type_traits_ns::select_system_exists_ns::select_system1_exists {}; template struct select_system2_exists : generic_type_traits_ns::select_system_exists_ns::select_system2_exists {}; template struct select_system3_exists : generic_type_traits_ns::select_system_exists_ns::select_system3_exists {}; template struct select_system4_exists : generic_type_traits_ns::select_system_exists_ns::select_system4_exists {}; template struct select_system5_exists : generic_type_traits_ns::select_system_exists_ns::select_system5_exists {}; template struct select_system6_exists : generic_type_traits_ns::select_system_exists_ns::select_system6_exists {}; } // namespace generic } // namespace detail } // namespace system THRUST_NAMESPACE_END