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