Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
label.hh
1 // Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and
2 // Development 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_VALUE_LABEL_HH
28 # define MLN_VALUE_LABEL_HH
29 
33 
34 # include <mln/debug/format.hh>
35 # include <mln/metal/math/pow.hh>
36 # include <mln/trait/value_.hh>
37 # include <mln/value/concept/symbolic.hh>
38 # include <mln/value/internal/value_like.hh>
39 # include <mln/value/internal/convert.hh>
40 # include <mln/value/internal/encoding.hh>
41 
42 # include <mln/value/internal/make_generic_name.hh>
43 
44 namespace mln
45 {
46 
47  // Forward declarations.
48  namespace value {
49  template <unsigned n> struct label;
50  template <unsigned n> struct int_u;
51  }
52 
53  namespace literal {
54  struct zero_t;
55  }
56 
57 
58  namespace trait
59  {
60 
61  template <unsigned n>
62  struct value_< mln::value::label<n> >
63  {
64  private:
65  typedef mln::value::label<n> self_;
66 
67  public:
68 
69  enum {
70  dim = 1,
71  nbits = n,
72  card = mln_value_card_from_(n)
73  };
74 
75  typedef trait::value::nature::symbolic nature;
76  typedef trait::value::kind::label kind;
77  typedef mln_value_quant_from_(card) quant;
78 
79  static const self_ min() { return 0; }
80  static const self_ max() { return mlc_pow_int(2, n) - 1; }
81 
82  static const char* name()
83  {
84  static std::string
85  s = mln::value::internal::make_generic_name("label_", n);
86  return s.c_str();
87  }
88 
89  typedef unsigned comp;
90  };
91 
92  } // end of namespace trait
93 
94 
95  namespace convert
96  {
97 
98  namespace over_load
99  {
100 
101  // int_u -> label.
102  template <unsigned n>
103  void
104  from_to_(const value::int_u<n>& from, value::label<n>& to_);
105 
106  // label -> int_u.
107  template <unsigned n>
108  void
109  from_to_(const value::label<n>& from, value::int_u<n>& to_);
110 
111 
112  // int_u -> label.
113  template <unsigned n, unsigned m>
114  void
115  from_to_(const value::int_u<n>& from, value::label<m>& to_);
116 
117  // label -> bool.
118  template <unsigned n>
119  void
120  from_to_(const value::label<n>& from, bool& to_);
121 
122  // label -> unsigned.
123  template <unsigned n>
124  void
125  from_to_(const value::label<n>& from, unsigned& to_);
126 
127  } // end of namespace mln::convert::over_load
128 
129  } // end of namespace mln::convert
130 
131  namespace value
132  {
133 
134 
139  template <unsigned n>
140  struct label
141  : public Symbolic< label<n> >,
142  public internal::value_like_< unsigned, // Equivalent.
143  typename internal::encoding_unsigned_<n>::ret, // Enc.
144  int, // Interoperation.
145  label<n> > // Exact.
146 
147  {
148  public:
150  typedef typename internal::encoding_unsigned_<n>::ret enc;
151 
153  label();
154 
156  label(unsigned i);
157 
159  label(const literal::zero_t& v);
160 
162  operator unsigned() const;
163 
165  label<n>& operator=(unsigned i);
166 
169 
171  label<n>& operator++();
172 
174  label<n>& operator--();
175 
177  label<n> next() const;
178 
180  label<n> prev() const;
181 
182  };
183 
184 
185  // Safety.
186  template <> struct label<0>;
187  template <> struct label<1>;
188 
196  template <unsigned n>
197  std::ostream& operator<<(std::ostream& ostr, const label<n>& l);
198 
199 
200  } // end of namespace mln::value
201 
202 
203 # ifndef MLN_INCLUDE_ONLY
204 
205 
206  namespace convert
207  {
208 
209  namespace over_load
210  {
211 
212  // int_u -> label.
213  template <unsigned n>
214  inline
215  void
216  from_to_(const value::int_u<n>& from, value::label<n>& to_)
217  {
218  to_ = from;
219  }
220 
221  // label -> int_u.
222  template <unsigned n>
223  void
224  from_to_(const value::label<n>& from, value::int_u<n>& to_)
225  {
226  to_ = from;
227  }
228 
229 
230  // int_u<n> -> label<m> with n < m.
231  template <unsigned n, unsigned m>
232  inline
233  void
234  from_to_(const value::int_u<n>& from, value::label<m>& to_)
235  {
236  enum { valid = n < m };
237  metal::bool_<valid>::check();
238  to_ = from;
239  }
240 
241  // int_u<n> -> bool
242  template <unsigned n>
243  inline
244  void
245  from_to_(const value::label<n>& from, bool& to_)
246  {
247  to_ = (from != 0u);
248  }
249 
250  // int_u<n> -> unsigned
251  template <unsigned n>
252  inline
253  void
254  from_to_(const value::label<n>& from, unsigned& to_)
255  {
256  to_ = from;
257  }
258 
259 
260  } // end of namespace mln::convert::over_load
261 
262  } // end of namespace mln::convert
263 
264 
265 
266  namespace value
267  {
268 
269  template <unsigned n>
270  inline
272  {
273  }
274 
275  template <unsigned n>
276  inline
277  label<n>::label(unsigned i)
278  {
279  this->v_ = enc(i);
280  }
281 
282  template <unsigned n>
283  inline
285  {
286  this->v_ = 0;
287  }
288 
289  template <unsigned n>
290  inline
291  label<n>::operator unsigned() const
292  {
293  return this->to_enc();
294  }
295 
296  template <unsigned n>
297  inline
298  label<n>&
300  {
301  mln_precondition(i <= mln_max(enc));
302  this->v_ = enc(i);
303  return *this;
304  }
305 
306  template <unsigned n>
307  inline
308  label<n>&
310  {
311  this->v_ = 0;
312  return *this;
313  }
314 
315  template <unsigned n>
316  inline
317  label<n>&
319  {
320  mln_precondition(this->v_ < mln_max(enc));
321  ++this->v_;
322  return *this;
323  }
324 
325  template <unsigned n>
326  inline
327  label<n>&
329  {
330  mln_precondition(this->v_ != 0);
331  --this->v_;
332  return *this;
333  }
334 
335  template <unsigned n>
336  inline
337  label<n>
339  {
340  return label<n>(this->v_ + 1);
341  }
342 
343  template <unsigned n>
344  inline
345  label<n>
347  {
348  return label<n>(this->v_ - 1);
349  }
350 
351  template <unsigned n>
352  inline
353  std::ostream& operator<<(std::ostream& ostr, const label<n>& i)
354  {
355  return ostr << debug::format(i.to_equiv());
356  }
357 
358  } // end of namespace mln::value
359 
360 
361 # endif // ! MLN_INCLUDE_ONLY
362 
363 } // end of namespace mln
364 
365 
366 #endif // ! MLN_VALUE_LABEL_HH