$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
tuple.hh
1 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_ACCU_TUPLE_HH
28 # define MLN_ACCU_TUPLE_HH
29 
33 
34 
35 # include <utility>
36 
37 # include <mln/core/concept/meta_accumulator.hh>
38 
39 # include <mln/accu/internal/base.hh>
40 # include <mln/metal/is_a.hh>
41 # include <mln/metal/unqualif.hh>
42 
43 # include <boost/tuple/tuple.hpp>
44 # include <boost/preprocessor/iteration/local.hpp>
45 # include <boost/preprocessor/repetition/repeat.hpp>
46 # include <boost/preprocessor/repetition/enum_params.hpp>
47 # include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
48 
49 # define RESULT_ACCU(z, n, data) BOOST_PP_COMMA_IF(n) typename internal::tuplehelper_<T ## n>::result
50 # define ARG(z, n, data) BOOST_PP_COMMA_IF(n) const T ## n& p ## n = T ## n()
51 # define BOOST_PP_LOCAL_MACRO(n) typedef mln_accu_with(T ## n, A) AT ## n;
52 # define BOOST_PP_LOCAL_LIMITS (0, 9)
53 
54 namespace mln
55 {
56 
57  namespace accu
58  {
59 
60  namespace internal
61  {
62  // Fwd decl.
63  template <typename T> struct tuplehelper_;
64  template <unsigned n, typename T> struct tuplehelper;
65  }
66 
68 
73  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(10, typename T, boost::tuples::null_type)>
74  struct tuple
75  : public mln::accu::internal::base< boost::tuple< BOOST_PP_REPEAT(10, RESULT_ACCU, Le Ricard ya que ca de vrai !) >, tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)> >
76  {
77  typedef A argument;
78 
79  typedef boost::tuple< BOOST_PP_REPEAT(10, RESULT_ACCU, Le Ricard ya que ca de vrai !)> res;
80  typedef boost::tuple< BOOST_PP_ENUM_PARAMS(10, T)> intern;
82 
83  tuple();
84 
87  void init();
88  void take_as_init_(const argument& t);
89  void take(const argument& t);
90  void take(const tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)>& other);
92 
94  res to_result() const;
95 
98  bool is_valid() const;
99 
100  protected:
101 
103  };
104 
105  namespace meta
106  {
107 
109 
110  template <unsigned n, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(10, typename T, boost::tuples::null_type)>
111  struct tuple : public Meta_Accumulator< tuple<n, BOOST_PP_ENUM_PARAMS(10, T)> >
112  {
113  template <typename A>
114  struct with
115  {
116 # include BOOST_PP_LOCAL_ITERATE()
117 
119  };
120  };
121 
122  }
123 
124 
125 # ifndef MLN_INCLUDE_ONLY
126 
127  namespace internal
128  {
129 
130  template <typename T>
131  struct tuplehelper_
132  {
133  typedef typename T::result result;
134  };
135 
136  template <>
137  struct tuplehelper_<boost::tuples::null_type>
138  {
139  typedef boost::tuples::null_type result;
140  };
141 
142  template <unsigned n, typename T>
143  struct tuplehelper
144  {
145  static void init(typename T::intern& a)
146  {
147  boost::get<n - 1>(a).init();
148  tuplehelper<n - 1, T>::init(a);
149  }
150 
151  static void take_as_init_(typename T::intern& a, const typename T::argument& argument)
152  {
153  boost::get<n - 1>(a).take_as_init_(argument);
154  tuplehelper<n - 1, T>::take_as_init_(a, argument);
155  }
156 
157  static void take(typename T::intern& a, const typename T::argument& argument)
158  {
159  boost::get<n - 1>(a).take(argument);
160  tuplehelper<n - 1, T>::take(a, argument);
161  }
162 
163  static void take(typename T::intern& a, const typename T::intern& other)
164  {
165  boost::get<n - 1>(a).take(boost::get<n - 1>(other));
166  tuplehelper<n - 1, T>::take(a, other);
167  }
168 
169  static void to_result(const typename T::intern& a, typename T::result& res)
170  {
171  boost::get<n - 1>(res) = boost::get<n - 1>(a).to_result();
172  tuplehelper<n - 1, T>::to_result(a, res);
173  }
174  };
175 
176  template <typename T>
177  struct tuplehelper<0, T>
178  {
179  static void init(typename T::intern&) {}
180  static void take_as_init_(typename T::intern&, const typename T::argument&) {}
181  static void take(typename T::intern&, const typename T::argument) {}
182  static void take(typename T::intern&, const typename T::intern&) {}
183  static void to_result(const typename T::intern&, typename T::result&) {}
184  };
185  }
186 
187  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
188  inline
189  tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::tuple()
190  {
191  init();
192  }
193 
194  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
195  inline
196  void
197  tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::init()
198  {
199  internal::tuplehelper<n, self>::init(this->a_);
200  }
201 
202  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
203  inline
204  void
205  tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take_as_init_(const argument& t)
206  {
207  internal::tuplehelper<n, self>::take_as_init_(this->a_, t);
208  }
209 
210  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
211  inline
212  void
213  tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take(const argument& t)
214  {
216  }
217 
218  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
219  inline
220  void
221  tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take(const tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >& other)
222  {
224  }
225 
226  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
227  inline
228  typename tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::res
229  tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::to_result() const
230  {
231  res tmp;
232  internal::tuplehelper<n, self>::to_result(this->a_, tmp);
233  return tmp;
234  }
235 
236  template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
237  inline
238  bool
239  tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::is_valid() const
240  {
241  return true;
242  }
243 
244 # endif // ! MLN_INCLUDE_ONLY
245 
246  } // end of namespace mln::accu
247 
248 } // end of namespace mln
249 
250 
251 #endif // ! MLN_ACCU_TUPLE_HH