/
ArborX_GeometryTraits.hpp
139 lines (111 loc) · 4.35 KB
/
ArborX_GeometryTraits.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/****************************************************************************
* 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 <Kokkos_DetectionIdiom.hpp>
#include <Kokkos_Macros.hpp>
namespace ArborX
{
namespace GeometryTraits
{
struct PointTag
{};
struct BoxTag
{};
struct SphereTag
{};
struct TriangleTag
{};
struct KDOPTag
{};
template <typename Geometry>
struct dimension
{
using not_specialized = void; // tag to detect existence of a specialization
};
template <typename Geometry>
inline constexpr int dimension_v = dimension<Geometry>::value;
struct not_specialized
{};
template <typename Geometry>
struct tag
{
using type = not_specialized;
};
template <typename Geometry>
struct coordinate_type
{
using type = not_specialized;
};
template <typename Geometry>
using DimensionNotSpecializedArchetypeAlias =
typename dimension<Geometry>::not_specialized;
template <typename Geometry>
using TagNotSpecializedArchetypeAlias = typename tag<Geometry>::not_specialized;
template <typename Geometry>
using CoordinateNotSpecializedArchetypeAlias =
typename coordinate_type<Geometry>::not_specialized;
template <typename Geometry>
using DimensionArchetypeAlias = decltype(dimension_v<Geometry>);
template <typename Geometry>
struct is_point : std::is_same<typename tag<Geometry>::type, PointTag>
{};
template <typename Geometry>
struct is_box : std::is_same<typename tag<Geometry>::type, BoxTag>
{};
template <typename Geometry>
struct is_sphere : std::is_same<typename tag<Geometry>::type, SphereTag>
{};
template <typename Geometry>
struct is_triangle : std::is_same<typename tag<Geometry>::type, TriangleTag>
{};
template <typename Geometry>
KOKKOS_FUNCTION constexpr void check_valid_geometry_traits(Geometry const &)
{
static_assert(
!Kokkos::is_detected<DimensionNotSpecializedArchetypeAlias, Geometry>{},
"Must specialize GeometryTraits::dimension<Geometry>");
static_assert(
!Kokkos::is_detected<TagNotSpecializedArchetypeAlias, Geometry>{},
"Must specialize GeometryTraits::tag<Geometry>");
static_assert(
!Kokkos::is_detected<CoordinateNotSpecializedArchetypeAlias, Geometry>{},
"Must specialize GeometryTraits::coordinate_type<Geometry>");
static_assert(
Kokkos::is_detected<DimensionArchetypeAlias, Geometry>{},
"GeometryTraits::dimension<Geometry> must define 'value' member type");
static_assert(
std::is_integral<
Kokkos::detected_t<DimensionArchetypeAlias, Geometry>>{} &&
GeometryTraits::dimension_v<Geometry> > 0,
"GeometryTraits::dimension<Geometry>::value must be a positive integral");
static_assert(
!std::is_same<typename tag<Geometry>::type, not_specialized>::value,
"GeometryTraits::tag<Geometry> must define 'type' member type");
using Tag = typename tag<Geometry>::type;
static_assert(std::is_same<Tag, PointTag>{} || std::is_same<Tag, BoxTag>{} ||
std::is_same<Tag, SphereTag>{} ||
std::is_same<Tag, TriangleTag>{} ||
std::is_same<Tag, KDOPTag>{},
"GeometryTraits::tag<Geometry>::type must be PointTag, BoxTag, "
"SphereTag, TriangleTag or KDOPTag");
static_assert(!std::is_same<typename coordinate_type<Geometry>::type,
not_specialized>::value,
"GeometryTraits::coordinate_type<Geometry> must define 'type' "
"member type");
using Coordinate = typename coordinate_type<Geometry>::type;
static_assert(
std::is_arithmetic_v<Coordinate>,
"GeometryTraits::coordinate_type<Geometry> must be an arithmetic type");
}
} // namespace GeometryTraits
} // namespace ArborX
#endif