version 0.4.1
traits.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2024 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 <tuple>
12#include <type_traits>
13
14namespace std {
15template <class T>
16class shared_ptr;
17}
18
19#include <dune/common/hybridutilities.hh>
20namespace Ikarus::traits {
21
27template <typename T>
28concept Pointer = std::is_pointer_v<T> || std::is_same_v<T, std::nullptr_t>;
29
30#ifndef DOXYGEN
31template <typename>
32struct is_tuple : std::false_type
33{
34};
35#endif
41template <typename... T>
42struct is_tuple<std::tuple<T...>> : std::true_type
43{
44};
45
53template <class Tuple, class Type>
54requires is_tuple<Tuple>::value
55consteval int countType() {
56 int count = 0;
57 Dune::Hybrid::forEach(Dune::Hybrid::integralRange(Dune::index_constant<std::tuple_size_v<Tuple>>()), [&](auto i) {
58 using currentType = std::remove_cvref_t<std::tuple_element_t<i, Tuple>>;
59 if constexpr (std::is_same_v<currentType, Type>)
60 ++count;
61 });
62 return count;
63}
64
73template <typename Fun, typename... Args>
74using ReturnType = std::invoke_result_t<Fun, Args...>;
75
84template <typename T, typename Tuple>
85struct hasType : std::false_type
86{
87};
88
89#ifndef DOXYGEN
90template <typename T>
91struct hasType<T, std::tuple<>> : std::false_type
92{
93};
94
95template <typename T>
96struct hasType<T, T> : std::true_type
97{
98};
99
107template <typename T, typename U, typename... Ts>
108struct hasType<T, std::tuple<U, Ts...>> : hasType<T, std::tuple<Ts...>>
109{
110};
111
112template <typename T, typename... Ts>
113struct hasType<T, std::tuple<T, Ts...>> : std::true_type
114{
115};
116#endif
117
118#ifndef DOXYGEN
119template <template <typename...> class, typename...>
120struct isSpecialization : std::false_type
121{
122};
123#endif
124
132template <typename T>
133struct isSharedPtr : std::false_type
134{
135};
136
137#ifndef DOXYGEN
138template <typename T>
139struct isSharedPtr<std::shared_ptr<T>> : std::true_type
140{
141};
142#endif
143
144template <typename T>
146{
147 template <typename U = T>
148 static auto test(int) -> std::remove_reference<decltype(*std::declval<U>())>;
149 static auto test(...) -> std::remove_cv<T>;
150
151public:
152 using type = typename decltype(test(0))::type;
153};
154
155template <typename T>
157
164template <template <typename...> class U, typename... T>
165struct isSpecialization<U, U<T...>> : std::true_type
166{
167};
168
169#ifndef DOXYGEN
170template <template <typename, auto...> class Type, typename>
171struct isSpecializationTypeAndNonTypes : std::false_type
172{
173};
174
175template <template <typename, auto...> class Type, typename T, auto... N>
176struct isSpecializationTypeAndNonTypes<Type, Type<T, N...>> : std::true_type
177{
178};
179
180template <template <auto, typename...> class Type, typename>
181struct isSpecializationNonTypeAndTypes : std::false_type
182{
183};
184#endif
185
195template <template <auto, typename...> class Type, auto T, typename... N>
196struct isSpecializationNonTypeAndTypes<Type, Type<T, N...>> : std::true_type
197{
198};
199
200#ifndef DOXYGEN
201template <template <typename, auto, typename> class Type, typename>
202struct isSpecializationTypeNonTypeAndType : std::false_type
203{
204};
205#endif
216template <template <typename, auto, typename> class Type, typename T, auto M, typename N>
217struct isSpecializationTypeNonTypeAndType<Type, Type<T, M, N>> : std::true_type
218{
219};
220
221#ifndef DOXYGEN
222template <template <auto...> class Type, typename>
223struct isSpecializationNonTypes : std::false_type
224{
225};
226#endif
227
236template <template <auto...> class Type, auto... N>
237struct isSpecializationNonTypes<Type, Type<N...>> : std::true_type
238{
239};
240
258template <class T, class Tuple>
259struct Index;
260#ifndef DOXYGEN
261template <class T>
262struct Index<T, std::tuple<>>
263{
264 static const std::size_t value = 0;
265};
266
267template <class T, class... Types>
268struct Index<T, std::tuple<T, Types...>>
269{
270 static constexpr std::size_t value = 0;
271};
272
273template <class T, class U, class... Types>
274struct Index<T, std::tuple<U, Types...>>
275{
276 static const std::size_t value = 1 + Index<T, std::tuple<Types...>>::value;
277};
278#endif
279
297template <class Container, class NewType>
298struct Rebind;
299
300#ifndef DOXYGEN
301/*
302 * Specialization for types like std::vector<...> and nested std::vector<std::vector>
303 */
304template <class OldType, class... Args, template <class...> class Container, class NewType>
305struct Rebind<Container<OldType, Args...>, NewType>
306{
307 using other = Container<NewType, typename Rebind<Args, NewType>::other...>;
308};
309
310/*
311 * Specialization for types like std::array<...,N>
312 */
313template <class OldType, std::size_t N, template <class, std::size_t> class Container, class NewType>
314struct Rebind<Container<OldType, N>, NewType>
315{
316 using other = Container<NewType, N>;
317};
318
319#endif
320
330template <typename T, typename = void>
332
333#ifndef DOXYGEN
337template <typename R, typename... Args>
338struct FunctionTraits<R (*)(Args...)>
339{
340 using return_type = R;
341 using ArgsTuple = std::tuple<Args...>;
342
343 template <int i>
344 using args_type = typename std::tuple_element<i, ArgsTuple>::type;
345 static constexpr int numberOfArguments = sizeof...(Args);
346};
347
351template <typename R, typename C, typename... Args>
352struct FunctionTraits<R (C::*)(Args...) const>
353{
354 using return_type = R;
355 using ArgsTuple = std::tuple<Args...>;
356
357 template <int i>
358 using args_type = typename std::tuple_element<i, ArgsTuple>::type;
359 static constexpr int numberOfArguments = sizeof...(Args);
360};
361
365template <typename R, typename C, typename... Args>
366struct FunctionTraits<R (C::*)(Args...)>
367{
368 using return_type = R;
369 using ArgsTuple = std::tuple<Args...>;
370
371 template <int i>
372 using args_type = typename std::tuple_element<i, ArgsTuple>::type;
373 static constexpr int numberOfArguments = sizeof...(Args);
374};
375
380template <typename T>
381struct FunctionTraits<T, Dune::void_t<decltype(&T::operator())>> : public FunctionTraits<decltype(&T::operator())>
382{
383};
384#endif
385
393template <typename Tuple, std::size_t Pos, typename NewType>
395
396#ifndef DOXYGEN
397template <typename NewType, std::size_t Pos, typename... Args>
398struct ReplaceTypeAtPos<std::tuple<Args...>, Pos, NewType>
399{
400private:
401 template <std::size_t... Is>
402 static auto replace_impl(std::index_sequence<Is...>) -> std::tuple<std::conditional_t<Is == Pos, NewType, Args>...>;
403
404public:
405 using type = decltype(replace_impl(std::index_sequence_for<Args...>{}));
406};
407#endif
408
416template <typename Tuple, std::size_t Pos, typename NewType>
418
425template <typename R, typename Tuple>
427
428#ifndef DOXYGEN
429template <typename R, typename... Args>
430struct TupleToFunctionType<R, std::tuple<Args...>>
431{
432 using type = std::function<R(Args...)>;
433};
434#endif
435
442template <typename R, typename Tuple>
444
452template <typename Func, std::size_t Pos, typename NewType>
454
455#ifndef DOXYGEN
456template <typename R, typename... Args, std::size_t Pos, typename NewType>
457struct ChangeArgTypeAtPos<std::function<R(Args...)>, Pos, NewType>
458{
459 using OriginalFunction = std::function<R(Args...)>;
462 using NewFunctionType = TupleToFunctionType_t<R, NewArgsTuple>;
463};
464#endif
465
466} // 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:74
::value consteval int countType()
Metafunction to count the occurrences of a specific type in a tuple.
Definition: traits.hh:55
STL namespace.
Definition: utils/dirichletvalues.hh:30
Definition: traits.hh:20
typename remove_pointer< T >::type remove_pointer_t
Definition: traits.hh:156
typename TupleToFunctionType< R, Tuple >::type TupleToFunctionType_t
Alias template for TupleToFunctionType.
Definition: traits.hh:443
typename ReplaceTypeAtPos< Tuple, Pos, NewType >::type ReplaceTypeAtPos_t
Alias template for ReplaceTypeAtPos.
Definition: traits.hh:417
Type trait to check if a specified type is present in a tuple.
Definition: traits.hh:86
Type trait to check if a type is a isSharedPtr.
Definition: traits.hh:134
Definition: traits.hh:146
typename decltype(test(0))::type type
Definition: traits.hh:152
Type trait to get the index of a type in a tuple.
Definition: traits.hh:259
Type trait to rebind the underlying type of containers.
Definition: traits.hh:298
Type trait for extracting information about functions.
Definition: traits.hh:331
Helper to replace the type at a specific position in a tuple.
Definition: traits.hh:394
Helper to convert a tuple to a function type.
Definition: traits.hh:426
Main function to wrap the type at position pos in a std::function.
Definition: traits.hh:453
Concept to check if a type is a pointer or nullptr_t.
Definition: traits.hh:28