Line data Source code
1 : //@HEADER
2 : // ************************************************************************
3 : //
4 : // Kokkos v. 4.0
5 : // Copyright (2022) National Technology & Engineering
6 : // Solutions of Sandia, LLC (NTESS).
7 : //
8 : // Under the terms of Contract DE-NA0003525 with NTESS,
9 : // the U.S. Government retains certain rights in this software.
10 : //
11 : // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 : // See https://kokkos.org/LICENSE for license information.
13 : // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 : //
15 : //@HEADER
16 :
17 : #ifndef KOKKOSTRAITS_HPP
18 : #define KOKKOSTRAITS_HPP
19 :
20 : #include <cstddef>
21 : #include <cstdint>
22 : #include <Kokkos_Macros.hpp>
23 : #include <impl/Kokkos_BitOps.hpp>
24 : #include <string>
25 : #include <type_traits>
26 :
27 : namespace Kokkos {
28 : namespace Impl {
29 :
30 : //----------------------------------------------------------------------------
31 : // Help with C++11 variadic argument packs
32 :
33 : template <unsigned I, typename... Pack>
34 : struct get_type {
35 : using type = void;
36 : };
37 :
38 : template <typename T, typename... Pack>
39 : struct get_type<0, T, Pack...> {
40 : using type = T;
41 : };
42 :
43 : template <unsigned I, typename T, typename... Pack>
44 : struct get_type<I, T, Pack...> {
45 : using type = typename get_type<I - 1, Pack...>::type;
46 : };
47 :
48 : template <typename T, typename... Pack>
49 : struct has_type {
50 : enum : bool { value = false };
51 : };
52 :
53 : template <typename T, typename S, typename... Pack>
54 : struct has_type<T, S, Pack...> {
55 : private:
56 : enum { self_value = std::is_same_v<T, S> };
57 :
58 : using next = has_type<T, Pack...>;
59 :
60 : static_assert(
61 : !(self_value && next::value),
62 : "Error: more than one member of the argument pack matches the type");
63 :
64 : public:
65 : enum : bool { value = self_value || next::value };
66 : };
67 :
68 : template <typename DefaultType, template <typename> class Condition,
69 : typename... Pack>
70 : struct has_condition {
71 : enum : bool { value = false };
72 : using type = DefaultType;
73 : };
74 :
75 : template <typename DefaultType, template <typename> class Condition, typename S,
76 : typename... Pack>
77 : struct has_condition<DefaultType, Condition, S, Pack...> {
78 : private:
79 : enum { self_value = Condition<S>::value };
80 :
81 : using next = has_condition<DefaultType, Condition, Pack...>;
82 :
83 : static_assert(
84 : !(self_value && next::value),
85 : "Error: more than one member of the argument pack satisfies condition");
86 :
87 : public:
88 : enum : bool { value = self_value || next::value };
89 :
90 : using type = std::conditional_t<self_value, S, typename next::type>;
91 : };
92 :
93 : template <class... Args>
94 : struct are_integral {
95 : enum : bool { value = true };
96 : };
97 :
98 : template <typename T, class... Args>
99 : struct are_integral<T, Args...> {
100 : enum {
101 : value =
102 : // Accept std::is_integral OR std::is_enum as an integral value
103 : // since a simple enum value is automically convertible to an
104 : // integral value.
105 : (std::is_integral_v<T> || std::is_enum_v<T>)&&are_integral<Args...>::value
106 : };
107 : };
108 :
109 : //----------------------------------------------------------------------------
110 : } // namespace Impl
111 : } // namespace Kokkos
112 :
113 : //----------------------------------------------------------------------------
114 : //----------------------------------------------------------------------------
115 : // Other traits
116 :
117 : namespace Kokkos {
118 : namespace Impl {
119 :
120 : //----------------------------------------------------------------------------
121 : // These 'constexpr'functions can be used as
122 : // both regular functions and meta-function.
123 :
124 : /**\brief There exists integral 'k' such that N = 2^k */
125 : KOKKOS_INLINE_FUNCTION
126 0 : constexpr bool is_integral_power_of_two(const size_t N) {
127 0 : return (0 < N) && (0 == (N & (N - 1)));
128 : }
129 :
130 : //----------------------------------------------------------------------------
131 :
132 : template <typename T, T v, bool NonZero = (v != T(0))>
133 : struct integral_nonzero_constant {
134 : // Declaration of 'static const' causes an unresolved linker symbol in debug
135 : // static const T value = v ;
136 : enum { value = T(v) };
137 : using value_type = T;
138 : using type = integral_nonzero_constant<T, v>;
139 : KOKKOS_INLINE_FUNCTION integral_nonzero_constant(const T&) {}
140 : };
141 :
142 : template <typename T, T zero>
143 : struct integral_nonzero_constant<T, zero, false> {
144 : const T value;
145 : using value_type = T;
146 : using type = integral_nonzero_constant<T, 0>;
147 : KOKKOS_INLINE_FUNCTION integral_nonzero_constant(const T& v) : value(v) {}
148 : };
149 :
150 : //----------------------------------------------------------------------------
151 :
152 : template <class T>
153 : struct make_all_extents_into_pointers {
154 : using type = T;
155 : };
156 :
157 : template <class T, unsigned N>
158 : struct make_all_extents_into_pointers<T[N]> {
159 : using type = typename make_all_extents_into_pointers<T>::type*;
160 : };
161 :
162 : template <class T>
163 : struct make_all_extents_into_pointers<T*> {
164 : using type = typename make_all_extents_into_pointers<T>::type*;
165 : };
166 :
167 : } // namespace Impl
168 : } // namespace Kokkos
169 :
170 : //----------------------------------------------------------------------------
171 : //----------------------------------------------------------------------------
172 :
173 : #endif /* #ifndef KOKKOSTRAITS_HPP */
|