Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
mln/core/concept/site_set.hh
1 // Copyright (C) 2007, 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_CORE_CONCEPT_SITE_SET_HH
27 # define MLN_CORE_CONCEPT_SITE_SET_HH
28 
34 
35 # include <set>
36 
37 # include <mln/core/concept/site_iterator.hh>
38 # include <mln/trait/site_sets.hh>
39 # include <mln/metal/not_equal.hh>
40 # include <mln/metal/is_a.hh>
41 # include <mln/metal/is_unqualif.hh>
42 # include <mln/util/ord.hh>
43 
44 
45 namespace mln
46 {
47 
48  // Forward declaration.
49  template <typename E> struct Site_Set;
50 
51 
53  template <>
54  struct Site_Set<void>
55  {
56  typedef Object<void> super;
57  };
58 
59 
64  template <typename E>
65  struct Site_Set : public Object<E>
66  {
67  typedef Site_Set<void> category;
68 
69  /*
70  typedef element;
71 
72  typedef site;
73  typedef psite;
74 
75  typedef fwd_piter;
76  typedef bkd_piter;
77 
78  bool has(const psite& p) const;
79  bool is_valid() const;
80 
81  std::size_t memory_size() const;
82  */
83 
84  protected:
85  Site_Set();
86  };
87 
88 
89 
90  namespace convert
91  {
92 
93  namespace over_load
94  {
95 
96  template <typename S, typename P, typename C_>
97  void
98  from_to_(const Site_Set<S>& from, std::set<P,C_>& to);
99 
100  template <typename P, typename C_, typename S>
101  void
102  from_to_(const std::set<P,C_>& from, Site_Set<S>& to);
103 
104  } // end of namespace mln::convert::over_load
105 
106  } // end of namespace mln::convert
107 
108 
109 
110  namespace trait
111  {
112 
113  template <typename S>
114  struct set_unary_< op::ord, Site_Set, S >
115  {
116  // No definition here.
117 
118  // That prevents from calling the inclusion operator ("op<")
119  // which is clearly not the expected ordering...
120 
121  // Consequently site sets have to define the way they are
122  // ordered.
123  };
124 
125  } // end of namespace mln::trait
126 
127 
128 
129 # ifndef MLN_INCLUDE_ONLY
130 
131 
132  namespace convert
133  {
134 
135  namespace over_load
136  {
137 
138  template <typename S, typename P, typename C_>
139  inline
140  void
141  from_to_(const Site_Set<S>& from_, std::set<P,C_>& to)
142  {
143  mlc_converts_to(mln_psite(S), P)::check();
144  const S& from = exact(from_);
145  to.clear();
146  mln_piter(S) p(from);
147  for_all(p)
148  to.insert(p);
149  }
150 
151 
152  template <typename P, typename C_, typename S>
153  inline
154  void
155  from_to_(const std::set<P,C_>& from, Site_Set<S>& to_)
156  {
157  mlc_converts_to(P, mln_i_element(S))::check();
158  S& to = exact(to_);
159  to.clear();
160  for (typename std::set<P>::const_iterator i = from.begin();
161  i != from.end();
162  ++i)
163  to.insert(*i);
164  }
165 
166  } // end of namespace mln::convert::over_load
167 
168  } // end of namespace mln::convert
169 
170 
171  namespace internal
172  {
173 
174  // nsites: known or unknown.
175 
176  template <typename trait_nsites, typename E>
177  struct site_set_nsites_check
178  {
179  static void run() { /* No requirement. */ }
180  };
181 
182  template <typename E>
183  struct site_set_nsites_check< mln::trait::site_set::nsites::known, E >
184  {
185  static void run()
186  {
187  unsigned (E::*m)() const = & E::nsites;
188  m = 0;
189  }
190  };
191 
192  // bbox: unknown, lazy, or straight.
193 
194  template <typename trait_bbox, typename E>
195  struct site_set_bbox_check
196  {
197  static void run()
198  {
199  typedef typename E::q_box q_box;
200  q_box (E::*m)() const = & E::bbox;
201  m = 0;
202  }
203  };
204 
205  template <typename E>
206  struct site_set_bbox_check< mln::trait::site_set::bbox::unknown, E >
207  {
208  static void run() { /* No requirement. */ }
209  };
210 
211  // contents: fixed, growing, or free.
212 
213  template <typename trait_contents, typename E>
214  struct site_set_contents_check;
215 
216  template <typename E>
217  struct site_set_contents_check< mln::trait::site_set::contents::fixed, E >
218  {
219  static void run() { /* No requirement. */ }
220  };
221 
222  template <typename E>
223  struct site_set_contents_check< mln::trait::site_set::contents::growing, E >
224  {
225  static void run()
226  {
227  typedef typename E::i_element i_element;
228  mlc_equal(mlc_unqualif(i_element), i_element)::check();
229  void (E::*m1)(const i_element&) = & E::insert;
230  m1 = 0;
231  void (E::*m2)() = & E::clear;
232  m2 = 0;
233  }
234  };
235 
236  template <typename E>
237  struct site_set_contents_check< mln::trait::site_set::contents::free, E >
238  {
239  static void run()
240  {
241  typedef typename E::i_element i_element;
242  mlc_equal(mlc_unqualif(i_element), i_element)::check();
243  void (E::*m1)(const i_element&) = & E::insert;
244  m1 = 0;
245  typedef typename E::r_element r_element;
246  mlc_equal(mlc_unqualif(r_element), r_element)::check();
247  void (E::*m2)(const r_element&) = & E::remove;
248  m2 = 0;
249  void (E::*m3)() = & E::clear;
250  m3 = 0;
251  }
252  };
253 
254  } // end of namespace mln::internal
255 
256 
257  // fwd decl
258  template <typename P> struct box_;
259 
260  template <typename E>
261  inline
262  Site_Set<E>::Site_Set()
263  {
264  // Check properties.
265  mlc_not_equal( mln_trait_site_set_nsites(E), mln::trait::undef )::check();
266  mlc_not_equal( mln_trait_site_set_bbox(E), mln::trait::undef )::check();
267  mlc_not_equal( mln_trait_site_set_contents(E), mln::trait::undef )::check();
268  mlc_not_equal( mln_trait_site_set_arity(E), mln::trait::undef )::check();
269  // FIXME: also test something like
270  // mlc_is_a( mln_trait_site_set_nsites(E), mln::trait::site_set::nsites::any )::check();
271 
272  // Check associated types.
273  typedef mln_element(E) element;
274  mlc_is_unqualif(element)::check();
275  typedef mln_site(E) site;
276  typedef mln_psite(E) psite;
277  typedef mln_piter(E) piter;
278  typedef mln_fwd_piter(E) fwd_piter;
279  typedef mln_bkd_piter(E) bkd_piter;
280 
281  // Check methods.
282  bool (E::*m1)(const psite& p) const = & E::has;
283  m1 = 0;
284  bool (E::*m2)() const = & E::is_valid;
285  m2 = 0;
286  std::size_t (E::*m3)() const = & E::memory_size;
287  m3 = 0;
288 
289  // Check methods depending upon properties.
290  internal::site_set_nsites_check < mln_trait_site_set_nsites(E), E >::run();
291  internal::site_set_bbox_check < mln_trait_site_set_bbox(E), E >::run();
292  internal::site_set_contents_check< mln_trait_site_set_contents(E), E >::run();
293  }
294 
295 # endif // ! MLN_INCLUDE_ONLY
296 
297 } // end of namespace mln
298 
299 
300 # include <mln/core/site_set/operators.hh>
301 # include <mln/core/routine/ops.hh>
302 
303 
304 #endif // ! MLN_CORE_CONCEPT_SITE_SET_HH