Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator 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>
59  struct adjacency_matrix_impl_selector
60  {
62  typedef image2d<bool> adj_t;
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:
83  adj_t adj_;
84  };
85 
86 
87  // Implementation for high quantification.
88 
89  template <typename V>
90  struct adjacency_matrix_impl_selector<V, metal::bool_<false> >
91  {
93  typedef util::set< util::ord_pair<V> > adj_t;
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:
114  adj_t adj_;
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  {
140  typedef internal::adjacency_matrix_impl_selector<V, typename mlc_equal(mln_trait_value_quant(V),trait::value::quant::low)::eval>
141  impl_t;
142 
143  typedef typename impl_t::adj_t adj_t;
144 
145  public:
153  adjacency_matrix(const V& nelements);
156 
158  const adj_t& hook_data_() const;
159  };
160 
161 
162  // <<
163 
164  template <typename V>
165  std::ostream&
166  operator<<(std::ostream& ostr, const adjacency_matrix<V>& adj);
167 
168 
169 
170 # ifndef MLN_INCLUDE_ONLY
171 
172 
173  namespace internal
174  {
175 
176  // Low quantification.
177 
178  template <typename V, typename Q>
179  adjacency_matrix_impl_selector<V, Q>::adjacency_matrix_impl_selector(const V& nelements)
180  : adj_(nelements, nelements)
181  {
182  clear();
183  }
184 
185  template <typename V, typename Q>
186  void
187  adjacency_matrix_impl_selector<V, Q>::add(const V& e1, const V& e2)
188  {
189  mln_precondition(adj_.is_valid());
190  mln_precondition(e1 < adj_.nrows());
191  mln_precondition(e2 < adj_.nrows());
192 
193  if (e1 > e2)
194  opt::at(adj_, e2, e1) = true;
195  else
196  opt::at(adj_, e1, e2) = true;
197  }
198 
199  template <typename V, typename Q>
200  void
201  adjacency_matrix_impl_selector<V, Q>::remove(const V& e1, const V& e2)
202  {
203  mln_precondition(adj_.is_valid());
204  mln_precondition(e1 < adj_.nrows());
205  mln_precondition(e2 < adj_.nrows());
206 
207  if (e1 > e2)
208  opt::at(adj_, e2, e1) = false;
209  else
210  opt::at(adj_, e1, e2) = false;
211  }
212 
213  template <typename V, typename Q>
214  void
215  adjacency_matrix_impl_selector<V, Q>::clear()
216  {
217  mln_precondition(adj_.is_valid());
218  data::fill(adj_, false);
219  }
220 
221  template <typename V, typename Q>
222  bool
223  adjacency_matrix_impl_selector<V, Q>::are_adjacent(const V& e1,
224  const V& e2) const
225  {
226  mln_precondition(adj_.is_valid());
227  mln_precondition(e1 < adj_.nrows());
228  mln_precondition(e2 < adj_.nrows());
229 
230  if (e1 > e2)
231  return opt::at(adj_, e2, e1);
232  return opt::at(adj_, e1, e2);
233  }
234 
235  template <typename V, typename Q>
236  std::ostream&
237  adjacency_matrix_impl_selector<V, Q>::print_data_(std::ostream& ostr) const
238  {
239  mln_precondition(adj_.is_valid());
240  debug::println(adj_);
241  return ostr;
242  }
243 
244 
245 
246 
247  // High quantification.
248 
249  template <typename V>
250  adjacency_matrix_impl_selector<V, metal::bool_<false> >
251  ::adjacency_matrix_impl_selector(const V& nelements)
252  {
253  (void) nelements;
254 # ifndef NDEBUG
255  nelements_ = nelements;
256 # endif // ! NDEBUG
257  }
258 
259  template <typename V>
260  void
261  adjacency_matrix_impl_selector<V, metal::bool_<false> >
262  ::add(const V& e1, const V& e2)
263  {
264  mln_precondition(int(e1) < int(nelements_));
265  mln_precondition(int(e2) < int(nelements_));
266  adj_.insert(make::ord_pair(e1, e2));
267  }
268 
269  template <typename V>
270  void
271  adjacency_matrix_impl_selector<V, metal::bool_<false> >
272  ::remove(const V& e1, const V& e2)
273  {
274  mln_precondition(int(e1) < int(nelements_));
275  mln_precondition(int(e2) < int(nelements_));
276  mln_precondition(adj_.has(make::ord_pair(e1, e2)));
277  adj_.remove(make::ord_pair(e1, e2));
278  }
279 
280  template <typename V>
281  void
282  adjacency_matrix_impl_selector<V, metal::bool_<false> >::clear()
283  {
284  adj_.clear();
285  }
286 
287  template <typename V>
288  bool
289  adjacency_matrix_impl_selector<V, metal::bool_<false> >
290  ::are_adjacent(const V& e1, const V& e2) const
291  {
292  mln_precondition(int(e1) < int(nelements_));
293  mln_precondition(int(e2) < int(nelements_));
294  return adj_.has(make::ord_pair(e1, e2));
295  }
296 
297  template <typename V>
298  std::ostream&
299  adjacency_matrix_impl_selector<V, metal::bool_<false> >::print_data_(std::ostream& ostr) const
300  {
301  return ostr << adj_;
302  }
303 
304  } // end of namespace mln::internal
305 
306 
307  template <typename V>
309  : impl_t()
310  {
311  }
312 
313 
314  template <typename V>
316  : impl_t(nelements)
317  {
318  }
319 
320 
321  template <typename V>
322  std::ostream&
323  operator<<(std::ostream& ostr, const adjacency_matrix<V>& adj)
324  {
325  return adj.print_data_(ostr);
326  }
327 
328 
329 # endif // ! MLN_UTIL_ADJACENCY_MATRIX_HH
330 
331  } // end of namespace mln::util
332 
333 } // end of namespace mln
334 
335 
336 #endif // ! MLN_UTIL_ADJACENCY_MATRIX_HH