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
00124 }
00125
00126 namespace value
00127 {
00128
00129
00134 template <unsigned n>
00135 struct label
00136 : public Symbolic< label<n> >,
00137 public internal::value_like_< unsigned,
00138 typename internal::encoding_unsigned_<n>::ret,
00139 int,
00140 label<n> >
00141
00142 {
00143 public:
00145 typedef typename internal::encoding_unsigned_<n>::ret enc;
00146
00148 label();
00149
00151 label(unsigned i);
00152
00154 label(const literal::zero_t& v);
00155
00157 operator unsigned() const;
00158
00160 label<n>& operator=(unsigned i);
00161
00163 label<n>& operator=(const literal::zero_t& v);
00164
00166 label<n>& operator++();
00167
00169 label<n>& operator--();
00170
00172 label<n> next() const;
00173
00175 label<n> prev() const;
00176
00177 };
00178
00179
00180
00181 template <> struct label<0>;
00182 template <> struct label<1>;
00183
00191 template <unsigned n>
00192 std::ostream& operator<<(std::ostream& ostr, const label<n>& l);
00193
00194
00195 }
00196
00197
00198 # ifndef MLN_INCLUDE_ONLY
00199
00200
00201 namespace convert
00202 {
00203
00204 namespace over_load
00205 {
00206
00207
00208 template <unsigned n>
00209 inline
00210 void
00211 from_to_(const value::int_u<n>& from, value::label<n>& to_)
00212 {
00213 to_ = from;
00214 }
00215
00216
00217 template <unsigned n>
00218 void
00219 from_to_(const value::label<n>& from, value::int_u<n>& to_)
00220 {
00221 to_ = from;
00222 }
00223
00224
00225
00226 template <unsigned n, unsigned m>
00227 inline
00228 void
00229 from_to_(const value::int_u<n>& from, value::label<m>& to_)
00230 {
00231 enum { valid = n < m };
00232 metal::bool_<valid>::check();
00233 to_ = from;
00234 }
00235
00236 template <unsigned n>
00237 inline
00238 void
00239 from_to_(const value::label<n>& from, bool& to_)
00240 {
00241 to_ = (from != 0u);
00242 }
00243
00244 }
00245
00246 }
00247
00248
00249
00250 namespace value
00251 {
00252
00253 template <unsigned n>
00254 inline
00255 label<n>::label()
00256 {
00257 }
00258
00259 template <unsigned n>
00260 inline
00261 label<n>::label(unsigned i)
00262 {
00263 this->v_ = enc(i);
00264 }
00265
00266 template <unsigned n>
00267 inline
00268 label<n>::label(const literal::zero_t&)
00269 {
00270 this->v_ = 0;
00271 }
00272
00273 template <unsigned n>
00274 inline
00275 label<n>::operator unsigned() const
00276 {
00277 return this->to_enc();
00278 }
00279
00280 template <unsigned n>
00281 inline
00282 label<n>&
00283 label<n>::operator=(unsigned i)
00284 {
00285 mln_precondition(i <= mln_max(enc));
00286 this->v_ = enc(i);
00287 return *this;
00288 }
00289
00290 template <unsigned n>
00291 inline
00292 label<n>&
00293 label<n>::operator=(const literal::zero_t&)
00294 {
00295 this->v_ = 0;
00296 return *this;
00297 }
00298
00299 template <unsigned n>
00300 inline
00301 label<n>&
00302 label<n>::operator++()
00303 {
00304 mln_precondition(this->v_ < mln_max(enc));
00305 ++this->v_;
00306 return *this;
00307 }
00308
00309 template <unsigned n>
00310 inline
00311 label<n>&
00312 label<n>::operator--()
00313 {
00314 mln_precondition(this->v_ != 0);
00315 --this->v_;
00316 return *this;
00317 }
00318
00319 template <unsigned n>
00320 inline
00321 label<n>
00322 label<n>::next() const
00323 {
00324 return label<n>(this->v_ + 1);
00325 }
00326
00327 template <unsigned n>
00328 inline
00329 label<n>
00330 label<n>::prev() const
00331 {
00332 return label<n>(this->v_ - 1);
00333 }
00334
00335 template <unsigned n>
00336 inline
00337 std::ostream& operator<<(std::ostream& ostr, const label<n>& i)
00338 {
00339 return ostr << debug::format(i.to_equiv());
00340 }
00341
00342 }
00343
00344
00345 # endif // ! MLN_INCLUDE_ONLY
00346
00347 }
00348
00349
00350 #endif // ! MLN_VALUE_LABEL_HH