Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// Defines type traits related to Charm++ types
6 :
7 : #pragma once
8 :
9 : #include <charm++.h>
10 : #include <pup.h>
11 :
12 : #include "Utilities/TypeTraits.hpp"
13 :
14 : /// \cond
15 : namespace Parallel::Algorithms {
16 : struct Array;
17 : struct Singleton;
18 : struct Group;
19 : struct Nodegroup;
20 : } // namespace Parallel::Algorithms
21 : /// \endcond
22 :
23 : namespace Parallel {
24 :
25 : /// \ingroup ParallelGroup
26 : /// Check if `T` is a Charm++ proxy for an array chare (the entire array)
27 : template <typename T>
28 1 : struct is_array_proxy : std::is_base_of<CProxy_ArrayElement, T>::type {};
29 :
30 : /// \ingroup ParallelGroup
31 : /// Check if `T` is a Charm++ proxy for an array chare element (from indexing
32 : /// into the array chare)
33 : template <typename T>
34 1 : struct is_array_element_proxy
35 : : std::is_base_of<CProxyElement_ArrayElement, T>::type {};
36 :
37 : /// \ingroup ParallelGroup
38 : /// Check if `T` is a Charm++ proxy for a group chare
39 : template <typename T>
40 1 : struct is_group_proxy : std::is_base_of<CProxy_IrrGroup, T>::type {};
41 :
42 : /// \ingroup ParallelGroup
43 : /// Check if `T` is a Charm++ proxy for a node group chare
44 : template <typename T>
45 1 : struct is_node_group_proxy : std::is_base_of<CProxy_NodeGroup, T>::type {};
46 :
47 : /// \ingroup ParallelGroup
48 : /// Check if `T` is a ParallelComponent for a Charm++ bound array
49 : template <typename T, typename = std::void_t<>>
50 1 : struct is_bound_array : std::false_type {};
51 :
52 : template <typename T>
53 : struct is_bound_array<T, std::void_t<typename T::bind_to>> : std::true_type {
54 : static_assert(Parallel::is_array_proxy<typename T::type>::value,
55 : "Can only bind an array chare");
56 : static_assert(Parallel::is_array_proxy<typename T::bind_to::type>::value,
57 : "Can only bind to an array chare");
58 : };
59 :
60 : /// \ingroup ParallelGroup
61 : /// @{
62 : /// Check if `T` is a SpECTRE Array
63 : template <typename T>
64 1 : struct is_array : std::is_same<Parallel::Algorithms::Array,
65 : typename T::chare_type::component_type> {};
66 : template <typename T>
67 0 : constexpr bool is_array_v = is_array<T>::value;
68 : /// @}
69 :
70 : /// \ingroup ParallelGroup
71 : /// @{
72 : /// Check if `T` is a SpECTRE Singleton
73 : template <typename T>
74 1 : struct is_singleton : std::is_same<Parallel::Algorithms::Singleton,
75 : typename T::chare_type::component_type> {};
76 : template <typename T>
77 0 : constexpr bool is_singleton_v = is_singleton<T>::value;
78 : /// @}
79 :
80 : /// \ingroup ParallelGroup
81 : /// @{
82 : /// Check if `T` is a SpECTRE Group
83 : template <typename T>
84 1 : struct is_group : std::is_same<Parallel::Algorithms::Group,
85 : typename T::chare_type::component_type> {};
86 : template <typename T>
87 0 : constexpr bool is_group_v = is_group<T>::value;
88 : /// @}
89 :
90 : /// \ingroup ParallelGroup
91 : /// @{
92 : /// Check if `T` is a SpECTRE Nodegroup
93 : template <typename T>
94 1 : struct is_nodegroup : std::is_same<Parallel::Algorithms::Nodegroup,
95 : typename T::chare_type::component_type> {};
96 : template <typename T>
97 0 : constexpr bool is_nodegroup_v = is_nodegroup<T>::value;
98 : /// @}
99 :
100 : /// @{
101 : /// \ingroup ParallelGroup
102 : /// Retrieve a parallel component from its proxy.
103 : template <typename Proxy>
104 1 : struct get_parallel_component_from_proxy;
105 :
106 : template <typename ParallelComponent, template <typename...> class Proxy,
107 : typename... Ts>
108 0 : struct get_parallel_component_from_proxy<Proxy<ParallelComponent, Ts...>> {
109 0 : using type = ParallelComponent;
110 : };
111 : /// @}
112 :
113 : /// @{
114 : /// \ingroup ParallelGroup
115 : /// \brief Check if `T` has a `pup` member function
116 : ///
117 : /// \details
118 : /// Inherits from std::true_type if the type `T` has a `pup(PUP::er&)` member
119 : /// function, otherwise inherits from std::false_type
120 : ///
121 : /// \usage
122 : /// For any type `T`,
123 : /// \code
124 : /// using result = tt::has_pup_member<T>;
125 : /// \endcode
126 : ///
127 : /// \metareturns
128 : /// std::bool_constant
129 : ///
130 : /// \semantics
131 : /// If the type `T` has a `pup(PUP::er&)` member function, then
132 : /// \code
133 : /// typename result::type = std::true_type;
134 : /// \endcode
135 : /// otherwise
136 : /// \code
137 : /// typename result::type = std::false_type;
138 : /// \endcode
139 : ///
140 : /// \example
141 : /// \snippet Parallel/Test_TypeTraits.cpp has_pup_member_example
142 : /// \see is_pupable
143 : /// \tparam T the type to check
144 : template <typename T, typename = std::void_t<>>
145 1 : struct has_pup_member : std::false_type {};
146 : /// \cond HIDDEN_SYMBOLS
147 : template <typename T>
148 : struct has_pup_member<
149 : T, std::void_t<decltype(std::declval<T>().pup(std::declval<PUP::er&>()))>>
150 : : std::true_type {};
151 : /// \endcond
152 : /// \see has_pup_member
153 : template <typename T>
154 1 : constexpr bool has_pup_member_v = has_pup_member<T>::value;
155 :
156 : /// \see has_pup_member
157 : template <typename T>
158 1 : using has_pup_member_t = typename has_pup_member<T>::type;
159 : /// @}
160 :
161 : /// @{
162 : /// \ingroup ParallelGroup
163 : /// \brief Check if type `T` has operator| defined for Charm++ serialization
164 : ///
165 : /// \details
166 : /// Inherits from std::true_type if the type `T` has operator| defined,
167 : /// otherwise inherits from std::false_type
168 : ///
169 : /// \usage
170 : /// For any type `T`,
171 : /// \code
172 : /// using result = tt::is_pupable<T>;
173 : /// \endcode
174 : ///
175 : /// \metareturns
176 : /// std::bool_constant
177 : ///
178 : /// \semantics
179 : /// If the type `T` has operator| defined, then
180 : /// \code
181 : /// typename result::type = std::true_type;
182 : /// \endcode
183 : /// otherwise
184 : /// \code
185 : /// typename result::type = std::false_type;
186 : /// \endcode
187 : ///
188 : /// \example
189 : /// \snippet Parallel/Test_TypeTraits.cpp is_pupable_example
190 : /// \see has_pup_member
191 : /// \tparam T the type to check
192 : template <typename T, typename U = void>
193 1 : struct is_pupable : std::false_type {};
194 : /// \cond HIDDEN_SYMBOLS
195 : template <typename T>
196 : struct is_pupable<
197 : T, std::void_t<decltype(std::declval<PUP::er&>() | std::declval<T&>())>>
198 : : std::true_type {};
199 : /// \endcond
200 : /// \see is_pupable
201 : template <typename T>
202 1 : constexpr bool is_pupable_v = is_pupable<T>::value;
203 :
204 : /// \see is_pupable
205 : template <typename T>
206 1 : using is_pupable_t = typename is_pupable<T>::type;
207 : /// @}
208 :
209 : } // namespace Parallel
|