29 sort(r.begin(), r.end());
43 template <
typename Value>
44 auto appendUnique(std::ranges::random_access_range
auto& r, Value&& v) {
45 static_assert(std::is_same_v<
typename decltype(begin(r))::value_type, std::remove_reference_t<
decltype(v)>>);
46 const auto it = find(begin(r), end(r), v);
47 size_t index = std::distance(begin(r), it);
48 if (it == end(r)) r.push_back(std::forward<Value>(v));
62 template <
class Container>
64 std::ranges::for_each(c, [&os](
auto&& var) { os << var <<
'\n'; });
75 template <
class Container>
77 auto transformValueToPointer = [](
auto&& obj) {
return &obj; };
78 return (std::ranges::subrange(cont.begin(), cont.end()) | std::views::transform(transformValueToPointer));
90 template <
class Container>
92 auto transformValueToPointer = [](
auto&& obj) ->
auto& {
return *obj; };
93 return (std::ranges::subrange(cont.begin(), cont.end()) | std::views::transform(transformValueToPointer));
98 template <
typename... Types>
103 template <
class Tuple, std::size_t... I>
104 constexpr auto makeTupleSubsetImpl(Tuple&& t, std::index_sequence<I...>) {
105 return std::make_tuple(std::get<I>(std::forward<Tuple>(t))...);
108 template <
class Tuple, std::size_t... I>
109 constexpr auto makeTupleFromTupleIndicesImpl(Tuple&& t, std::index_sequence<I...>) {
110 return std::make_tuple(std::get<I>(std::forward<Tuple>(t))...);
113 template <
typename T,
typename... Ts>
114 struct uniqueImpl : std::type_identity<T> {};
116 template <
typename... Ts,
typename U,
typename... Us>
117 struct uniqueImpl<std::tuple<Ts...>, U, Us...>
118 : std::conditional_t<(std::is_same_v<U, Ts> || ...), uniqueImpl<std::tuple<Ts...>, Us...>,
119 uniqueImpl<std::tuple<Ts..., U>, Us...>> {};
121 template <
typename... Ts>
122 using unique_tupleImpl =
typename uniqueImpl<std::tuple<>, Ts...>::type;
124 template <
typename T,
typename... Types>
125 auto makeNestedTupleFlatImpl() {
126 constexpr bool isTuple = traits::isSpecialization<std::tuple, T>::value;
127 if constexpr (
sizeof...(Types) > 0) {
128 if constexpr (isTuple)
131 return std::tuple_cat(std::make_tuple(T()), makeNestedTupleFlatImpl<Types...>());
133 if constexpr (isTuple)
136 return std::make_tuple(T());
140 template <
typename T,
typename... Types>
141 auto makeNestedTupleFlatAndStoreReferencesImpl(
const std::tuple<T, Types...>& tup) {
142 constexpr bool isTuple = traits::isSpecialization<std::tuple, std::remove_cvref_t<T>>::value;
143 if constexpr (
sizeof...(Types) > 0) {
144 if constexpr (isTuple)
145 return std::tuple_cat(
146 makeNestedTupleFlatAndStoreReferencesImpl(std::get<0>(tup)),
148 [](
const T&,
const Types&... args) {
149 return makeNestedTupleFlatAndStoreReferencesImpl(std::make_tuple(std::cref(args)...));
153 return std::tuple_cat(
154 std::make_tuple(std::cref(std::get<0>(tup))),
156 [](
const T&,
const Types&... args) {
157 return makeNestedTupleFlatAndStoreReferencesImpl(std::make_tuple(std::cref(args)...));
161 if constexpr (isTuple)
162 return makeNestedTupleFlatAndStoreReferencesImpl(std::get<0>(tup));
164 return std::make_tuple(std::cref(std::get<0>(tup)));
168 template <
typename T,
typename... Types>
169 auto makeNestedTupleFlatAndStoreReferencesNonConstImpl(
const std::tuple<T, Types...>& tupconst) {
170 auto& tup =
const_cast<std::tuple<T, Types...
>&>(tupconst);
171 constexpr bool isTuple = traits::isSpecialization<std::tuple, std::remove_cvref_t<T>>::value;
172 if constexpr (
sizeof...(Types) > 0) {
173 if constexpr (isTuple)
174 return std::tuple_cat(
175 makeNestedTupleFlatAndStoreReferencesNonConstImpl(std::get<0>(tup)),
177 [](T&, Types&... args) {
178 return makeNestedTupleFlatAndStoreReferencesNonConstImpl(std::make_tuple(std::ref(args)...));
182 return std::tuple_cat(
183 std::make_tuple(std::ref(std::get<0>(tup))),
185 [](T&, Types&... args) {
186 return makeNestedTupleFlatAndStoreReferencesNonConstImpl(std::make_tuple(std::ref(args)...));
190 if constexpr (isTuple)
191 return makeNestedTupleFlatAndStoreReferencesNonConstImpl(std::get<0>(tup));
193 return std::make_tuple(std::ref(std::get<0>(tup)));
214 template <
typename Tuple,
typename Predicate>
215 constexpr size_t find_if(Tuple&& tuple, Predicate pred) {
216 size_t index = std::tuple_size<std::remove_reference_t<Tuple>>::value;
217 size_t currentIndex = 0;
220 Dune::Hybrid::forEach(tuple, [&](
auto&& value) {
221 if (!found && pred(value)) {
222 index = currentIndex;
242 template <
typename Tuple,
typename Predicate>
244 return find_if(tuple, pred) == std::tuple_size<std::decay_t<Tuple>>::value;
259 template <
typename Tuple,
typename Predicate>
260 bool any_of(Tuple&& tuple, Predicate pred) {
278 template <
typename Tuple,
typename Predicate>
279 auto filter(Tuple&& tuple, Predicate pred) {
281 [&pred](
auto... ts) {
282 return std::tuple_cat(std::conditional_t<pred(ts), std::tuple<
decltype(ts)>, std::tuple<>>{}...);
298 template <
typename... Types>
299 constexpr auto unique([[maybe_unused]] std::tuple<Types...>&& tuple) {
300 return Impl::unique_tupleImpl<Types...>();
316 template <
typename Tuple,
typename Predicate>
317 constexpr size_t count_if(Tuple&& tuple, Predicate pred) {
319 Dune::Hybrid::forEach(tuple, [&](
auto&& value) {
320 if (pred(value)) ++counter;
337 template <
template <
auto...>
class Type,
typename Tuple>
339 return find_if(std::remove_cvref_t<Tuple>(), []<
typename T>(T&&) {
340 return traits::isSpecializationNonTypes<Type, std::remove_cvref_t<T>>::value;
356 template <
template <
auto...>
class Type,
typename Tuple>
358 constexpr int index = findTypeSpecialization<Type, Tuple>();
359 static_assert(index < std::tuple_size_v<std::remove_cvref_t<Tuple>>,
360 "The found index has to be smaller than the tuple size");
361 return std::get<index>(tuple);
377 template <
template <
auto...>
class Type,
typename Tuple>
380 find_if(std::remove_cvref_t<Tuple>(),
381 []<
typename T>(T&&) {
return traits::isSpecializationNonTypes<Type, std::remove_cvref_t<T>>::value; })
382 < std::tuple_size_v<std::remove_cvref_t<Tuple>>);
396 template <
template <
auto...>
class Type,
typename Tuple>
399 Tuple(), []<
typename T>(T&&) {
return traits::isSpecializationNonTypes<Type, std::remove_cvref_t<T>>::value; });
413 template <
template <
auto...>
class Type,
typename Tuple>
428 template <
int N,
class Tuple>
430 static_assert(N < std::tuple_size_v<std::remove_reference_t<Tuple>>,
431 "The requested size needs to be smaller than the size of the tuple.");
433 return Impl::makeTupleSubsetImpl(std::forward<Tuple>(t), std::make_index_sequence<N>{});
449 template <
class Tuple, std::size_t... I>
451 return Impl::makeTupleFromTupleIndicesImpl(std::forward<Tuple>(t), std::index_sequence<I...>{});
461 template <
typename... Types>
463 return decltype(Impl::makeNestedTupleFlatImpl<Types...>())();
475 template <
typename Tuple>
477 if constexpr (std::tuple_size_v<std::remove_cvref_t<Tuple>> == 0)
479 else if constexpr (!std::is_const_v<std::remove_reference_t<Tuple>>)
480 return Impl::makeNestedTupleFlatAndStoreReferencesNonConstImpl(std::forward<Tuple>(tup));
482 return Impl::makeNestedTupleFlatAndStoreReferencesImpl(std::forward<Tuple>(tup));
492 template <
typename T>
495 if constexpr (!std::is_same_v<T, std::nullptr_t>)
Contains stl-like type traits.
auto getSpecialization(Tuple &&tuple)
Gets the specialization of the given template type from the tuple.
Definition: algorithms.hh:357
void printContent(Container &&c, std::ostream &os=std::cout)
Prints the contents of a container to the specified output stream.
Definition: algorithms.hh:63
constexpr auto unique(std::tuple< Types... > &&tuple)
Creates a tuple with unique types from the given tuple.
Definition: algorithms.hh:299
constexpr auto makeTupleSubset(Tuple &&t)
Creates a subset tuple with the first N elements from the given tuple.
Definition: algorithms.hh:429
bool none_of(Tuple &&tuple, Predicate pred)
Checks if none of the elements in the tuple satisfy a given predicate.
Definition: algorithms.hh:243
auto transformValueRangeToPointerRange(Container &cont)
Transforms a value range to a pointer range.
Definition: algorithms.hh:76
constexpr int findTypeSpecialization()
Finds the index of the first element in the tuple that is a specialization of the given template type...
Definition: algorithms.hh:338
static constexpr bool countTypeSpecialization_v
Variable template for counting the occurrences of a specialization of a template type in a tuple.
Definition: algorithms.hh:414
void makeUniqueAndSort(std::ranges::random_access_range auto &r)
Sorts and removes duplicate elements from a random access range.*.
Definition: algorithms.hh:28
auto appendUnique(std::ranges::random_access_range auto &r, Value &&v)
Appends a value to the range if it is not already present.
Definition: algorithms.hh:44
auto transformPointerRangeToReferenceRange(Container &cont)
Transforms a pointer range to a reference range.
Definition: algorithms.hh:91
bool any_of(Tuple &&tuple, Predicate pred)
Checks if any of the elements in the tuple satisfy a given predicate.
Definition: algorithms.hh:260
auto filter(Tuple &&tuple, Predicate pred)
Filters the elements of a tuple based on a given predicate.
Definition: algorithms.hh:279
constexpr bool countTypeSpecialization()
Counts the occurrences of a specialization of a template type in a tuple.
Definition: algorithms.hh:397
constexpr size_t count_if(Tuple &&tuple, Predicate pred)
Counts the number of elements in the tuple satisfying the given predicate.
Definition: algorithms.hh:317
constexpr bool hasTypeSpecialization()
Checks if a tuple has a specialization of a template type.
Definition: algorithms.hh:378
constexpr auto makeTupleFromTupleIndices(Tuple &&t)
Creates a new tuple using indices from the original tuple.
Definition: algorithms.hh:450
constexpr size_t find_if(Tuple &&tuple, Predicate pred)
Finds the index of the first element in the tuple satisfying a predicate.
Definition: algorithms.hh:215
Definition: algorithms.hh:17
auto makeNestedTupleFlatAndStoreReferences(Tuple &&tup)
Creates a flattened nested tuple and stores references.
Definition: algorithms.hh:476
auto makeNestedTupleFlat(std::tuple< Types... >)
Creates a flattened nested tuple.
Definition: algorithms.hh:462
auto & returnReferenceOrNulloptIfObjectIsNullPtr(T v)
Returns a reference or std::nullopt if the object is a nullptr.
Definition: algorithms.hh:494
Concept to check if a type is a pointer or nullptr_t.
Definition: traits.hh:23