00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_VALUE_LABEL_HH
00028 # define MLN_VALUE_LABEL_HH
00029
00033
00034 # include <mln/debug/format.hh>
00035 # include <mln/metal/math/pow.hh>
00036 # include <mln/trait/value_.hh>
00037 # include <mln/value/concept/symbolic.hh>
00038 # include <mln/value/internal/value_like.hh>
00039 # include <mln/value/internal/convert.hh>
00040 # include <mln/value/internal/encoding.hh>
00041
00042 # include <mln/value/internal/make_generic_name.hh>
00043
00044 namespace mln
00045 {
00046
00047
00048 namespace value {
00049 template <unsigned n> struct label;
00050 template <unsigned n> struct int_u;
00051 }
00052
00053 namespace literal {
00054 struct zero_t;
00055 }
00056
00057
00058 namespace trait
00059 {
00060
00061 template <unsigned n>
00062 struct value_< mln::value::label<n> >
00063 {
00064 private:
00065 typedef mln::value::label<n> self_;
00066
00067 public:
00068
00069 enum {
00070 dim = 1,
00071 nbits = n,
00072 card = mln_value_card_from_(n)
00073 };
00074
00075 typedef trait::value::nature::symbolic nature;
00076 typedef trait::value::kind::label kind;
00077 typedef mln_value_quant_from_(card) quant;
00078
00079 static const self_ min() { return 0; }
00080 static const self_ max() { return mlc_pow_int(2, n) - 1; }
00081
00082 static const char* name()
00083 {
00084 static std::string
00085 s = mln::value::internal::make_generic_name("label_", n);
00086 return s.c_str();
00087 }
00088
00089 typedef unsigned comp;
00090 };
00091
00092 }
00093
00094
00095 namespace convert
00096 {
00097
00098 namespace over_load
00099 {
00100
00101
00102 template <unsigned n>
00103 void
00104 from_to_(const value::int_u<n>& from, value::label<n>& to_);
00105
00106
00107 template <unsigned n>
00108 void
00109 from_to_(const value::label<n>& from, value::int_u<n>& to_);
00110
00111
00112
00113 template <unsigned n, unsigned m>
00114 void
00115 from_to_(const value::int_u<n>& from, value::label<m>& to_);
00116
00117
00118 template <unsigned n>
00119 void
00120 from_to_(const value::label<n>& from, bool& to_);
00121
00122
00123 template <unsigned n>
00124 void
00125 from_to_(const value::label<n>& from, unsigned& to_);
00126
00127 }
00128
00129 }
00130
00131 namespace value
00132 {
00133
00134
00139 template <unsigned n>
00140 struct label
00141 : public Symbolic< label<n> >,
00142 public internal::value_like_< unsigned,
00143 typename internal::encoding_unsigned_<n>::ret,
00144 int,
00145 label<n> >
00146
00147 {
00148 public:
00150 typedef typename internal::encoding_unsigned_<n>::ret enc;
00151
00153 label();
00154
00156 label(unsigned i);
00157
00159 label(const literal::zero_t& v);
00160
00162 operator unsigned() const;
00163
00165 label<n>& operator=(unsigned i);
00166
00168 label<n>& operator=(const literal::zero_t& v);
00169
00171 label<n>& operator++();
00172
00174 label<n>& operator--();
00175
00177 label<n> next() const;
00178
00180 label<n> prev() const;
00181
00182 };
00183
00184
00185
00186 template <> struct label<0>;
00187 template <> struct label<1>;
00188
00196 template <unsigned n>
00197 std::ostream& operator<<(std::ostream& ostr, const label<n>& l);
00198
00199
00200 }
00201
00202
00203 # ifndef MLN_INCLUDE_ONLY
00204
00205
00206 namespace convert
00207 {
00208
00209 namespace over_load
00210 {
00211
00212
00213 template <unsigned n>
00214 inline
00215 void
00216 from_to_(const value::int_u<n>& from, value::label<n>& to_)
00217 {
00218 to_ = from;
00219 }
00220
00221
00222 template <unsigned n>
00223 void
00224 from_to_(const value::label<n>& from, value::int_u<n>& to_)
00225 {
00226 to_ = from;
00227 }
00228
00229
00230
00231 template <unsigned n, unsigned m>
00232 inline
00233 void
00234 from_to_(const value::int_u<n>& from, value::label<m>& to_)
00235 {
00236 enum { valid = n < m };
00237 metal::bool_<valid>::check();
00238 to_ = from;
00239 }
00240
00241
00242 template <unsigned n>
00243 inline
00244 void
00245 from_to_(const value::label<n>& from, bool& to_)
00246 {
00247 to_ = (from != 0u);
00248 }
00249
00250
00251 template <unsigned n>
00252 inline
00253 void
00254 from_to_(const value::label<n>& from, unsigned& to_)
00255 {
00256 to_ = from;
00257 }
00258
00259
00260 }
00261
00262 }
00263
00264
00265
00266 namespace value
00267 {
00268
00269 template <unsigned n>
00270 inline
00271 label<n>::label()
00272 {
00273 }
00274
00275 template <unsigned n>
00276 inline
00277 label<n>::label(unsigned i)
00278 {
00279 this->v_ = enc(i);
00280 }
00281
00282 template <unsigned n>
00283 inline
00284 label<n>::label(const literal::zero_t&)
00285 {
00286 this->v_ = 0;
00287 }
00288
00289 template <unsigned n>
00290 inline
00291 label<n>::operator unsigned() const
00292 {
00293 return this->to_enc();
00294 }
00295
00296 template <unsigned n>
00297 inline
00298 label<n>&
00299 label<n>::operator=(unsigned i)
00300 {
00301 mln_precondition(i <= mln_max(enc));
00302 this->v_ = enc(i);
00303 return *this;
00304 }
00305
00306 template <unsigned n>
00307 inline
00308 label<n>&
00309 label<n>::operator=(const literal::zero_t&)
00310 {
00311 this->v_ = 0;
00312 return *this;
00313 }
00314
00315 template <unsigned n>
00316 inline
00317 label<n>&
00318 label<n>::operator++()
00319 {
00320 mln_precondition(this->v_ < mln_max(enc));
00321 ++this->v_;
00322 return *this;
00323 }
00324
00325 template <unsigned n>
00326 inline
00327 label<n>&
00328 label<n>::operator--()
00329 {
00330 mln_precondition(this->v_ != 0);
00331 --this->v_;
00332 return *this;
00333 }
00334
00335 template <unsigned n>
00336 inline
00337 label<n>
00338 label<n>::next() const
00339 {
00340 return label<n>(this->v_ + 1);
00341 }
00342
00343 template <unsigned n>
00344 inline
00345 label<n>
00346 label<n>::prev() const
00347 {
00348 return label<n>(this->v_ - 1);
00349 }
00350
00351 template <unsigned n>
00352 inline
00353 std::ostream& operator<<(std::ostream& ostr, const label<n>& i)
00354 {
00355 return ostr << debug::format(i.to_equiv());
00356 }
00357
00358 }
00359
00360
00361 # endif // ! MLN_INCLUDE_ONLY
00362
00363 }
00364
00365
00366 #endif // ! MLN_VALUE_LABEL_HH