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 #ifndef MLN_VALUE_LABEL_HH
00027 # define MLN_VALUE_LABEL_HH
00028
00032
00033 # include <mln/debug/format.hh>
00034 # include <mln/metal/math/pow.hh>
00035 # include <mln/trait/value_.hh>
00036 # include <mln/value/concept/symbolic.hh>
00037 # include <mln/value/internal/value_like.hh>
00038 # include <mln/value/internal/convert.hh>
00039 # include <mln/value/internal/encoding.hh>
00040
00041
00042 namespace mln
00043 {
00044
00045
00046 namespace value {
00047 template <unsigned n> struct label;
00048 template <unsigned n> struct int_u;
00049 }
00050
00051 namespace literal {
00052 struct zero_t;
00053 }
00054
00055
00056 namespace trait
00057 {
00058
00059 template <unsigned n>
00060 struct value_< mln::value::label<n> >
00061 {
00062 private:
00063 typedef mln::value::label<n> self_;
00064
00065 public:
00066
00067 enum {
00068 dim = 1,
00069 nbits = n,
00070 card = mln_value_card_from_(n)
00071 };
00072
00073 typedef trait::value::nature::symbolic nature;
00074 typedef trait::value::kind::label kind;
00075 typedef mln_value_quant_from_(card) quant;
00076
00077 static const self_ min() { return 0; }
00078 static const self_ max() { return mlc_pow_int(2, n) - 1; }
00079
00080 static const char* name()
00081 {
00082 static std::string s = std::string("label_").append(1, n + '0');
00083 return s.c_str();
00084 }
00085
00086 typedef unsigned comp;
00087 };
00088
00089 }
00090
00091
00092 namespace convert
00093 {
00094
00095 namespace over_load
00096 {
00097
00098
00099 template <unsigned n>
00100 void
00101 from_to_(const value::int_u<n>& from, value::label<n>& to_);
00102
00103
00104 template <unsigned n, unsigned m>
00105 void
00106 from_to_(const value::int_u<n>& from, value::label<m>& to_);
00107
00108
00109 template <unsigned n>
00110 void
00111 from_to_(const value::label<n>& from, bool& to_);
00112
00113 }
00114
00115 }
00116
00117 namespace value
00118 {
00119
00120
00125 template <unsigned n>
00126 struct label
00127 : public Symbolic< label<n> >,
00128 public internal::value_like_< unsigned,
00129 typename internal::encoding_unsigned_<n>::ret,
00130 int,
00131 label<n> >
00132
00133 {
00134 public:
00136 typedef typename internal::encoding_unsigned_<n>::ret enc;
00137
00139 label();
00140
00142 label(unsigned i);
00143
00145 label(const literal::zero_t& v);
00146
00148 operator unsigned() const;
00149
00151 label<n>& operator=(unsigned i);
00152
00154 label<n>& operator=(const literal::zero_t& v);
00155
00157 label<n>& operator++();
00158
00160 label<n>& operator--();
00161
00163 label<n> next() const;
00164
00166 label<n> prev() const;
00167
00168 };
00169
00170
00171
00172 template <> struct label<0>;
00173 template <> struct label<1>;
00174
00182 template <unsigned n>
00183 std::ostream& operator<<(std::ostream& ostr, const label<n>& l);
00184
00185
00186 }
00187
00188
00189 # ifndef MLN_INCLUDE_ONLY
00190
00191
00192 namespace convert
00193 {
00194
00195 namespace over_load
00196 {
00197
00198
00199 template <unsigned n>
00200 inline
00201 void
00202 from_to_(const value::int_u<n>& from, value::label<n>& to_)
00203 {
00204 to_ = from;
00205 }
00206
00207
00208 template <unsigned n, unsigned m>
00209 inline
00210 void
00211 from_to_(const value::int_u<n>& from, value::label<m>& to_)
00212 {
00213 enum { valid = n < m };
00214 metal::bool_<valid>::check();
00215 to_ = from;
00216 }
00217
00218 template <unsigned n>
00219 inline
00220 void
00221 from_to_(const value::label<n>& from, bool& to_)
00222 {
00223 to_ = (from != 0u);
00224 }
00225
00226 }
00227
00228 }
00229
00230
00231
00232 namespace value
00233 {
00234
00235 template <unsigned n>
00236 inline
00237 label<n>::label()
00238 {
00239 }
00240
00241 template <unsigned n>
00242 inline
00243 label<n>::label(unsigned i)
00244 {
00245 this->v_ = enc(i);
00246 }
00247
00248 template <unsigned n>
00249 inline
00250 label<n>::label(const literal::zero_t&)
00251 {
00252 this->v_ = 0;
00253 }
00254
00255 template <unsigned n>
00256 inline
00257 label<n>::operator unsigned() const
00258 {
00259 return this->to_enc();
00260 }
00261
00262 template <unsigned n>
00263 inline
00264 label<n>&
00265 label<n>::operator=(unsigned i)
00266 {
00267 mln_precondition(i <= mln_max(enc));
00268 this->v_ = enc(i);
00269 return *this;
00270 }
00271
00272 template <unsigned n>
00273 inline
00274 label<n>&
00275 label<n>::operator=(const literal::zero_t&)
00276 {
00277 this->v_ = 0;
00278 return *this;
00279 }
00280
00281 template <unsigned n>
00282 inline
00283 label<n>&
00284 label<n>::operator++()
00285 {
00286 mln_precondition(this->v_ < mln_max(enc));
00287 ++this->v_;
00288 return *this;
00289 }
00290
00291 template <unsigned n>
00292 inline
00293 label<n>&
00294 label<n>::operator--()
00295 {
00296 mln_precondition(this->v_ != 0);
00297 --this->v_;
00298 return *this;
00299 }
00300
00301 template <unsigned n>
00302 inline
00303 label<n>
00304 label<n>::next() const
00305 {
00306 return label<n>(this->v_ + 1);
00307 }
00308
00309 template <unsigned n>
00310 inline
00311 label<n>
00312 label<n>::prev() const
00313 {
00314 return label<n>(this->v_ - 1);
00315 }
00316
00317 template <unsigned n>
00318 inline
00319 std::ostream& operator<<(std::ostream& ostr, const label<n>& i)
00320 {
00321 return ostr << debug::format(i.to_equiv());
00322 }
00323
00324 }
00325
00326
00327 # endif // ! MLN_INCLUDE_ONLY
00328
00329 }
00330
00331
00332 #endif // ! MLN_VALUE_LABEL_HH