version 0.4.1
traits.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2025 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
9#pragma once
10#include <functional>
11#include <memory>
12#include <tuple>
13#include <type_traits>
14
15namespace Eigen {
16
17template <typename Derived>
19}
20
21#include <dune/common/hybridutilities.hh>
22namespace Ikarus::traits {
23
29template <typename T>
30concept Pointer = std::is_pointer_v<T> || std::is_same_v<T, std::nullptr_t>;
31
32#ifndef DOXYGEN
33template <typename>
34struct is_tuple : std::false_type
35{
36};
37#endif
43template <typename... T>
44struct is_tuple<std::tuple<T...>> : std::true_type
45{
46};
47
55template <class Tuple, class Type>
56requires is_tuple<Tuple>::value
57consteval int countType() {
58 int count = 0;
59 Dune::Hybrid::forEach(Dune::Hybrid::integralRange(Dune::index_constant<std::tuple_size_v<Tuple>>()), [&](auto i) {
60 using currentType = std::remove_cvref_t<std::tuple_element_t<i, Tuple>>;
61 if constexpr (std::is_same_v<currentType, Type>)
62 ++count;
63 });
64 return count;
65}
66
75template <typename Fun, typename... Args>
76using ReturnType = std::invoke_result_t<Fun, Args...>;
77
86template <typename T, typename Tuple>
87struct hasType : std::false_type
88{
89};
90
91#ifndef DOXYGEN
92template <typename T>
93struct hasType<T, std::tuple<>> : std::false_type
94{
95};
96
97template <typename T>
98struct hasType<T, T> : std::true_type
99{
100};
101
109template <typename T, typename U, typename... Ts>
110struct hasType<T, std::tuple<U, Ts...>> : hasType<T, std::tuple<Ts...>>
111{
112};
113
114template <typename T, typename... Ts>
115struct hasType<T, std::tuple<T, Ts...>> : std::true_type
116{
117};
118#endif
119
120#ifndef DOXYGEN
121template <template <typename...> class, typename...>
122struct isSpecialization : std::false_type
123{
124};
125#endif
126
134template <typename T>
135struct isSharedPtr : std::false_type
136{
137};
138
139#ifndef DOXYGEN
140template <typename T>
141struct isSharedPtr<std::shared_ptr<T>> : std::true_type
142{
143};
144#endif
145
151template <typename T>
152struct isUniquePtr : std::false_type
153{
154};
155
156#ifndef DOXYGEN
157
158template <typename T, typename Deleter>
159struct isUniquePtr<std::unique_ptr<T, Deleter>> : std::true_type
160{
161};
162#endif
163
164template <typename T>
166{
167 template <typename U = T>
168 static auto test(int) -> std::remove_reference<decltype(*std::declval<U>())>;
169 static auto test(...) -> std::remove_cv<T>;
170
171public:
172 using type = typename decltype(test(0))::type;
173};
174
175template <typename T>
177
184template <template <typename...> class U, typename... T>
185struct isSpecialization<U, U<T...>> : std::true_type
186{
187};
188
189#ifndef DOXYGEN
190template <template <typename, auto...> class Type, typename>
191struct isSpecializationTypeAndNonTypes : std::false_type
192{
193};
194
195template <template <typename, auto...> class Type, typename T, auto... N>
196struct isSpecializationTypeAndNonTypes<Type, Type<T, N...>> : std::true_type
197{
198};
199
200template <template <auto, typename...> class Type, typename>
201struct isSpecializationNonTypeAndTypes : std::false_type
202{
203};
204
205template <template <auto, auto, typename...> class Type, typename>
206struct isSpecializationNonTypeNonTypeAndTypes : std::false_type
207{
208};
209#endif
210
220template <template <auto, typename...> class Type, auto T, typename... N>
221struct isSpecializationNonTypeAndTypes<Type, Type<T, N...>> : std::true_type
222{
223};
224
235template <template <auto, auto, typename...> class Type, auto T, auto R, typename... N>
236struct isSpecializationNonTypeNonTypeAndTypes<Type, Type<T, R, N...>> : std::true_type
237{
238};
239
240#ifndef DOXYGEN
241template <template <typename, auto, typename> class Type, typename>
242struct isSpecializationTypeNonTypeAndType : std::false_type
243{
244};
245#endif
256template <template <typename, auto, typename> class Type, typename T, auto M, typename N>
257struct isSpecializationTypeNonTypeAndType<Type, Type<T, M, N>> : std::true_type
258{
259};
260
261#ifndef DOXYGEN
262template <template <auto...> class Type, typename>
263struct isSpecializationNonTypes : std::false_type
264{
265};
266#endif
267
276template <template <auto...> class Type, auto... N>
277struct isSpecializationNonTypes<Type, Type<N...>> : std::true_type
278{
279};
280
298template <class T, class Tuple>
299struct Index;
300#ifndef DOXYGEN
301template <class T>
302struct Index<T, std::tuple<>>
303{
304 static const std::size_t value = 0;
305};
306
307template <class T, class... Types>
308struct Index<T, std::tuple<T, Types...>>
309{
310 static constexpr std::size_t value = 0;
311};
312
313template <class T, class U, class... Types>
314struct Index<T, std::tuple<U, Types...>>
315{
316 static const std::size_t value = 1 + Index<T, std::tuple<Types...>>::value;
317};
318#endif
319
337template <class Container, class NewType>
338struct Rebind;
339
340#ifndef DOXYGEN
341/*
342 * Specialization for types like std::vector<...> and nested std::vector<std::vector>
343 */
344template <class OldType, class... Args, template <class...> class Container, class NewType>
345struct Rebind<Container<OldType, Args...>, NewType>
346{
347 using other = Container<NewType, typename Rebind<Args, NewType>::other...>;
348};
349
350/*
351 * Specialization for types like std::array<...,N>
352 */
353template <class OldType, std::size_t N, template <class, std::size_t> class Container, class NewType>
354struct Rebind<Container<OldType, N>, NewType>
355{
356 using other = Container<NewType, N>;
357};
358
359#endif
360
370template <typename T, typename = void>
372
373#ifndef DOXYGEN
377template <typename R, typename... Args>
378struct FunctionTraits<R (*)(Args...)>
379{
380 using return_type = R;
381 using ArgsTuple = std::tuple<Args...>;
382 using FreeSignature = R(Args...);
383
384 template <int i>
385 using args_type = typename std::tuple_element<i, ArgsTuple>::type;
386 static constexpr int numberOfArguments = sizeof...(Args);
387};
388
392template <typename R, typename C, typename... Args>
393struct FunctionTraits<R (C::*)(Args...) const>
394{
395 using return_type = R;
396 using ArgsTuple = std::tuple<Args...>;
397 using FreeSignature = R(Args...);
398
399 template <int i>
400 using args_type = typename std::tuple_element<i, ArgsTuple>::type;
401 static constexpr int numberOfArguments = sizeof...(Args);
402};
403
407template <typename R, typename C, typename... Args>
408struct FunctionTraits<R (C::*)(Args...)>
409{
410 using return_type = R;
411 using ArgsTuple = std::tuple<Args...>;
412 using FreeSignature = R(Args...);
413
414 template <int i>
415 using args_type = typename std::tuple_element<i, ArgsTuple>::type;
416 static constexpr int numberOfArguments = sizeof...(Args);
417};
418
423template <typename T>
424struct FunctionTraits<T, Dune::void_t<decltype(&T::operator())>> : public FunctionTraits<decltype(&T::operator())>
425{
426};
427#endif
428
436template <typename Tuple, std::size_t Pos, typename NewType>
438
439#ifndef DOXYGEN
440template <typename NewType, std::size_t Pos, typename... Args>
441struct ReplaceTypeAtPos<std::tuple<Args...>, Pos, NewType>
442{
443private:
444 template <std::size_t... Is>
445 static auto replace_impl(std::index_sequence<Is...>) -> std::tuple<std::conditional_t<Is == Pos, NewType, Args>...>;
446
447public:
448 using type = decltype(replace_impl(std::index_sequence_for<Args...>{}));
449};
450#endif
451
459template <typename Tuple, std::size_t Pos, typename NewType>
461
468template <typename R, typename Tuple>
470
471#ifndef DOXYGEN
472template <typename R, typename... Args>
473struct TupleToFunctionType<R, std::tuple<Args...>>
474{
475 using type = std::function<R(Args...)>;
476};
477#endif
478
485template <typename R, typename Tuple>
487
495template <typename Func, std::size_t Pos, typename NewType>
497
498#ifndef DOXYGEN
499template <typename R, typename... Args, std::size_t Pos, typename NewType>
500struct ChangeArgTypeAtPos<std::function<R(Args...)>, Pos, NewType>
501{
502 using OriginalFunction = std::function<R(Args...)>;
505 using NewFunctionType = TupleToFunctionType_t<R, NewArgsTuple>;
506};
507#endif
508
516template <typename T>
517concept EigenSparseMatrix = std::is_base_of_v<Eigen::SparseMatrixBase<T>, T>;
518
519} // namespace Ikarus::traits
std::invoke_result_t< Fun, Args... > ReturnType
Type trait to obtain the return type of a callable type when given specific arguments.
Definition: traits.hh:76
::value consteval int countType()
Metafunction to count the occurrences of a specific type in a tuple.
Definition: traits.hh:57
Definition: truncatedconjugategradient.hh:24
Definition: utils/concepts.hh:666
typename remove_pointer< T >::type remove_pointer_t
Definition: traits.hh:176
typename TupleToFunctionType< R, Tuple >::type TupleToFunctionType_t
Alias template for TupleToFunctionType.
Definition: traits.hh:486
typename ReplaceTypeAtPos< Tuple, Pos, NewType >::type ReplaceTypeAtPos_t
Alias template for ReplaceTypeAtPos.
Definition: traits.hh:460
Definition: utils/dirichletvalues.hh:30
Definition: traits.hh:18
Type trait to check if a specified type is present in a tuple.
Definition: traits.hh:88
Type trait to check if a type is a isSharedPtr.
Definition: traits.hh:136
Type trait to check if a type is a isUniquePtr.
Definition: traits.hh:153
Definition: traits.hh:166
typename decltype(test(0))::type type
Definition: traits.hh:172
Type trait to get the index of a type in a tuple.
Definition: traits.hh:299
Type trait to rebind the underlying type of containers.
Definition: traits.hh:338
Type trait for extracting information about functions.
Definition: traits.hh:371
Helper to replace the type at a specific position in a tuple.
Definition: traits.hh:437
Helper to convert a tuple to a function type.
Definition: traits.hh:469
Main function to wrap the type at position pos in a std::function.
Definition: traits.hh:496
Concept to check if a type is a pointer or nullptr_t.
Definition: traits.hh:30
Concept to check if a type is an Eigen SparseMatrix.
Definition: traits.hh:517