Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
Sacado_TemplateContainer.hpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Sacado Package
5// Copyright (2006) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// This library is free software; you can redistribute it and/or modify
11// it under the terms of the GNU Lesser General Public License as
12// published by the Free Software Foundation; either version 2.1 of the
13// License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23// USA
24// Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25// (etphipp@sandia.gov).
26//
27// ***********************************************************************
28// @HEADER
29
30#ifndef SACADO_TEMPLATE_CONTAINER_HPP
31#define SACADO_TEMPLATE_CONTAINER_HPP
32
33// While this code does not directly use C++11 features, it uses mpl::vector,
34// which does
35#include "Sacado_ConfigDefs.h"
36#ifdef HAVE_SACADO_CXX11
37
38#include "Sacado_mpl_size.hpp"
39#include "Sacado_mpl_find.hpp"
41#include "Sacado_mpl_apply.hpp"
42#include "Sacado_mpl_begin.hpp"
43#include "Sacado_mpl_end.hpp"
44#include "Sacado_mpl_deref.hpp"
45#include "Sacado_mpl_next.hpp"
48
49namespace Sacado {
50
51 namespace Impl {
52
53 // Forward declaration
54 template <typename TypeSeq,
55 typename ObjectT,
56 typename Iter1 = typename mpl::begin<TypeSeq>::type,
57 typename Iter2 =typename mpl::end<TypeSeq>::type>
58 struct TupleSeq;
59
60 // Forward declaration
61 template <typename T,
62 typename TypeSeq,
63 typename ObjectT,
64 typename Iter1 = typename mpl::begin<TypeSeq>::type,
65 typename Iter2 = typename mpl::end<TypeSeq>::type,
66 typename Enabled = void>
67 struct GetTupleSeq;
68
69 } // namespace Impl
70
71
73
95 template <typename TypeSeq, typename ObjectT>
96 class TemplateContainer {
97
99 typedef Impl::TupleSeq<TypeSeq, ObjectT> tuple_type;
100
102 template <typename BuilderOpT>
103 struct BuildObject {
104 tuple_type& objects;
105 const BuilderOpT& builder;
106 BuildObject(tuple_type& objects_,
107 const BuilderOpT& builder_) :
108 objects(objects_), builder(builder_) {}
109 template <typename T> void operator()(T x) const {
110 Impl::GetTupleSeq<T,TypeSeq,ObjectT>::apply(objects) = builder(x);
111 }
112 };
113
114 public:
115
117 typedef TypeSeq types;
118
120 struct DefaultBuilderOp {
121
123 template<class T>
124 typename Sacado::mpl::apply<ObjectT,T>::type operator() (T) const {
125 return typename Sacado::mpl::apply<ObjectT,T>::type();
126 }
127
128 };
129
131 TemplateContainer() {}
132
134 ~TemplateContainer() {}
135
137 template<typename T>
139 return Impl::GetTupleSeq<T,TypeSeq,ObjectT>::apply(objects);
140 }
141
143 template<typename T>
144 const typename Sacado::mpl::apply<ObjectT,T>::type& get() const {
145 return Impl::GetTupleSeq<T,TypeSeq,ObjectT>::apply(objects);
146 }
147
149 template <typename BuilderOpT = DefaultBuilderOp>
150 void build(const BuilderOpT& builder) {
152 BuildObject<BuilderOpT>(objects,builder));
153 }
154
155 private:
156
158 tuple_type objects;
159
160 };
161
162 // Wrap call to mpl::for_each so you don't have to specify the container
163 // or type sequence
164 template <typename TypeSeq, typename ObjectT, typename FunctorT>
165 void container_for_each(TemplateContainer<TypeSeq,ObjectT>& container,
166 const FunctorT& op) {
167 typedef TemplateContainer<TypeSeq,ObjectT> Container;
169 }
170
171 // Wrap call to mpl::for_each so you don't have to specify the container
172 // or type sequence
173 template <typename TypeSeq, typename ObjectT, typename FunctorT>
174 void container_for_each_no_kokkos(TemplateContainer<TypeSeq,ObjectT>& container,
175 const FunctorT& op) {
176 typedef TemplateContainer<TypeSeq,ObjectT> Container;
178 }
179
180 namespace mpl {
181
182 // Give TemplateContainer begin<> and end<> iterators for for_each
183
184 template <typename TypeSeq, typename ObjectT>
185 struct begin< TemplateContainer<TypeSeq,ObjectT> > {
186 typedef typename begin<TypeSeq>::type type;
187 };
188
189 template <typename TypeSeq, typename ObjectT>
190 struct end< TemplateContainer<TypeSeq,ObjectT> > {
191 typedef typename end<TypeSeq>::type type;
192 };
193
194 }
195
196 namespace Impl {
197
198 // Container class to store our tuple sequence
199 template <typename TypeSeq,
200 typename ObjectT,
201 typename Iter1,
202 typename Iter2>
203 struct TupleSeq :
204 TupleSeq<TypeSeq, ObjectT, typename mpl::next<Iter1>::type, Iter2>
205 {
206 typedef typename mpl::apply<ObjectT,
207 typename mpl::deref<Iter1>::type>::type type;
208 type tail;
209 };
210
211 template <typename TypeSeq,
212 typename ObjectT,
213 typename Iter1>
214 struct TupleSeq<TypeSeq, ObjectT, Iter1, Iter1> {};
215
216 // Helper class to get a value out of the tuple sequence from a given type
217 template <typename T,
218 typename TypeSeq,
219 typename ObjectT,
220 typename Iter1,
221 typename Iter2,
222 typename Enabled>
223 struct GetTupleSeq {};
224
225 template <typename T,
226 typename TypeSeq,
227 typename ObjectT,
228 typename Iter1,
229 typename Iter2>
230 struct GetTupleSeq< T,
231 TypeSeq,
232 ObjectT,
233 Iter1,
234 Iter2,
235 typename mpl::enable_if_c<
236 mpl::is_same< T, typename mpl::deref<Iter1>::type
237 >::value
238 >::type > {
239 static typename TupleSeq<TypeSeq,ObjectT,Iter1,Iter2>::type&
240 apply(TupleSeq<TypeSeq,ObjectT,Iter1,Iter2>& t) {
241 return t.tail;
242 }
243
244 static const typename TupleSeq<TypeSeq,ObjectT,Iter1,Iter2>::type&
245 apply(const TupleSeq<TypeSeq,ObjectT,Iter1,Iter2>& t) {
246 return t.tail;
247 }
248 };
249
250 template <typename T,
251 typename TypeSeq,
252 typename ObjectT,
253 typename Iter1,
254 typename Iter2>
255 struct GetTupleSeq< T,
256 TypeSeq,
257 ObjectT,
258 Iter1,
259 Iter2,
260 typename mpl::enable_if_c<
261 !mpl::is_same< T, typename mpl::deref<Iter1>::type
262 >::value
263 >::type > :
264 GetTupleSeq< T, TypeSeq, ObjectT, typename mpl::next<Iter1>::type, Iter2>
265 {};
266
267 template <typename T,
268 typename TypeSeq,
269 typename ObjectT,
270 typename Iter1>
271 struct GetTupleSeq< T, TypeSeq, ObjectT, Iter1, Iter1, void> {};
272
273
274 } // namespace Impl
275
276}
277
278#endif
279#endif
#define T
Definition: Sacado_rad.hpp:573
F::template apply< A1, A2, A3, A4, A5 >::type type