OGS
TMP.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <algorithm>
7#include <array>
8#include <utility>
9
10#include "Algorithm.h"
11
12namespace BaseLib::TMP
13{
14// Concat ----------------------------------------------------------------------
18template <typename List1, typename List2>
19struct Concat;
20
21template <template <typename... /*Types*/> typename List, typename... Types1,
22 typename... Types2>
23struct Concat<List<Types1...>, List<Types2...>>
24{
25 using type = List<Types1..., Types2...>;
26};
27
29template <typename List1, typename List2>
31
32// filter- ---------------------------------------------------------------------
34template <typename...>
35struct List
36{
37};
38
39namespace detail
40{
41template <typename Pred, template <typename...> typename SomeListOfTypes>
42constexpr List<> filter(Pred, SomeListOfTypes<>*)
43{
44 return {};
45}
46
47template <typename Pred, template <typename...> typename SomeListOfTypes,
48 typename Head, typename... Tail>
49constexpr decltype(auto) filter(Pred pred, SomeListOfTypes<Head, Tail...>*)
50{
51 constexpr auto tail_arg = static_cast<List<Tail...>*>(nullptr);
52 using TailFiltered = decltype(filter(pred, tail_arg));
53
54 using Result =
55 std::conditional_t<pred((Head*)nullptr),
56 Concat_t<List<Head>, TailFiltered>, TailFiltered>;
57
58 return Result{};
59}
60} // namespace detail
61
70template <typename List, typename Pred>
71decltype(auto) filter(Pred pred)
72{
73 return detail::filter(pred, static_cast<List*>(nullptr));
74}
75
76// Map -------------------------------------------------------------------------
81template <template <typename /*FromType*/> typename MapFromTypeToType,
82 typename List>
83struct Map;
84
85template <template <typename /*FromType*/> typename MapFromTypeToType,
86 template <typename... /*Types*/> typename List, typename... Types>
87struct Map<MapFromTypeToType, List<Types...>>
88{
90};
91
93template <template <typename /*FromType*/> typename MapFromTypeToType,
94 typename List>
96
97// map_to_array ----------------------------------------------------------------
98namespace detail
99{
100template <template <typename... /*Types*/> typename List, typename Function,
101 typename Head, typename... Tail>
102constexpr decltype(auto) map_to_array(Function&& f, List<Head, Tail...>*)
103{
104 using CommonType =
105 std::common_type_t<std::invoke_result_t<Function, Head*>,
106 std::invoke_result_t<Function, Tail*>...>;
107
108 return std::array<CommonType, 1 + sizeof...(Tail)>{f((Head*)nullptr),
109 f((Tail*)nullptr)...};
110}
111
112template <template <typename... /*Types*/> typename List, typename Function>
113constexpr std::array<std::nullptr_t, 0> map_to_array(Function&& /*f*/, List<>*)
114{
115 return {};
116}
117} // namespace detail
118
126template <typename List, typename Function>
127constexpr decltype(auto) map_to_array(Function&& f)
128{
129 return detail::map_to_array(std::forward<Function>(f), (List*)nullptr);
130}
131
132// foreach ---------------------------------------------------------------------
133namespace detail
134{
135template <template <typename... /*Types*/> typename List, typename Function,
136 typename... Types>
137void foreach (Function&& f, List<Types...>*)
138{
139 (..., f((Types*)nullptr));
140}
141} // namespace detail
142
149template <typename List, typename Function>
150void foreach (Function&& f)
151{
152 detail::foreach (std::forward<Function>(f), (List*)nullptr);
153}
154
155// contains --------------------------------------------------------------------
157template <typename List, typename Type>
158constexpr bool contains()
159{
160 auto pred_is_same = []<typename OtherType>(OtherType*)
161 { return std::is_same_v<Type, OtherType>; };
162
163 return any_of(map_to_array<List>(pred_is_same));
164}
165
166} // namespace BaseLib::TMP
constexpr decltype(auto) map_to_array(Function &&f, List< Head, Tail... > *)
Definition TMP.h:102
void foreach(Function &&f, List< Types... > *)
Definition TMP.h:137
constexpr List filter(Pred, SomeListOfTypes<> *)
Definition TMP.h:42
constexpr decltype(auto) map_to_array(Function &&f)
Definition TMP.h:127
typename Concat< List1, List2 >::type Concat_t
Definition TMP.h:30
constexpr bool contains()
Returns if Type is contained in the given List of types.
Definition TMP.h:158
decltype(auto) filter(Pred pred)
Definition TMP.h:71
typename Map< MapFromTypeToType, List >::type Map_t
Definition TMP.h:95
constexpr bool any_of(List const &values)
Checks if any of the elements in the given list is true.
Definition Algorithm.h:286
A list of types.
Definition TMP.h:36
List< MapFromTypeToType< Types >... > type
Definition TMP.h:89