$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
accumulator.hh
1 // Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013 EPITA Research and
2 // Development 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_CORE_CONCEPT_ACCUMULATOR_HH
28 # define MLN_CORE_CONCEPT_ACCUMULATOR_HH
29 
33 
34 # include <mln/core/concept/proxy.hh>
35 # include <mln/metal/fix_return.hh>
36 # include <mln/metal/const.hh>
37 # include <mln/trait/accumulators.hh>
38 
39 
40 namespace mln
41 {
42 
45  template <>
46  struct Accumulator<void>
47  {
48  typedef Proxy<void> super;
49  };
51 
52 
53 
61  template <typename E>
62  struct Accumulator : public Proxy<E>
63  {
65 
66  /*
67  typedef argument;
68  typedef result;
69  typedef q_result;
70 
71  void init();
72  void take(const argument& t);
73  void take(const E& other);
74 
75  q_result to_result() const;
76  operator q_result const;
77 
78  bool is_valid() const;
79  */
80 
88  template <typename T>
89  void take_as_init(const T& t); // 't' is either argument or E.
90 
93  template <typename T>
94  void take_as_init_(const T& t);
96 
97 
105  template <typename T>
106  void take_n_times(unsigned n, const T& t);
107 
110  template <typename T>
111  void take_n_times_(unsigned n, const T& t);
113 
114 
115  protected:
116  Accumulator();
117  };
118 
119 
124  template <typename A>
125  void
126  from_to_(const Accumulator<A>& from, mln_result(A)& to);
127 
128 
129 # ifndef MLN_INCLUDE_ONLY
130 
131  // Accumulator<E>
132 
133  template <typename E>
134  inline
136  {
137  typedef mln_argument(E) argument;
138  typedef mln_result(E) result;
139  typedef mln_q_result(E) q_result;
140 
141  void (E::*m1)() = & E::init;
142  (void) m1;
143  void (E::*m2)(const argument&) = & E::take;
144  (void) m2;
145  void (E::*m3)(const E&) = & E::take;
146  (void) m3;
147 
148  q_result (E::*m4)() const = & E::to_result;
149  (void) m4;
150  q_result (E::*m5)() const = & E::operator q_result;
151  (void) m5;
152 
153  bool (E::*m6)() const = & E::is_valid;
154  (void) m6;
155  }
156 
157 
158  // take_as_init
159 
160  template <typename E>
161  template <typename T>
162  void
163  Accumulator<E>::take_as_init(const T& t)
164  {
165  typedef mln_exact(T) T_;
166  typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
167  typedef mlc_converts_to(T_, E) t_is_accumulator;
168  mlc_or(t_is_argument, t_is_accumulator)::check();
169 
170  // Dispatch.
171  exact(this)->take_as_init_(t);
172  }
173 
174  template <typename E>
175  template <typename T>
176  void
177  Accumulator<E>::take_as_init_(const T& t)
178  {
179  // Default impl.
180  exact(this)->init();
181  exact(this)->take(t);
182  }
183 
184 
185  // take n times
186 
187  template <typename E>
188  template <typename T>
189  void
190  Accumulator<E>::take_n_times(unsigned n, const T& t)
191  {
192  typedef mln_exact(T) T_;
193  typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
194  typedef mlc_converts_to(T_, E) t_is_accumulator;
195  mlc_or(t_is_argument, t_is_accumulator)::check();
196 
197  if (n == 0u)
198  return;
199 
200  // Dispatch.
201  exact(this)->take_n_times_(n, t);
202  }
203 
204  template <typename E>
205  template <typename T>
206  void
207  Accumulator<E>::take_n_times_(unsigned n, const T& t)
208  {
209  // Default impl.
210  for (unsigned i = 0; i < n; ++i)
211  exact(this)->take(t);
212  }
213 
214 
215  // Conversions
216 
217  template <typename A>
218  void
219  from_to_(const Accumulator<A>& from_, mln_result(A)& to)
220  {
221  const A& from = exact(from_);
222  if (from.is_valid())
223  to = from.to_result();
224  else
225  to = mln_result(A)();
226  }
227 
228 
229 # endif // ! MLN_INCLUDE_ONLY
230 
231 } // end of namespace mln
232 
233 
234 #endif // ! MLN_CORE_CONCEPT_ACCUMULATOR_HH