OGS
TMP.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <algorithm>
14#include <array>
15#include <utility>
16
17#include "Algorithm.h"
18
19namespace BaseLib::TMP
20{
21// Concat ----------------------------------------------------------------------
25template <typename List1, typename List2>
26struct Concat;
27
28template <template <typename... /*Types*/> typename List, typename... Types1,
29 typename... Types2>
30struct Concat<List<Types1...>, List<Types2...>>
31{
32 using type = List<Types1..., Types2...>;
33};
34
36template <typename List1, typename List2>
38
39// filter- ---------------------------------------------------------------------
41template <typename...>
42struct List
43{
44};
45
46namespace detail
47{
48template <typename Pred, template <typename...> typename SomeListOfTypes>
49constexpr List<> filter(Pred, SomeListOfTypes<>*)
50{
51 return {};
52}
53
54template <typename Pred, template <typename...> typename SomeListOfTypes,
55 typename Head, typename... Tail>
56constexpr decltype(auto) filter(Pred pred, SomeListOfTypes<Head, Tail...>*)
57{
58 constexpr auto tail_arg = static_cast<List<Tail...>*>(nullptr);
59 using TailFiltered = decltype(filter(pred, tail_arg));
60
61 using Result =
62 std::conditional_t<pred((Head*)nullptr),
63 Concat_t<List<Head>, TailFiltered>, TailFiltered>;
64
65 return Result{};
66}
67} // namespace detail
68
77template <typename List, typename Pred>
78decltype(auto) filter(Pred pred)
79{
80 return detail::filter(pred, static_cast<List*>(nullptr));
81}
82
83// Map -------------------------------------------------------------------------
88template <template <typename /*FromType*/> typename MapFromTypeToType,
89 typename List>
90struct Map;
91
92template <template <typename /*FromType*/> typename MapFromTypeToType,
93 template <typename... /*Types*/> typename List, typename... Types>
94struct Map<MapFromTypeToType, List<Types...>>
95{
97};
98
100template <template <typename /*FromType*/> typename MapFromTypeToType,
101 typename List>
103
104// map_to_array ----------------------------------------------------------------
105namespace detail
106{
107template <template <typename... /*Types*/> typename List, typename Function,
108 typename Head, typename... Tail>
109constexpr decltype(auto) map_to_array(Function&& f, List<Head, Tail...>*)
110{
111 using CommonType =
112 std::common_type_t<std::invoke_result_t<Function, Head*>,
113 std::invoke_result_t<Function, Tail*>...>;
114
115 return std::array<CommonType, 1 + sizeof...(Tail)>{f((Head*)nullptr),
116 f((Tail*)nullptr)...};
117}
118
119template <template <typename... /*Types*/> typename List, typename Function>
120constexpr std::array<std::nullptr_t, 0> map_to_array(Function&& /*f*/, 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, typename Function,
143 typename... Types>
144void foreach (Function&& f, List<Types...>*)
145{
146 (..., f((Types*)nullptr));
147}
148} // namespace detail
149
156template <typename List, typename Function>
157void foreach (Function&& f)
158{
159 detail::foreach (std::forward<Function>(f), (List*)nullptr);
160}
161
162// contains --------------------------------------------------------------------
164template <typename List, typename Type>
165constexpr bool contains()
166{
167 auto pred_is_same = []<typename OtherType>(OtherType*)
168 { return std::is_same_v<Type, OtherType>; };
169
170 return any_of(map_to_array<List>(pred_is_same));
171}
172
173} // namespace BaseLib::TMP
constexpr decltype(auto) map_to_array(Function &&f, List< Head, Tail... > *)
Definition TMP.h:109
void foreach(Function &&f, List< Types... > *)
Definition TMP.h:144
constexpr List filter(Pred, SomeListOfTypes<> *)
Definition TMP.h:49
constexpr decltype(auto) map_to_array(Function &&f)
Definition TMP.h:134
typename Concat< List1, List2 >::type Concat_t
Definition TMP.h:37
constexpr bool contains()
Returns if Type is contained in the given List of types.
Definition TMP.h:165
decltype(auto) filter(Pred pred)
Definition TMP.h:78
typename Map< MapFromTypeToType, List >::type Map_t
Definition TMP.h:102
constexpr bool any_of(List const &values)
Checks if any of the elements in the given list is true.
Definition Algorithm.h:276
A list of types.
Definition TMP.h:43