YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
type_traits.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <yaclib/fwd.hpp>
5
6#include <exception>
7#include <type_traits>
8#include <utility>
9#include <variant>
10
11namespace yaclib {
12
13// Not available in C++17, move to std if C++17 support is ever dropped
14template <typename T>
15using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
16
17template <typename... Args>
18using head_t = typename detail::Head<Args...>::Type; // NOLINT
19
20template <typename Func, typename... Arg>
21inline constexpr bool is_invocable_v = detail::IsInvocable<Func, Arg...>::Value; // NOLINT
22
23template <typename Func, typename... Arg>
24using invoke_t = typename detail::Invoke<Func, Arg...>::Type; // NOLINT
25
26template <typename T>
28
29template <typename T>
31
32template <typename T>
34
35template <typename T>
37
38template <typename T>
42
43template <typename T>
47
48template <typename T>
49inline constexpr bool is_task_v = detail::IsInstantiationOf<Task, T>::Value; // NOLINT
50
51// Waitable: a reference to a shared future or a non-const reference to a regular future
52template <typename T>
53inline constexpr bool is_waitable_v =
55 (!std::is_const_v<std::remove_reference_t<T>> && is_future_base_v<remove_cvref_t<T>>);
56
57// Waitable with timeout: a non-const reference to a regular future (shared futures cannot be waited with timeout)
58template <typename T>
59inline constexpr bool is_waitable_with_timeout_v =
60 (!std::is_const_v<std::remove_reference_t<T>> && is_future_base_v<remove_cvref_t<T>>);
61
62// Combinator input: futures by value
63template <typename T>
65
66template <typename T>
68
69template <typename T>
71
72template <bool Condition, typename T>
73decltype(auto) move_if(T&& arg) noexcept { // NOLINT
74 if constexpr (Condition) {
75 return std::move(std::forward<T>(arg));
76 } else {
77 return std::forward<T>(arg);
78 }
79}
80
81template <typename T, typename... List>
82inline constexpr auto kCount = (std::size_t{std::is_same_v<T, List> ? 1 : 0} + ...);
83
84template <typename T, typename... Ts>
85inline constexpr auto kContains = (std::is_same_v<T, Ts> || ...);
86
87template <typename T, typename Tuple>
88struct Prepend;
89
90template <typename T, typename... Ts>
91struct Prepend<T, std::tuple<Ts...>> {
92 using Type = std::tuple<T, Ts...>;
93};
94
95template <typename Tuple>
96struct Tail;
97
98template <typename T, typename... Ts>
99struct Tail<std::tuple<T, Ts...>> {
100 using Type = std::tuple<Ts...>;
101};
102
103template <typename Tuple>
104using tail_t = typename Tail<Tuple>::Type;
105
106template <template <typename> typename F, typename Tuple>
107struct Filter;
108
109template <template <typename> typename F>
110struct Filter<F, std::tuple<>> {
111 using Type = std::tuple<>;
112};
113
114template <template <typename> typename F, typename T>
115struct Filter<F, std::tuple<T>> {
116 using Type = std::conditional_t<F<T>::Value, std::tuple<T>, std::tuple<>>;
117};
118
119template <template <typename> typename F, typename T, typename... Ts>
120struct Filter<F, std::tuple<T, Ts...>> {
121 private:
122 using PrevType = typename Filter<F, std::tuple<Ts...>>::Type;
123
124 public:
125 using Type = std::conditional_t<F<T>::Value, typename Prepend<T, PrevType>::Type, PrevType>;
126};
127
128template <typename Tuple>
129struct Unique;
130
131template <>
132struct Unique<std::tuple<>> {
133 using Type = std::tuple<>;
134};
135
136template <typename T>
137struct Unique<std::tuple<T>> {
138 using Type = std::tuple<T>;
139};
140
141template <typename T, typename... Ts>
142struct Unique<std::tuple<T, Ts...>> {
143 private:
144 using PrevType = typename Unique<std::tuple<Ts...>>::Type;
145
146 public:
147 using Type = std::conditional_t<kContains<T, Ts...>, PrevType, typename Prepend<T, PrevType>::Type>;
148};
149
150template <typename Tuple>
151struct Variant;
152
153template <typename... Ts>
154struct Variant<std::tuple<Ts...>> {
155 using Type = std::variant<Ts...>;
156};
157
158template <typename Tuple>
160
161template <typename T>
162struct MaybeVariant<std::tuple<T>> {
163 using Type = T;
164};
165
166template <typename... Ts>
167struct MaybeVariant<std::tuple<Ts...>> {
168 using Type = std::variant<Ts...>;
169};
170
171template <typename T>
172struct WrapVoid {
173 using Type = T;
174};
175
176template <>
177struct WrapVoid<void> {
178 using Type = Unit;
179};
180
181template <typename T>
183
184template <std::size_t FromIndex, std::size_t ToIndex, typename FromTuple, typename ToTuple>
186
187template <std::size_t ToIndex, typename... From, typename... To>
188struct TranslateIndexImpl<0, ToIndex, std::tuple<From...>, std::tuple<To...>> {
189 static_assert(sizeof...(From) >= sizeof...(To));
190 static constexpr std::size_t Index() {
191 return ToIndex;
192 }
193};
194
195template <std::size_t FromIndex, std::size_t ToIndex, typename... From, typename... To>
196struct TranslateIndexImpl<FromIndex, ToIndex, std::tuple<From...>, std::tuple<To...>> {
197 static_assert(sizeof...(From) >= sizeof...(To));
198 static_assert(FromIndex != 0);
199
200 static constexpr std::size_t Index() {
201 if constexpr (std::is_same_v<head_t<From...>, head_t<To...>>) {
202 return TranslateIndexImpl<FromIndex - 1, ToIndex + 1, tail_t<std::tuple<From...>>,
203 tail_t<std::tuple<To...>>>::Index();
204 } else {
205 return TranslateIndexImpl<FromIndex - 1, ToIndex, tail_t<std::tuple<From...>>, std::tuple<To...>>::Index();
206 }
207 }
208};
209
210template <std::size_t FromIndex, typename FromTuple, typename ToTuple>
212
213template <typename T, typename Tuple>
214struct IndexOf;
215
216template <typename T, typename... Ts>
217struct IndexOf<T, std::tuple<Ts...>> {
218 static_assert(sizeof...(Ts) > 0);
219
220 static constexpr std::size_t Index() {
221 if constexpr (std::is_same_v<T, head_t<Ts...>>) {
222 return 0;
223 } else {
224 return 1 + IndexOf<T, tail_t<std::tuple<Ts...>>>::Index();
225 }
226 }
227};
228
229template <typename T, typename Tuple>
230inline constexpr std::size_t index_of_v = IndexOf<T, Tuple>::Index();
231
232template <typename T>
233constexpr bool Check() noexcept {
234 static_assert(!std::is_reference_v<T>, "T cannot be V&, just use pointer or std::reference_wrapper");
235 static_assert(!std::is_const_v<T>, "T cannot be const, because it's unnecessary");
236 static_assert(!std::is_volatile_v<T>, "T cannot be volatile, because it's unnecessary");
237 static_assert(!is_result_v<T>, "T cannot be Result, because it's ambiguous");
238 static_assert(!is_future_base_v<T>, "T cannot be Future, because it's ambiguous");
239 static_assert(!is_task_v<T>, "T cannot be Task, because it's ambiguous");
240 static_assert(!std::is_same_v<T, std::exception_ptr>, "T cannot be std::exception_ptr, because it's ambiguous");
241 static_assert(!std::is_same_v<T, Unit>, "T cannot be Unit, because Unit for internal instead of void usage");
242 return true;
243}
244
245} // namespace yaclib
Contract< V, T > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
constexpr bool is_waitable_v
constexpr auto kCount
typename detail::Head< Args... >::Type head_t
constexpr std::size_t index_of_v
constexpr bool is_result_v
typename detail::InstantiationType< Result, T >::Value result_value_t
constexpr bool is_task_v
typename detail::AsyncTypes< T >::Value async_value_t
constexpr bool is_invocable_v
decltype(auto) move_if(T &&arg) noexcept
typename detail::InstantiationTypes< Task, T >::Trait task_trait_t
typename WrapVoid< T >::Type wrap_void_t
constexpr bool is_combinator_input_v
typename Tail< Tuple >::Type tail_t
constexpr bool is_future_base_v
constexpr std::size_t translate_index_v
constexpr bool Check() noexcept
constexpr bool is_shared_future_base_v
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
typename detail::Invoke< Func, Arg... >::Type invoke_t
constexpr bool is_waitable_with_timeout_v
typename detail::InstantiationTypes< Task, T >::Value task_value_t
constexpr auto kContains
typename detail::AsyncTypes< T >::Trait async_trait_t
std::conditional_t< F< T >::Value, typename Prepend< T, PrevType >::Type, PrevType > Type
std::conditional_t< F< T >::Value, std::tuple< T >, std::tuple<> > Type
static constexpr std::size_t Index()
std::conditional_t< kContains< T, Ts... >, PrevType, typename Prepend< T, PrevType >::Type > Type