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 /*pred*/, SomeListOfTypes<>* /*list*/)
43{
44 return {};
45}
46
47template <typename Pred,
48 template <typename...> typename SomeListOfTypes,
49 typename Head,
50 typename... Tail>
51constexpr decltype(auto) filter(Pred pred,
52 SomeListOfTypes<Head, Tail...>* /*list*/)
53{
54 constexpr auto tail_arg = static_cast<List<Tail...>*>(nullptr);
55 using TailFiltered = decltype(filter(pred, tail_arg));
56
57 using Result =
58 std::conditional_t<pred((Head*)nullptr),
59 Concat_t<List<Head>, TailFiltered>, TailFiltered>;
60
61 return Result{};
62}
63} // namespace detail
64
73template <typename List, typename Pred>
74decltype(auto) filter(Pred pred)
75{
76 return detail::filter(pred, static_cast<List*>(nullptr));
77}
78
79// Map -------------------------------------------------------------------------
84template <template <typename /*FromType*/> typename MapFromTypeToType,
85 typename List>
86struct Map;
87
88template <template <typename /*FromType*/> typename MapFromTypeToType,
89 template <typename... /*Types*/> typename List, typename... Types>
90struct Map<MapFromTypeToType, List<Types...>>
91{
93};
94
96template <template <typename /*FromType*/> typename MapFromTypeToType,
97 typename List>
99
100// map_to_array ----------------------------------------------------------------
101namespace detail
102{
103template <template <typename... /*Types*/> typename List,
104 typename Function,
105 typename Head,
106 typename... Tail>
107constexpr decltype(auto) map_to_array(Function&& f,
108 List<Head, Tail...>* /*list*/)
109{
110 using CommonType =
111 std::common_type_t<std::invoke_result_t<Function, Head*>,
112 std::invoke_result_t<Function, Tail*>...>;
113
114 return std::array<CommonType, 1 + sizeof...(Tail)>{f((Head*)nullptr),
115 f((Tail*)nullptr)...};
116}
117
118template <template <typename... /*Types*/> typename List, typename Function>
119constexpr std::array<std::nullptr_t, 0> map_to_array(Function&& /*f*/,
120 List<>* /*list*/)
121{
122 return {};
123}
124} // namespace detail
125
133template <typename List, typename Function>
134constexpr decltype(auto) map_to_array(Function&& f)
135{
136 return detail::map_to_array(std::forward<Function>(f), (List*)nullptr);
137}
138
139// foreach ---------------------------------------------------------------------
140namespace detail
141{
142template <template <typename... /*Types*/> typename List,
143 typename Function,
144 typename... Types>
145void foreach (Function&& f, List<Types...>* /*list*/)
146{
147 (..., f((Types*)nullptr));
148}
149} // namespace detail
150
157template <typename List, typename Function>
158void foreach (Function&& f)
159{
160 detail::foreach (std::forward<Function>(f), (List*)nullptr);
161}
162
163// contains --------------------------------------------------------------------
165template <typename List, typename Type>
166constexpr bool contains()
167{
168 auto pred_is_same = []<typename OtherType>(OtherType*)
169 { return std::is_same_v<Type, OtherType>; };
170
171 return any_of(map_to_array<List>(pred_is_same));
172}
173
174} // namespace BaseLib::TMP
constexpr decltype(auto) map_to_array(Function &&f, List< Head, Tail... > *)
Definition TMP.h:107
void foreach(Function &&f, List< Types... > *)
Definition TMP.h:145
constexpr List filter(Pred, SomeListOfTypes<> *)
Definition TMP.h:42
constexpr decltype(auto) map_to_array(Function &&f)
Definition TMP.h:134
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:166
decltype(auto) filter(Pred pred)
Definition TMP.h:74
typename Map< MapFromTypeToType, List >::type Map_t
Definition TMP.h:98
constexpr bool any_of(List const &values)
Checks if any of the elements in the given list is true.
Definition Algorithm.h:311
A list of types.
Definition TMP.h:36
List< MapFromTypeToType< Types >... > type
Definition TMP.h:92