Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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"
40 #include "Sacado_mpl_for_each.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"
46 #include "Sacado_mpl_enable_if.hpp"
47 #include "Sacado_mpl_is_same.hpp"
48 
49 namespace 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>
138  typename Sacado::mpl::apply<ObjectT,T>::type& get() {
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
void f()
F::template apply< A1, A2, A3, A4, A5 >::type type
#define T
Definition: Sacado_rad.hpp:573
void
Definition: uninit.c:96