Morpheus 1.0.0
Dynamic matrix type and algorithms for sparse matrices
Loading...
Searching...
No Matches
Morpheus_ContainerFactory_Impl.hpp
1
24#ifndef MORPHEUS_CONTAINERFACTORY_IMPL_HPP
25#define MORPHEUS_CONTAINERFACTORY_IMPL_HPP
26
27#include <Morpheus_Metaprogramming.hpp>
28
30namespace Morpheus {
31
32// Forward Decl
33struct Default;
34template <typename T1, typename T2>
35struct BinaryContainer;
36template <typename ContainerType, typename TypeSet>
37struct UnaryContainer;
38
39namespace Impl {
40// Forward Decl
41template <typename ContainerType, typename TypeSet>
42struct UnaryContainerProxy;
43
44template <typename Container, typename T1, typename T2, typename T3,
45 typename T4>
46struct UnaryContainerProxy_Impl;
47
48// A unary container specialization that is build by selecting the ValueType.
49// The rest of the parameters are set to default.
50template <template <class...> class Container, typename T, typename ValueType>
51struct UnaryContainerProxy_Impl<Container<T>, ValueType, Default, Default,
52 Default> {
53 using type = Container<ValueType>;
54
55 using value_type = ValueType;
56 using index_type = Default;
57 using array_layout = Default;
58 using backend = Default;
59};
60
61// A unary container specialization that is build by selecting the ValueType and
62// IndexType. The rest of the parameters are set to default.
63template <template <class...> class Container, typename T, typename ValueType,
64 typename IndexType>
65struct UnaryContainerProxy_Impl<Container<T>, ValueType, IndexType, Default,
66 Default> {
67 using type = Container<ValueType, IndexType>;
68
69 using value_type = ValueType;
70 using index_type = IndexType;
71 using array_layout = Default;
72 using backend = Default;
73};
74
75// A unary container specialization that is build by selecting the ValueType and
76// Layout. The rest of the parameters are set to default.
77template <template <class...> class Container, typename T, typename ValueType,
78 typename Layout>
79struct UnaryContainerProxy_Impl<Container<T>, ValueType, Default, Layout,
80 Default> {
81 using type = Container<ValueType, Layout>;
82
83 using value_type = ValueType;
84 using index_type = Default;
85 using array_layout = Layout;
86 using backend = Default;
87};
88
89// A unary container specialization that is build by selecting the ValueType and
90// Space. The rest of the parameters are set to default.
91template <template <class...> class Container, typename T, typename ValueType,
92 typename Space>
93struct UnaryContainerProxy_Impl<Container<T>, ValueType, Default, Default,
94 Space> {
95 using type = Container<ValueType, Space>;
96
97 using value_type = ValueType;
98 using index_type = Default;
99 using array_layout = Default;
100 using backend = Space;
101};
102
103// A unary container specialization that is build by selecting the ValueType,
104// IndexType and Layout. The rest of the parameters are set to default.
105template <template <class...> class Container, typename T, typename ValueType,
106 typename IndexType, typename Layout>
107struct UnaryContainerProxy_Impl<Container<T>, ValueType, IndexType, Layout,
108 Default> {
109 using type = Container<ValueType, IndexType, Layout>;
110
111 using value_type = ValueType;
112 using index_type = IndexType;
113 using array_layout = Layout;
114 using backend = Default;
115};
116
117// A unary container specialization that is build by selecting the ValueType,
118// IndexType and Space. The rest of the parameters are set to default.
119template <template <class...> class Container, typename T, typename ValueType,
120 typename IndexType, typename Space>
121struct UnaryContainerProxy_Impl<Container<T>, ValueType, IndexType, Default,
122 Space> {
123 using type = Container<ValueType, IndexType, Space>;
124
125 using value_type = ValueType;
126 using index_type = IndexType;
127 using array_layout = Default;
128 using backend = Space;
129};
130
131// A unary container specialization that is build by selecting the ValueType,
132// Layout and Space. The rest of the parameters are set to default.
133template <template <class...> class Container, typename T, typename ValueType,
134 typename Layout, typename Space>
135struct UnaryContainerProxy_Impl<Container<T>, ValueType, Default, Layout,
136 Space> {
137 using type = Container<ValueType, Layout, Space>;
138
139 using value_type = ValueType;
140 using index_type = Default;
141 using array_layout = Layout;
142 using backend = Space;
143};
144
145// A unary container specialization that is build by selecting the ValueType,
146// IndexType, Layout and Space. The rest of the parameters are set to default.
147template <template <class...> class Container, typename T, typename ValueType,
148 typename IndexType, typename Layout, typename Space>
149struct UnaryContainerProxy_Impl<Container<T>, ValueType, IndexType, Layout,
150 Space> {
151 using type = Container<ValueType, IndexType, Layout, Space>;
152
153 using value_type = ValueType;
154 using index_type = IndexType;
155 using array_layout = Layout;
156 using backend = Space;
157};
158
159// Takes in types as a set and forwards it to the UnaryContainer.
160template <template <class...> class Container, typename T, typename T1,
161 typename T2, typename T3, typename T4>
162struct UnaryContainerProxy<Container<T>, Set<T1, T2, T3, T4>> {
163 using unary = UnaryContainerProxy_Impl<Container<T>, T1, T2, T3, T4>;
164 using type = typename unary::type;
165
166 using value_type = typename unary::value_type;
167 using index_type = typename unary::index_type;
168 using array_layout = typename unary::array_layout;
169 using backend = typename unary::backend;
170};
171
172template <typename... Ts>
173struct generate_unary_typelist {};
174
175// Partially specialise the empty cases.
176template <typename T>
177struct generate_unary_typelist<TypeList<>, T> {
178 using type = TypeList<>;
179};
180
181template <typename T>
182struct generate_unary_typelist<T, TypeList<>> {
183 using type = TypeList<>;
184};
185
186// Generate unary container from a Set of parameter types
187template <template <typename...> class Container, typename T, typename... U>
188struct generate_unary_typelist<Container<T>, Set<U...>> {
189 using type = UnaryContainer<Container<T>, Set<U...>>;
190};
191
192// Generate unary container
193template <template <typename...> class Container, typename T, typename... U,
194 typename... Us>
195struct generate_unary_typelist<Container<T>, TypeList<Set<U...>, Us...>> {
196 using type = typename concat<
197 TypeList<typename generate_unary_typelist<Container<T>, Set<U...>>::type>,
198 typename generate_unary_typelist<Container<T>,
199 TypeList<Us...>>::type>::type;
200};
201
202template <typename... Ts>
203struct generate_binary_typelist {};
204
205// Generate binary container from a Set of containers
206template <typename T1, typename T2>
207struct generate_binary_typelist<Set<T1, T2>> {
208 using type = TypeList<BinaryContainer<T1, T2>>;
209};
210
211// Generate binary container from the base case i.e only one element in TypeList
212template <typename S>
213struct generate_binary_typelist<TypeList<S>> {
214 using type = typename Impl::generate_binary_typelist<S>::type;
215};
216
217// Generate binary container by processing each element in TypeList
218template <typename S, typename... Ss>
219struct generate_binary_typelist<TypeList<S, Ss...>> {
220 using type = typename concat<
221 typename Impl::generate_binary_typelist<S>::type,
222 typename Impl::generate_binary_typelist<TypeList<Ss...>>::type>::type;
223};
224
225template <typename... Lists>
226struct generate_binary_typelist_proxy {};
227
228// Process the two TypeLists and generate all possible combinations of the two.
229template <typename... List1, typename... List2>
230struct generate_binary_typelist_proxy<TypeList<List1...>, TypeList<List2...>> {
231 using type =
232 typename Impl::generate_binary_typelist<typename Morpheus::cross_product<
233 TypeList<List1...>, TypeList<List2...>>::type>::type;
234};
235
236} // namespace Impl
237} // namespace Morpheus
239#endif // MORPHEUS_CONTAINERFACTORY_IMPL_HPP
Generic Morpheus interfaces.
Definition: dummy.cpp:24