KaMPIng 0.1.1
Flexible and (near) zero-overhead C++ bindings for MPI
Loading...
Searching...
No Matches
named_parameter_selection.hpp
Go to the documentation of this file.
1// This file is part of KaMPIng.
2//
3// Copyright 2021 The KaMPIng Authors
4//
5// KaMPIng is free software : you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
7// version. KaMPIng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
9// for more details.
10//
11// You should have received a copy of the GNU Lesser General Public License along with KaMPIng. If not, see
12// <https://www.gnu.org/licenses/>.:
13
14/// @file
15/// @brief Template magic to implement named parameters in cpp
16
17#pragma once
18
19#include <cstddef>
20#include <limits>
21#include <tuple>
22
24
25namespace kamping::internal {
26/// @addtogroup kamping_utility
27/// @{
28
29/// @brief Trait struct used to determine the underlying type and value of the parameter type of an object with a
30/// parameter type. (This is a building block to enable plugins to have their own named parameters).
31/// @tparam Arg Type for which the parameter type unwrapping is done.
32template <typename Arg>
34 using type = std::remove_cv_t<std::remove_reference_t<decltype(std::remove_reference_t<Arg>::parameter_type
35 )>>; ///< Type of the underlying parameter type.
36 static constexpr type value =
37 std::remove_reference_t<Arg>::parameter_type; ///< Value of the underlying parameter type.
38};
39
40/// @brief Trait struct used to determine the underlying type and value of the parameter type of an
41/// std::integral_constant wrapping a parameter type. (This is a building block to enable plugins to have their own
42/// named parameters).
43///
44/// @tparam T Type of the parameter type.
45/// @tparam v Value of the parameter type.
46template <typename T, T v>
48 using type = T; ///< Type of the underlying parameter type.
49 static constexpr type value = v; ///< Value of the underlying parameter type.
50};
51
52/// @brief Trait for the underlying type of the parameter type of \tparam Arg.
53template <typename Arg>
55
56/// @brief Trait for the underlying value of the parameter type of \tparam Arg.
57template <typename Arg>
59
60/// @brief Check whether two objects have the same parameter type.
61///
62/// @tparam T First type.
63/// @tparam U Second type.
64/// @return True iff T's and U's underlying parameter type are equal.
65template <typename T, typename U>
66constexpr bool has_same_parameter_type() {
67 if constexpr (std::is_same_v<parameter_type_t<T>, parameter_type_t<U>>) {
69 } else {
70 return false;
71 }
72}
73
74/// @brief Base case if there are no parameters: always returns max index indicating that the parameter was not found.
75/// @tparam ParameterTypeConstant Type and value of the parameter type (required for parameter selection within
76/// plugins).
77/// @tparam Index Index of current argument to evaluate (ignored).
78/// @return \c std::numeric_limits<size_t>::max().
79template <typename ParameterTypeConstant, size_t Index>
80constexpr size_t find_pos() {
81 return std::numeric_limits<size_t>::max();
82}
83
84/// @brief Returns the Index parameter if the parameter type of Arg matches the requested parameter type. If not, this
85/// fails to compile.
86///
87/// This is the base case of the recursion.
88///
89/// @tparam ParameterTypeConstant Type and value of the parameter type (required for parameter selection within
90/// plugins).
91/// @tparam Index Index of current argument to evaluate.
92/// @tparam Arg Argument to evaluate.
93/// @return The index
94/// @return \c std::numeric_limits<size_t>::max() if not found
95template <typename ParameterTypeConstant, size_t Index, typename Arg>
96constexpr size_t find_pos() {
98 // when we do not find the parameter type here, it is not given
99 // a we fail to compile with a useful message
100 return found_arg ? Index : std::numeric_limits<size_t>::max();
101}
102
103/// @brief Returns position of first argument in Args with Trait trait.
104///
105/// @tparam ParameterTypeConstant Type and value of the parameter type (required for parameter selection within
106/// plugins).
107/// @tparam Index Index of current argument to evaluate.
108/// @tparam Arg Argument to evaluate.
109/// @tparam Arg2 The next argument.
110/// @tparam Args All remaining arguments.
111/// @return Position of first argument with matched trait.
112/// @return \c std::numeric_limits<size_t>::max() if not found
113template <typename ParameterTypeConstant, size_t Index, typename Arg, typename Arg2, typename... Args>
114constexpr size_t find_pos() {
116 return Index;
117 } else {
118 // We need to unpack the next two arguments, so we can unambiguously check for the case
119 // of a single remaining argument.
120 return find_pos<ParameterTypeConstant, Index + 1, Arg2, Args...>();
121 }
122}
123
124/// @brief Returns parameter with requested parameter type.
125///
126/// @tparam ParameterTypeConstant Type and value of the parameter type for which a parameter should be found(required
127/// for parameter selection within plugins).
128/// @tparam Args All parameter types to be searched for type `ParameterTypeConstant::value`.
129/// @param args All parameters from which a parameter with the correct type is selected.
130/// @returns The first parameter whose type has the requested parameter type.
131template <typename ParameterTypeConstant, typename... Args>
133 constexpr size_t selected_index = find_pos<ParameterTypeConstant, 0, Args...>();
134 static_assert(selected_index < sizeof...(args), "Could not find the requested parameter type.");
135 return std::get<selected_index>(std::forward_as_tuple(args...));
136}
137
138/// @brief "Specialization" for internal::ParameterType.
139template <ParameterType parameter_type, typename... Args>
142}
143
144/// @brief Returns parameter with requested parameter type.
145///
146/// @tparam parameter_type The parameter type with which a parameter should be found.
147/// @tparam Args All parameter types to be searched for type `parameter_type`.
148/// @param tuple std::tuple with containing all parameters from which a parameter with the correct type is selected.
149/// @returns The first parameter whose type has the requested parameter type.
150template <ParameterType parameter_type, typename... Args>
151auto& select_parameter_type_in_tuple(std::tuple<Args...>& tuple) {
153 static_assert(selected_index < sizeof...(Args), "Could not find the requested parameter type.");
154 return std::get<selected_index>(tuple);
155}
156
157/// @brief Returns parameter with requested parameter type.
158///
159/// @tparam parameter_type The parameter type with which a parameter should be found.
160/// @tparam Args All parameter types to be searched for type `parameter_type`.
161/// @param tuple std::tuple with containing all parameters from which a parameter with the correct type is selected.
162/// @returns The first parameter whose type has the requested parameter type.
163template <ParameterType parameter_type, typename... Args>
164auto const& select_parameter_type_in_tuple(std::tuple<Args...> const& tuple) {
166 static_assert(selected_index < sizeof...(Args), "Could not find the requested parameter type.");
167 return std::get<selected_index>(tuple);
168}
169
170/// @brief Type of Buffer with requested \tparam parameter_type
171///
172/// @tparam TParameterType Type of the parameter type (required for parameter selection within plugins).
173/// @tparam parameter_type The parameter type with which a parameter should be found.
174/// @tparam Args All parameter types to be searched for type `parameter_type`.
175template <ParameterType parameter_type, typename... Args>
177 tuple_element_t<find_pos<std::integral_constant<ParameterType, parameter_type>, 0, Args...>(), std::tuple<Args...>>;
178
179/// @brief Checks if parameter with requested parameter type exists.
180///
181/// @tparam ParameterTypeConstant Type and value of the parameter type to be searched(required
182/// for parameter selection within plugins).
183/// @tparam Args All parameter types to be searched.
184/// @return \c true iff. `Args` contains a parameter of type `ParameterTypeConstant::value`.
185template <typename ParameterTypeConstant, typename... Args>
186constexpr bool has_parameter_type() {
187 return find_pos<ParameterTypeConstant, 0, Args...>() < sizeof...(Args);
188}
189
190/// @brief Checks if parameter with requested parameter type exists.
191///
192/// @tparam parameter_type The parameter type with which a parameter should be found.
193/// @tparam Args All parameter types to be searched.
194/// @return \c true iff. `Args` contains a parameter of type `parameter_type`.
195template <ParameterType parameter_type, typename... Args>
196constexpr bool has_parameter_type() {
198}
199
200/// @brief Helper struct needed to retrieve the types stored in a std::tuple for the has_parameter_type check.
201///
202template <typename>
204
205/// @brief Checks if parameter with requested parameter type exists. Wrapper using the functionality from \ref
206/// kamping::internal::has_parameter_type() disassembling a std::tuple passed as parameter.
207///
208/// @tparam parameter_type The parameter type with which a parameter should be found.
209/// @tparam Args All parameter types to be searched.
210/// @return \c true iff. `Args` contains a parameter of type `parameter_type`.
211template <ParameterType parameter_type, typename... Args>
212constexpr bool has_parameter_type_in_tuple_impl(has_parameter_helper<std::tuple<Args...>> /*args*/) {
213 return has_parameter_type<parameter_type, Args...>();
214}
215
216/// @brief Checks if parameter with requested parameter type exists.
217///
218/// @tparam parameter_type The parameter type with which a parameter should be found.
219/// @tparam Tuple Intended: std::tuple<Args...> containing all types to be searched.
220/// @return \c true iff. `Args` contains a parameter of type `parameter_type`.
221template <ParameterType parameter_type, typename Tuple>
225
226/// @brief Checks if parameter with requested parameter type exists, if not constructs a default value.
227///
228///
229/// @tparam ParameterTypeConstant Type and value of the parameter type for which a parameter should be found(required
230/// for parameter selection within plugins).
231/// @tparam Args All parameter types to be searched for parameter type `ParameterTypeConstant::value`.
232/// @tparam DefaultParameterType The type of the default parameter to be constructed.
233/// @tparam DefaultArguments The types of parameters passed to the constructor \c DefaultParameterType.
234/// @param default_arguments Tuple of the arguments passed to the constructor of \c DefaultParameterType.
235/// @param args All parameters from which a parameter with the correct type is selected.
236/// @return The first parameter whose type has the requested parameter type or the constructed default parameter if
237/// none is found.
238template <typename ParameterTypeConstant, typename DefaultParameterType, typename... DefaultArguments, typename... Args>
239decltype(auto) select_parameter_type_or_default(std::tuple<DefaultArguments...> default_arguments, Args&... args) {
240 static_assert(
241 std::is_constructible_v<DefaultParameterType, DefaultArguments...>,
242 "The default parameter cannot be constructed from the provided arguments"
243 );
244 if constexpr (has_parameter_type<ParameterTypeConstant, Args...>()) {
245 constexpr size_t selected_index = find_pos<ParameterTypeConstant, 0, Args...>();
246 return std::get<selected_index>(std::forward_as_tuple(args...));
247 } else {
248 static_assert(!std::is_reference_v<DefaultParameterType>, "DefaultParameterType must not be a reference.");
249 return std::make_from_tuple<DefaultParameterType>(std::move(default_arguments));
250 }
251}
252
253/// @brief "Specialization" for internal::ParameterType.
254template <ParameterType parameter_type, typename DefaultParameterType, typename... DefaultArguments, typename... Args>
255decltype(auto) select_parameter_type_or_default(std::tuple<DefaultArguments...> default_arguments, Args&... args) {
257 std::integral_constant<internal::ParameterType, parameter_type>,
259}
260
261/// @}
262} // namespace kamping::internal
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
ParameterType
Each input parameter to one of the MPI calls wrapped by KaMPIng needs to has one of the following tag...
Definition named_parameter_types.hpp:33
constexpr parameter_type_t< Arg > parameter_type_v
Trait for the underlying value of the parameter type of.
Definition named_parameter_selection.hpp:58
constexpr bool has_parameter_type_in_tuple_impl(has_parameter_helper< std::tuple< Args... > >)
Checks if parameter with requested parameter type exists. Wrapper using the functionality from kampin...
Definition named_parameter_selection.hpp:212
constexpr bool has_same_parameter_type()
Check whether two objects have the same parameter type.
Definition named_parameter_selection.hpp:66
decltype(auto) select_parameter_type_or_default(std::tuple< DefaultArguments... > default_arguments, Args &... args)
Checks if parameter with requested parameter type exists, if not constructs a default value.
Definition named_parameter_selection.hpp:239
constexpr bool has_parameter_type_in_tuple()
Checks if parameter with requested parameter type exists.
Definition named_parameter_selection.hpp:222
std:: tuple_element_t< find_pos< std::integral_constant< ParameterType, parameter_type >, 0, Args... >(), std::tuple< Args... > > buffer_type_with_requested_parameter_type
Type of Buffer with requested.
Definition named_parameter_selection.hpp:176
constexpr bool has_parameter_type()
Checks if parameter with requested parameter type exists.
Definition named_parameter_selection.hpp:186
typename ParameterTypeUnwrapping< Arg >::type parameter_type_t
Trait for the underlying type of the parameter type of.
Definition named_parameter_selection.hpp:54
constexpr size_t find_pos()
Base case if there are no parameters: always returns max index indicating that the parameter was not ...
Definition named_parameter_selection.hpp:80
auto & select_parameter_type_in_tuple(std::tuple< Args... > &tuple)
Returns parameter with requested parameter type.
Definition named_parameter_selection.hpp:151
auto & select_parameter_type(Args &... args)
Returns parameter with requested parameter type.
Definition named_parameter_selection.hpp:132
File containing the parameter types used by the KaMPIng library.
Internal namespace marking the code that is not user-facing.
Definition collectives_helpers.hpp:20
STL namespace.
T type
Type of the underlying parameter type.
Definition named_parameter_selection.hpp:48
Trait struct used to determine the underlying type and value of the parameter type of an object with ...
Definition named_parameter_selection.hpp:33
std::remove_cv_t< std::remove_reference_t< decltype(std::remove_reference_t< Arg >::parameter_type)> > type
Type of the underlying parameter type.
Definition named_parameter_selection.hpp:34
static constexpr type value
Value of the underlying parameter type.
Definition named_parameter_selection.hpp:36
Helper struct needed to retrieve the types stored in a std::tuple for the has_parameter_type check.
Definition named_parameter_selection.hpp:203