Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
multiple_size.hh
1 // Copyright (C) 2008, 2009, 2011 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_WIN_MULTIPLE_SIZE_HH
28 # define MLN_WIN_MULTIPLE_SIZE_HH
29 
35 
36 # include <mln/core/internal/window_base.hh>
37 # include <mln/core/internal/site_relative_iterator_base.hh>
38 # include <mln/util/array.hh>
39 # include <mln/metal/ands.hh>
40 
41 
42 
43 namespace mln
44 {
45 
46  // Forward declarations.
47  namespace win
48  {
49  template <unsigned n, typename W, typename F> class multiple_size;
50  template <unsigned n, typename W, typename F> class multiple_size_qiter;
51  }
52 
53 
54 
55  namespace trait
56  {
57 
58  template <unsigned n, typename W, typename F>
59  struct window_< win::multiple_size<n,W,F> >
60  {
61  typedef trait::window::size::unknown size;
62  typedef trait::window::support::regular support;
63  typedef trait::window::definition::n_ary definition;
64  };
65 
66  } // end of namespace trait
67 
68 
69 
70  namespace win
71  {
72 
76  //
77  template <unsigned n, typename W, typename F>
79 
80  : public internal::window_base< mln_dpsite(W), multiple_size<n,W,F> >,
81 
82  private metal::ands< mlc_bool(n > 1),
83  mlc_is(mln_trait_window_size(W),
84  trait::window::size::fixed),
85  mlc_is(mln_trait_window_support(W),
86  trait::window::support::regular) >::check_t
87  {
88  public:
89 
90  typedef mln_dpsite(W) dpsite;
91  typedef mln_psite(W) psite;
92  typedef mln_site(W) site;
93 
95 
96  typedef multiple_size_qiter<n,W,F> fwd_qiter;
97  typedef multiple_size_qiter<n,W,F> bkd_qiter;
98  typedef multiple_size_qiter<n,W,F> qiter;
99 
100  typedef W element;
101 
102  multiple_size();
103 
104  multiple_size(const F& f);
105 
106  bool is_empty() const;
107 
108  void set_window(unsigned i, const W& win);
109 
110  const W& window_(unsigned i) const;
111 
112  unsigned nwindows() const;
113 
114  const F& function() const;
115 
116  unsigned size_around(const mln_psite(W)& p) const;
117 
118  const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p) const;
119 
120  bool is_centered() const;
121 
122  bool is_symmetric() const;
123 
124  void sym();
125 
126  unsigned delta() const;
127 
128  private:
129 
130  util::array<W> win_;
131  F f_;
132  };
133 
134 
135  template <unsigned n, typename W, typename F>
136  class multiple_size_qiter
137  : public internal::site_relative_iterator_base< multiple_size<n,W,F>,
138  multiple_size_qiter<n,W,F> >
139  {
140  typedef multiple_size_qiter<n,W,F> self_;
141  typedef internal::site_relative_iterator_base< multiple_size<n,W,F>, self_ > super_;
142  public:
143 
144  multiple_size_qiter();
145 
146  template <typename P>
147  multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c);
148 
149  template <typename P>
150  void init_(const multiple_size<n,W,F>& w, const P& 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  int i_;
169  int size_() const;
170  };
171 
172 
173 
174 # ifndef MLN_INCLUDE_ONLY
175 
176  // win::multiple_size<n,W,F>
177 
178  template <unsigned n, typename W, typename F>
179  inline
181  : f_()
182  {
183  }
184 
185  template <unsigned n, typename W, typename F>
186  inline
187  multiple_size<n,W,F>::multiple_size(const F& f)
188  : f_(f)
189  {
190  }
191 
192  template <unsigned n, typename W, typename F>
193  inline
194  bool
195  multiple_size<n,W,F>::is_empty() const
196  {
197  return win_.is_empty();
198  }
199 
200  template <unsigned n, typename W, typename F>
201  inline
202  void
203  multiple_size<n,W,F>::set_window(unsigned i, const W& win)
204  {
205  mln_precondition(i == win_.nelements());
206  (void) i;
207  win_.append(win);
208  }
209 
210  template <unsigned n, typename W, typename F>
211  inline
212  const W&
213  multiple_size<n,W,F>::window_(unsigned i) const
214  {
215  mln_precondition(i < win_.nelements());
216  return win_[i];
217  }
218 
219  template <unsigned n, typename W, typename F>
220  inline
221  unsigned
222  multiple_size<n,W,F>::nwindows() const
223  {
224  return win_.nelements();
225  }
226 
227  template <unsigned n, typename W, typename F>
228  inline
229  const F&
230  multiple_size<n,W,F>::function() const
231  {
232  return f_;
233  }
234 
235  template <unsigned n, typename W, typename F>
236  inline
237  bool
238  multiple_size<n,W,F>::is_centered() const
239  {
240  mln_precondition(win_.nelements() >= 1);
241  for (unsigned i = 0; i < win_.nelements(); ++i)
242  if (! win_[i].is_centered())
243  return false;
244  return true;
245  }
246 
247  template <unsigned n, typename W, typename F>
248  inline
249  bool
250  multiple_size<n,W,F>::is_symmetric() const
251  {
252  mln_precondition(win_.nelements() >= 1);
253  for (unsigned i = 0; i < win_.nelements(); ++i)
254  if (! win_[i].is_symmetric())
255  return false;
256  return true;
257  }
258 
259  template <unsigned n, typename W, typename F>
260  inline
261  void
262  multiple_size<n,W,F>::sym()
263  {
264  mln_precondition(win_.nelements() >= 1);
265  for (unsigned i = 0; i < win_.nelements(); ++i)
266  win_[i].sym();
267  }
268 
269  template <unsigned n, typename W, typename F>
270  inline
271  unsigned
272  multiple_size<n,W,F>::delta() const
273  {
274  mln_precondition(win_.nelements() >= 1);
275  unsigned d = win_[0].delta();
276  for (unsigned i = 1; i < win_.nelements(); ++i)
277  {
278  unsigned d_i = win_[i].delta();
279  if (d_i > d)
280  d = d_i;
281  }
282  return d;
283  }
284 
285  template <unsigned n, typename W, typename F>
286  inline
287  unsigned
288  multiple_size<n,W,F>::size_around(const mln_psite(W)& p) const
289  {
290  mln_precondition(win_.nelements() >= 2);
291  mln_precondition(f_(p) < win_.nelements());
292  return win_[f_(p)].size();
293  }
294 
295  template <unsigned n, typename W, typename F>
296  inline
297  const mln_dpsite(W)&
298  multiple_size<n,W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const
299  {
300  mln_precondition(win_.nelements() >= 2);
301  mln_precondition(f_(p) < win_.nelements());
302  mln_precondition(i < win_[f_(p)].size());
303  return win_[f_(p)].dp(i);
304  }
305 
306 
307  // win::multiple_size_qiter<n,W,F>
308 
309  template <unsigned n, typename W, typename F>
310  inline
311  multiple_size_qiter<n,W,F>::multiple_size_qiter()
312  {
313  }
314 
315  template <unsigned n, typename W, typename F>
316  template <typename P>
317  inline
318  multiple_size_qiter<n,W,F>::multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c)
319  {
320  init_(w, c);
321  }
322 
323  template <unsigned n, typename W, typename F>
324  template <typename P>
325  inline
326  void
327  multiple_size_qiter<n,W,F>::init_(const multiple_size<n,W,F>& w, const P& c)
328  {
329  this->center_at(c);
330  // We have to first change the center so that 'invalidate' can
331  // work when changing the target.
332  this->change_target(w);
333  }
334 
335 
336  template <unsigned n, typename W, typename F>
337  inline
338  bool
339  multiple_size_qiter<n,W,F>::is_valid_() const
340  {
341  return i_ != -1 && i_ < size_();
342  }
343 
344  template <unsigned n, typename W, typename F>
345  inline
346  void
347  multiple_size_qiter<n,W,F>::invalidate_()
348  {
349  i_ = -1;
350  }
351 
352  template <unsigned n, typename W, typename F>
353  inline
354  void
355  multiple_size_qiter<n,W,F>::do_start_()
356  {
357  i_ = 0;
358  }
359 
360  template <unsigned n, typename W, typename F>
361  inline
362  void
363  multiple_size_qiter<n,W,F>::do_next_()
364  {
365  ++i_;
366  }
367 
368  template <unsigned n, typename W, typename F>
369  inline
370  mln_psite(W)
371  multiple_size_qiter<n,W,F>::compute_p_() const
372  {
373  return *this->c_ + this->s_->ith_dp_around(i_, *this->c_);
374  }
375 
376  template <unsigned n, typename W, typename F>
377  inline
378  int
379  multiple_size_qiter<n,W,F>::size_() const
380  {
381  return int(this->s_->size_around(*this->c_));
382  }
383 
384 # endif // ! MLN_INCLUDE_ONLY
385 
386 
387  } // end of namespace mln::win
388 
389 } // end of namespace mln
390 
391 
392 #endif // ! MLN_WIN_MULTIPLE_SIZE_HH