$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
adjacency_matrix.hh
1 // Copyright (C) 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_UTIL_ADJACENCY_MATRIX_HH
27 # define MLN_UTIL_ADJACENCY_MATRIX_HH
28 
38 
39 # include <mln/core/image/image2d.hh>
40 # include <mln/util/set.hh>
41 # include <mln/util/ord_pair.hh>
42 # include <mln/trait/value_.hh>
43 # include <mln/metal/converts_to.hh>
44 # include <mln/debug/println.hh>
45 
46 
47 namespace mln
48 {
49 
50  namespace util
51  {
52 
53  namespace internal
54  {
55 
56  // Implementation for low quantification.
57 
58  template <typename V, typename Q>
60  {
63 
65  adjacency_matrix_impl_selector(const V& nelements);
66 
68  void add(const V& e1, const V& e2);
69 
71  void remove(const V& e1, const V& e2);
72 
74  void clear();
75 
77  bool are_adjacent(const V& e1, const V& e2) const;
78 
80  std::ostream& print_data_(std::ostream& ostr) const;
81 
82  protected:
84  };
85 
86 
87  // Implementation for high quantification.
88 
89  template <typename V>
90  struct adjacency_matrix_impl_selector<V, metal::bool_<false> >
91  {
94 
96  adjacency_matrix_impl_selector(const V& nelements);
97 
99  void add(const V& e1, const V& e2);
100 
102  void remove(const V& e1, const V& e2);
103 
105  void clear();
106 
108  bool are_adjacent(const V& e1, const V& e2) const;
109 
111  std::ostream& print_data_(std::ostream& ostr) const;
112 
113  protected:
115 
116 # ifndef NDEBUG
117  unsigned nelements_;
118 # endif // ! NDEBUG
119  };
120 
121 
122  } // end of namespace mln::util::internal
123 
124 
134  //
135  template <typename V = def::coord>
137  : private mlc_converts_to(V,unsigned)::check_t,
138  public internal::adjacency_matrix_impl_selector<V, typename mlc_equal(mln_trait_value_quant(V),trait::value::quant::low)::eval>
139  {
141  impl_t;
142 
143  typedef typename impl_t::adj_t adj_t;
144 
145  public:
148 
151 
154  adjacency_matrix(const V& nelements);
155 
157 
159  const adj_t& hook_data_() const;
160  };
161 
162 
163  // <<
164 
165  template <typename V>
166  std::ostream&
167  operator<<(std::ostream& ostr, const adjacency_matrix<V>& adj);
168 
169 
170 
171 # ifndef MLN_INCLUDE_ONLY
172 
173 
174  namespace internal
175  {
176 
177  // Low quantification.
178 
179  template <typename V, typename Q>
181  : adj_(nelements, nelements)
182  {
183  clear();
184  }
185 
186  template <typename V, typename Q>
187  void
188  adjacency_matrix_impl_selector<V, Q>::add(const V& e1, const V& e2)
189  {
190  mln_precondition(adj_.is_valid());
191  mln_precondition(e1 < adj_.nrows());
192  mln_precondition(e2 < adj_.nrows());
193 
194  if (e1 > e2)
195  opt::at(adj_, e2, e1) = true;
196  else
197  opt::at(adj_, e1, e2) = true;
198  }
199 
200  template <typename V, typename Q>
201  void
202  adjacency_matrix_impl_selector<V, Q>::remove(const V& e1, const V& e2)
203  {
204  mln_precondition(adj_.is_valid());
205  mln_precondition(e1 < adj_.nrows());
206  mln_precondition(e2 < adj_.nrows());
207 
208  if (e1 > e2)
209  opt::at(adj_, e2, e1) = false;
210  else
211  opt::at(adj_, e1, e2) = false;
212  }
213 
214  template <typename V, typename Q>
215  void
216  adjacency_matrix_impl_selector<V, Q>::clear()
217  {
218  mln_precondition(adj_.is_valid());
219  data::fill(adj_, false);
220  }
221 
222  template <typename V, typename Q>
223  bool
224  adjacency_matrix_impl_selector<V, Q>::are_adjacent(const V& e1,
225  const V& e2) const
226  {
227  mln_precondition(adj_.is_valid());
228  mln_precondition(e1 < adj_.nrows());
229  mln_precondition(e2 < adj_.nrows());
230 
231  if (e1 > e2)
232  return opt::at(adj_, e2, e1);
233  return opt::at(adj_, e1, e2);
234  }
235 
236  template <typename V, typename Q>
237  std::ostream&
238  adjacency_matrix_impl_selector<V, Q>::print_data_(std::ostream& ostr) const
239  {
240  mln_precondition(adj_.is_valid());
241  debug::println(adj_);
242  return ostr;
243  }
244 
245 
246 
247 
248  // High quantification.
249 
250  template <typename V>
251  adjacency_matrix_impl_selector<V, metal::bool_<false> >
252  ::adjacency_matrix_impl_selector(const V& nelements)
253  {
254  (void) nelements;
255 # ifndef NDEBUG
256  nelements_ = nelements;
257 # endif // ! NDEBUG
258  }
259 
260  template <typename V>
261  void
262  adjacency_matrix_impl_selector<V, metal::bool_<false> >
263  ::add(const V& e1, const V& e2)
264  {
265  mln_precondition(int(e1) < int(nelements_));
266  mln_precondition(int(e2) < int(nelements_));
267  adj_.insert(make::ord_pair(e1, e2));
268  }
269 
270  template <typename V>
271  void
272  adjacency_matrix_impl_selector<V, metal::bool_<false> >
273  ::remove(const V& e1, const V& e2)
274  {
275  mln_precondition(int(e1) < int(nelements_));
276  mln_precondition(int(e2) < int(nelements_));
277  mln_precondition(adj_.has(make::ord_pair(e1, e2)));
278  adj_.remove(make::ord_pair(e1, e2));
279  }
280 
281  template <typename V>
282  void
283  adjacency_matrix_impl_selector<V, metal::bool_<false> >::clear()
284  {
285  adj_.clear();
286  }
287 
288  template <typename V>
289  bool
290  adjacency_matrix_impl_selector<V, metal::bool_<false> >
291  ::are_adjacent(const V& e1, const V& e2) const
292  {
293  mln_precondition(int(e1) < int(nelements_));
294  mln_precondition(int(e2) < int(nelements_));
295  return adj_.has(make::ord_pair(e1, e2));
296  }
297 
298  template <typename V>
299  std::ostream&
300  adjacency_matrix_impl_selector<V, metal::bool_<false> >::print_data_(std::ostream& ostr) const
301  {
302  return ostr << adj_;
303  }
304 
305  } // end of namespace mln::internal
306 
307 
308  template <typename V>
309  adjacency_matrix<V>::adjacency_matrix()
310  : impl_t()
311  {
312  }
313 
314 
315  template <typename V>
316  adjacency_matrix<V>::adjacency_matrix(const V& nelements)
317  : impl_t(nelements)
318  {
319  }
320 
321 
322  template <typename V>
323  std::ostream&
324  operator<<(std::ostream& ostr, const adjacency_matrix<V>& adj)
325  {
326  return adj.print_data_(ostr);
327  }
328 
329 
330 # endif // ! MLN_UTIL_ADJACENCY_MATRIX_HH
331 
332  } // end of namespace mln::util
333 
334 } // end of namespace mln
335 
336 
337 #endif // ! MLN_UTIL_ADJACENCY_MATRIX_HH