Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
multiple.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_WIN_MULTIPLE_HH
27 # define MLN_WIN_MULTIPLE_HH
28 
34 
35 # include <mln/core/internal/window_base.hh>
36 # include <mln/core/internal/site_relative_iterator_base.hh>
37 # include <mln/util/array.hh>
38 
39 
40 
41 namespace mln
42 {
43 
44  // Forward declarations.
45  namespace win
46  {
47  template <typename W, typename F> class multiple;
48  template <typename W, typename F> class multiple_qiter;
49  }
50 
51 
52 
53  namespace trait
54  {
55 
56  template <typename W, typename F>
57  struct window_< win::multiple<W,F> >
58  {
59  typedef trait::window::size::fixed size;
60  typedef trait::window::support::regular support;
61  typedef trait::window::definition::n_ary definition;
62  };
63 
64  } // end of namespace trait
65 
66 
67 
68  namespace win
69  {
70 
71 
75  template <typename W, typename F>
76  class multiple
77 
78  : public internal::window_base< mln_dpsite(W), multiple<W,F> >,
79 
80  private metal::and_< mlc_is(mln_trait_window_size(W),
81  trait::window::size::fixed),
82  mlc_is(mln_trait_window_support(W),
83  trait::window::support::regular) >::check_t
84  {
85  public:
86 
87  typedef mln_dpsite(W) dpsite;
88  typedef mln_psite(W) psite;
89  typedef mln_site(W) site;
90 
91  typedef multiple< window<dpsite>, F > regular;
92 
93  typedef multiple_qiter<W,F> fwd_qiter;
94  typedef /* FIXME: */ multiple_qiter<W,F> bkd_qiter;
95  typedef multiple_qiter<W,F> qiter;
96 
97  typedef W element;
98 
99  multiple();
100 
101  multiple(const F& f);
102 
103  bool is_empty() const;
104 
105  void set_window(unsigned i, const W& win);
106 
107  const W& window_(unsigned i) const;
108 
109  unsigned nwindows() const;
110 
111  const F& function() const;
112 
113  unsigned size() const;
114 
115  const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const;
116 
117  bool is_centered() const;
118 
119  bool is_symmetric() const;
120 
121  void sym();
122 
123  unsigned delta() const;
124 
125  private:
126 
127  util::array<W> win_;
128  F f_;
129  };
130 
131 
132  template <typename W, typename F>
133  class multiple_qiter
134  : public internal::site_relative_iterator_base< multiple<W,F>,
135  multiple_qiter<W,F> >
136  {
137  typedef multiple_qiter<W,F> self_;
138  typedef internal::site_relative_iterator_base< multiple<W,F>, self_ > super_;
139  public:
140 
141  multiple_qiter();
142  template <typename Pref>
143  multiple_qiter(const multiple<W,F>& w, const Pref& c);
144 
146  void change_target(const multiple<W,F>& w);
147 
149  template <typename Pref>
150  void init_(const multiple<W,F>& w, const Pref& c);
151 
153  bool is_valid_() const;
154 
156  void invalidate_();
157 
159  void do_start_();
160 
162  void do_next_();
163 
165  mln_psite(W) compute_p_() const;
166 
167  private:
168  unsigned i_;
169  unsigned size_;
170  };
171 
172 
173 
174 # ifndef MLN_INCLUDE_ONLY
175 
176  // win::multiple<W,F>
177 
178  template <typename W, typename F>
179  inline
181  : f_()
182  {
183  }
184 
185  template <typename W, typename F>
186  inline
187  multiple<W,F>::multiple(const F& f)
188  : f_(f)
189  {
190  }
191 
192  template <typename W, typename F>
193  inline
194  bool
195  multiple<W,F>::is_empty() const
196  {
197  return win_.is_empty();
198  }
199 
200  template <typename W, typename F>
201  inline
202  void
203  multiple<W,F>::set_window(unsigned i, const W& win)
204  {
205  mln_precondition(i == win_.nelements());
206  if (i >= 1)
207  mln_precondition(win.size() == win_[0].size());
208  win_.append(win);
209  }
210 
211  template <typename W, typename F>
212  inline
213  const W&
214  multiple<W,F>::window_(unsigned i) const
215  {
216  mln_precondition(i < win_.nelements());
217  return win_[i];
218  }
219 
220  template <typename W, typename F>
221  inline
222  unsigned
223  multiple<W,F>::nwindows() const
224  {
225  return win_.nelements();
226  }
227 
228  template <typename W, typename F>
229  inline
230  const F&
231  multiple<W,F>::function() const
232  {
233  return f_;
234  }
235 
236  template <typename W, typename F>
237  inline
238  unsigned
239  multiple<W,F>::size() const
240  {
241  mln_precondition(win_.nelements() >= 2); // Multiple cannot be just 1 element.
242  unsigned s = win_[0].size();
243  for (unsigned i = 1; i < win_.nelements(); ++i)
244  mln_precondition(win_[i].size() == s);
245  return s;
246  }
247 
248  template <typename W, typename F>
249  inline
250  bool
251  multiple<W,F>::is_centered() const
252  {
253  mln_precondition(win_.nelements() >= 1);
254  for (unsigned i = 0; i < win_.nelements(); ++i)
255  if (! win_[i].is_centered())
256  return false;
257  return true;
258  }
259 
260  template <typename W, typename F>
261  inline
262  bool
263  multiple<W,F>::is_symmetric() const
264  {
265  mln_precondition(win_.nelements() >= 1);
266  for (unsigned i = 0; i < win_.nelements(); ++i)
267  if (! win_[i].is_symmetric())
268  return false;
269  return true;
270  }
271 
272 
273  template <typename W, typename F>
274  inline
275  void
276  multiple<W,F>::sym()
277  {
278  mln_precondition(win_.nelements() >= 1);
279  for (unsigned i = 0; i < win_.nelements(); ++i)
280  win_[i].sym();
281  }
282 
283  template <typename W, typename F>
284  inline
285  unsigned
286  multiple<W,F>::delta() const
287  {
288  mln_precondition(win_.nelements() >= 1);
289  unsigned d = win_[0].delta();
290  for (unsigned i = 1; i < win_.nelements(); ++i)
291  {
292  unsigned d_i = win_[i].delta();
293  if (d_i > d)
294  d = d_i;
295  }
296  return d;
297  }
298 
299  template <typename W, typename F>
300  inline
301  const mln_dpsite(W)&
302  multiple<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const
303  {
304  mln_precondition(f_(p) < win_.nelements());
305  mln_precondition(i < win_[f_(p)].size());
306  return win_[f_(p)].dp(i);
307  }
308 
309 
310  // win::multiple_qiter<W,F>
311 
312  template <typename W, typename F>
313  inline
314  multiple_qiter<W,F>::multiple_qiter()
315  {
316  }
317 
318  template <typename W, typename F>
319  template <typename Pref>
320  inline
321  multiple_qiter<W,F>::multiple_qiter(const multiple<W,F>& w, const Pref& c)
322  {
323  init_(w, c);
324  }
325 
326  template <typename W, typename F>
327  template <typename Pref>
328  inline
329  void
330  multiple_qiter<W,F>::init_(const multiple<W,F>& w, const Pref& c)
331  {
332  this->center_at(c);
333  // We have to first change the center so that 'invalidate' can
334  // work when changing the target.
335  change_target(w);
336  }
337 
338  template <typename W, typename F>
339  inline
340  void
341  multiple_qiter<W,F>::change_target(const multiple<W,F>& w)
342  {
343  size_ = w.size();
344  this->super_::change_target(w);
345  }
346 
347  template <typename W, typename F>
348  inline
349  bool
350  multiple_qiter<W,F>::is_valid_() const
351  {
352  return i_ < size_;
353  }
354 
355  template <typename W, typename F>
356  inline
357  void
358  multiple_qiter<W,F>::invalidate_()
359  {
360  i_ = size_;
361  }
362 
363  template <typename W, typename F>
364  inline
365  void
366  multiple_qiter<W,F>::do_start_()
367  {
368  i_ = 0;
369  }
370 
371  template <typename W, typename F>
372  inline
373  void
374  multiple_qiter<W,F>::do_next_()
375  {
376  ++i_;
377  }
378 
379  template <typename W, typename F>
380  inline
381  mln_psite(W)
382  multiple_qiter<W,F>::compute_p_() const
383  {
384  return *this->c_ + this->s_->ith_dp_around(i_, *this->c_);
385  }
386 
387 # endif // ! MLN_INCLUDE_ONLY
388 
389 
390  } // end of namespace mln::win
391 
392 } // end of namespace mln
393 
394 
395 #endif // ! MLN_WIN_MULTIPLE_HH