/**************************************************************************** * Copyright (c) 2017-2022 by the ArborX authors * * All rights reserved. * * * * This file is part of the ArborX library. ArborX is * * distributed under a BSD 3-clause license. For the licensing terms see * * the LICENSE file in the top-level directory. * * * * SPDX-License-Identifier: BSD-3-Clause * ****************************************************************************/ #ifndef ARBORX_GEOMETRY_TRAITS_HPP #define ARBORX_GEOMETRY_TRAITS_HPP #include #include namespace ArborX { namespace GeometryTraits { template struct dimension { using not_specialized = void; // tag to detect existence of a specialization }; template inline constexpr int dimension_v = dimension::value; struct not_specialized {}; template struct tag { using type = not_specialized; }; template using tag_t = typename tag::type; template struct coordinate_type { using type = not_specialized; }; template using coordinate_type_t = typename coordinate_type::type; // clang-format off #define DEFINE_GEOMETRY(name, name_tag) \ struct name_tag{}; \ template \ struct is_##name : std::is_same, name_tag>{}; \ template \ inline constexpr bool is_##name##_v = is_##name::value // clang-format on DEFINE_GEOMETRY(point, PointTag); DEFINE_GEOMETRY(box, BoxTag); DEFINE_GEOMETRY(sphere, SphereTag); DEFINE_GEOMETRY(triangle, TriangleTag); DEFINE_GEOMETRY(kdop, KDOPTag); DEFINE_GEOMETRY(tetrahedron, TetrahedronTag); DEFINE_GEOMETRY(ray, RayTag); #undef DEFINE_GEOMETRY template inline constexpr bool is_valid_geometry = (is_point_v || is_box_v || is_sphere_v || is_kdop_v || is_triangle_v || is_tetrahedron_v || is_ray_v); template using DimensionNotSpecializedArchetypeAlias = typename dimension::not_specialized; template using TagNotSpecializedArchetypeAlias = typename tag::not_specialized; template using CoordinateNotSpecializedArchetypeAlias = typename coordinate_type::not_specialized; template using DimensionArchetypeAlias = decltype(dimension_v); template void check_valid_geometry_traits(Geometry const &) { static_assert( !Kokkos::is_detected{}, "Must specialize GeometryTraits::dimension"); static_assert( !Kokkos::is_detected{}, "Must specialize GeometryTraits::tag"); static_assert( !Kokkos::is_detected{}, "Must specialize GeometryTraits::coordinate_type"); static_assert( Kokkos::is_detected{}, "GeometryTraits::dimension must define 'value' member type"); static_assert( std::is_integral< Kokkos::detected_t>{} && GeometryTraits::dimension_v > 0, "GeometryTraits::dimension::value must be a positive integral"); static_assert(!std::is_same_v, not_specialized>, "GeometryTraits::tag must define 'type' member type"); static_assert(is_valid_geometry, "GeometryTraits::tag::type must be PointTag, BoxTag, " "SphereTag, TriangleTag, KDOPTag, or RayTag"); static_assert(!std::is_same_v, not_specialized>, "GeometryTraits::coordinate_type must define 'type' " "member type"); using Coordinate = coordinate_type_t; static_assert( std::is_arithmetic_v, "GeometryTraits::coordinate_type must be an arithmetic type"); } } // namespace GeometryTraits } // namespace ArborX #endif