1 #pragma once
2
3 #include <cstddef>
4 #include <optional>
5 #include <tuple>
6 #include <type_traits>
7
8 namespace sdbusplus
9 {
10
11 namespace utility
12 {
13
14 /** @brief Retrieve the first type from a parameter pack
15 *
16 * @tparam Types - the parameter pack
17 */
18 template <typename... Types>
19 using first_type_t = std::tuple_element_t<0, std::tuple<Types...>>;
20
21 /** @brief Convert T[N] to T* if is_same<Tbase,T>
22 *
23 * @tparam Tbase - The base type expected.
24 * @tparam T - The type to convert.
25 */
26 template <typename Tbase, typename T>
27 using array_to_ptr_t = typename std::conditional_t<
28 std::is_array_v<T>,
29 std::conditional_t<std::is_same_v<Tbase, std::remove_extent_t<T>>,
30 std::add_pointer_t<std::remove_extent_t<T>>, T>,
31 T>;
32
33 template <std::size_t N, typename FirstArg, typename... Rest>
34 struct strip_first_n_args;
35
36 template <std::size_t N, typename FirstArg, typename... Rest>
37 struct strip_first_n_args<N, std::tuple<FirstArg, Rest...>> :
38 strip_first_n_args<N - 1, std::tuple<Rest...>>
39 {};
40
41 template <typename FirstArg, typename... Rest>
42 struct strip_first_n_args<0, std::tuple<FirstArg, Rest...>>
43 {
44 using type = std::tuple<FirstArg, Rest...>;
45 };
46 template <std::size_t N>
47 struct strip_first_n_args<N, std::tuple<>>
48 {
49 using type = std::tuple<>;
50 };
51
52 template <std::size_t N, typename... Args>
53 using strip_first_n_args_t = typename strip_first_n_args<N, Args...>::type;
54
55 // Small helper class for stripping off the error code from the function
56 // argument definitions so unpack can be called appropriately
57 template <typename T>
58 using strip_first_arg = strip_first_n_args<1, T>;
59
60 template <typename T>
61 using strip_first_arg_t = typename strip_first_arg<T>::type;
62
63 // matching helper class to only return the first type
64 template <typename T>
65 struct get_first_arg
66 {
67 using type = void;
68 };
69
70 template <typename FirstArg, typename... Rest>
71 struct get_first_arg<std::tuple<FirstArg, Rest...>>
72 {
73 using type = FirstArg;
74 };
75
76 template <typename... Args>
77 using get_first_arg_t = typename get_first_arg<Args...>::type;
78
79 // helper class to remove const and reference from types
80 template <typename T>
81 struct decay_tuple
82 {};
83
84 template <typename... Args>
85 struct decay_tuple<std::tuple<Args...>>
86 {
87 using type = std::tuple<typename std::decay<Args>::type...>;
88 };
89
90 template <typename... Args>
91 using decay_tuple_t = typename decay_tuple<Args...>::type;
92
93 // Small helper class for stripping off the first + last character of a char
94 // array
95 template <std::size_t N, std::size_t... Is>
96 constexpr std::array<char, N - 2>
strip_ends(const std::array<char,N> & s,std::index_sequence<Is...>)97 strip_ends(const std::array<char, N>& s, std::index_sequence<Is...>)
98 {
99 return {(s[1 + Is])..., static_cast<char>(0)};
100 }
101
102 template <std::size_t N>
strip_ends(const std::array<char,N> & s)103 constexpr std::array<char, N - 2> strip_ends(const std::array<char, N>& s)
104 {
105 return strip_ends(s, std::make_index_sequence<N - 3>{});
106 }
107
108 template <typename T>
109 class has_member_find
110 {
111 private:
112 template <typename U>
113 static U& ref();
114
115 template <typename U>
116 static std::true_type check(decltype(ref<U>().find(
117 ref<std::tuple_element_t<0, typename U::value_type>>()))*);
118 template <typename>
119 static std::false_type check(...);
120
121 public:
122 static constexpr bool value =
123 decltype(check<std::decay_t<T>>(nullptr))::value;
124 };
125
126 template <typename T>
127 constexpr bool has_member_find_v = has_member_find<T>::value;
128
129 template <typename T>
130 class has_member_contains
131 {
132 private:
133 template <typename U>
134 static U& ref();
135
136 template <typename U>
137 static std::true_type check(decltype(ref<U>().contains(
138 ref<std::tuple_element_t<0, typename U::value_type>>()))*);
139 template <typename>
140 static std::false_type check(...);
141
142 public:
143 static constexpr bool value =
144 decltype(check<std::decay_t<T>>(nullptr))::value;
145 };
146
147 template <typename T>
148 constexpr bool has_member_contains_v = has_member_contains<T>::value;
149
150 template <typename T>
151 struct is_optional : public std::false_type
152 {};
153
154 template <typename T>
155 struct is_optional<std::optional<T>> : public std::true_type
156 {};
157
158 template <typename T>
159 struct is_optional<const std::optional<T>> : public std::true_type
160 {};
161
162 template <typename T>
163 struct is_optional<std::optional<T>&> : public std::true_type
164 {};
165
166 template <typename T>
167 struct is_optional<const std::optional<T>&> : public std::true_type
168 {};
169
170 template <typename T>
171 constexpr bool is_optional_v = is_optional<T>::value;
172
173 } // namespace utility
174
175 } // namespace sdbusplus
176