KaMPIng 0.1.1
Flexible and (near) zero-overhead C++ bindings for MPI
Loading...
Searching...
No Matches
traits.hpp
1// This file is part of KaMPIng.
2//
3// Copyright 2024 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#pragma once
15#include <array> // defines std::tuple_size for std::array
16#include <tuple> // defines std::tuple_size for tuples
17#include <type_traits>
18#include <utility> // defines std::tuple_size for std::pair
19
20namespace kamping {
21
22/// @brief A type trait that checks if a type \p T is a range, i.e., it has `std::begin` and `std::end` defined.
23template <typename T>
24struct is_range {
25 template <typename S>
26 /// @brief Only enable this overload if `std::begin` and `std::end` are defined for \p S.
27 static auto test(int) -> decltype(std::begin(std::declval<S>()), std::end(std::declval<S>()), std::true_type{});
28 template <typename>
29 /// @brief Fallback overload.
30 static auto test(...) -> std::false_type;
31 static constexpr bool value = decltype(test<T>(0))::value; ///< The value of the trait.
32};
33
34/// @brief A type trait that checks if a type \p T is a range, i.e., it has `std::begin` and `std::end` defined.
35template <typename T>
36constexpr bool is_range_v = is_range<T>::value;
37
38/// @brief A type trait that checks if a type \p T is a contiguous and sized range, i.e., it is a range and has
39/// `std::size` and `std::data` defined.
40template <typename T>
42 /// @brief Only enable this overload if `std::size` and `std::data` are defined for \p S.
43 template <typename S>
44 static auto test(int) -> decltype(std::size(std::declval<S>()), std::data(std::declval<S>()), std::true_type{});
45 /// @brief Fallback overload.
46 template <typename>
47 static auto test(...) -> std::false_type;
48 static constexpr bool value = decltype(test<T>(0))::value; ///< The value of the trait.
49};
50
51/// @brief A type trait that checks if a type \p T is a contiguous and sized range, i.e., it is a range and has
52/// `std::size` and `std::data` defined.
53template <typename T>
54constexpr bool is_contiguous_sized_range_v = is_contiguous_sized_range<T>::value;
55
56/// @brief A type trait that checks if a type \p T is a pair-like type, i.e., it may be destructured using `std::get<0>`
57/// and `std::get<1>` and has a size of 2.
58template <typename T>
60 /// @brief Only enable this overload if `std::tuple_size` is defined for \p S.
61 template <typename S>
62 static auto test(int) -> decltype(std::integral_constant<size_t, std::tuple_size<S>::value>{});
63 template <typename>
64 /// @brief Fallback overload, returns size 0.
65 static auto test(...) -> std::integral_constant<size_t, 0>;
66 static constexpr bool value = decltype(test<T>(0))::value == 2; ///< The value of the trait.
67};
68
69/// @brief A type trait that checks if a type \p T is a pair-like type, i.e., it may be destructured using `std::get<0>`
70/// and `std::get<1>` and has a size of 2.
71template <typename T>
72constexpr bool is_pair_like_v = is_pair_like<T>::value;
73
74/// @brief A type trait that checks if a type T a pair-like type using \c is_pair_like, the first element is
75/// convertible to int, and the second element satisfies \c is_contiguous_sized_range_v.
76template <typename T>
77constexpr bool is_destination_buffer_pair_v = [] {
78 if constexpr (is_pair_like_v<T>) {
79 return is_contiguous_sized_range_v<std::remove_const_t<std::tuple_element_t<
80 1,
81 T>>> && std::is_convertible_v<std::remove_const_t<std::tuple_element_t<0, T>>, int>;
82 } else {
83 return false;
84 }
85}();
86
87/// @brief A type trait that checks if a type \p T is a sparse send buffer, i.e., it is a range of pair-like which are
88/// (dst, message) pairs. (see \c is_destination_buffer_pair_v)
89template <typename T>
90constexpr bool is_sparse_send_buffer_v = [] {
91 if constexpr (is_range_v<T>) {
92 return is_destination_buffer_pair_v<std::remove_const_t<typename T::value_type>>;
93 } else {
94 return false;
95 }
96}();
97
98/// @brief A type traits that checks if a type is a nested send buffer, i.e., it is a range of contiguous ranges (see
99/// \c is_contiguous_sized_range_v).
100template <typename T>
101constexpr bool is_nested_send_buffer_v = [] {
102 if constexpr (is_range_v<T>) {
103 return is_contiguous_sized_range_v<std::remove_const_t<typename T::value_type>>;
104 } else {
105 return false;
106 }
107}();
108} // namespace kamping
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
A type trait that checks if a type T is a contiguous and sized range, i.e., it is a range and has std...
Definition traits.hpp:41
static constexpr bool value
The value of the trait.
Definition traits.hpp:48
static auto test(...) -> std::false_type
Fallback overload.
static auto test(int) -> decltype(std::size(std::declval< S >()), std::data(std::declval< S >()), std::true_type{})
Only enable this overload if std::size and std::data are defined for S.
A type trait that checks if a type T is a pair-like type, i.e., it may be destructured using std::get...
Definition traits.hpp:59
static auto test(...) -> std::integral_constant< size_t, 0 >
Fallback overload, returns size 0.
static constexpr bool value
The value of the trait.
Definition traits.hpp:66
static auto test(int) -> decltype(std::integral_constant< size_t, std::tuple_size< S >::value >{})
Only enable this overload if std::tuple_size is defined for S.
A type trait that checks if a type T is a range, i.e., it has std::begin and std::end defined.
Definition traits.hpp:24
static auto test(int) -> decltype(std::begin(std::declval< S >()), std::end(std::declval< S >()), std::true_type{})
Only enable this overload if std::begin and std::end are defined for S.
static auto test(...) -> std::false_type
Fallback overload.
static constexpr bool value
The value of the trait.
Definition traits.hpp:31