• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

label.hh

00001 // Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and
00002 // Development Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
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   // Forward declarations.
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   } // end of namespace trait
00093 
00094 
00095   namespace convert
00096   {
00097 
00098     namespace over_load
00099     {
00100 
00101       // int_u -> label.
00102       template <unsigned n>
00103       void
00104       from_to_(const value::int_u<n>& from, value::label<n>& to_);
00105 
00106       // label -> int_u.
00107       template <unsigned n>
00108       void
00109       from_to_(const value::label<n>& from, value::int_u<n>& to_);
00110 
00111 
00112       // int_u -> label.
00113       template <unsigned n, unsigned m>
00114       void
00115       from_to_(const value::int_u<n>& from, value::label<m>& to_);
00116 
00117       // label -> bool.
00118       template <unsigned n>
00119       void
00120       from_to_(const value::label<n>& from, bool& to_);
00121 
00122       // label -> unsigned.
00123       template <unsigned n>
00124       void
00125       from_to_(const value::label<n>& from, unsigned& to_);
00126 
00127     } // end of namespace mln::convert::over_load
00128 
00129   } // end of namespace mln::convert
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,    // Equivalent.
00143                                       typename internal::encoding_unsigned_<n>::ret, // Enc.
00144                                       int,    // Interoperation.
00145                                       label<n> >   // Exact.
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     // Safety.
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   } // end of namespace mln::value
00201 
00202 
00203 # ifndef MLN_INCLUDE_ONLY
00204 
00205 
00206   namespace convert
00207   {
00208 
00209     namespace over_load
00210     {
00211 
00212       // int_u -> label.
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       // label -> int_u.
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       // int_u<n> -> label<m> with n < m.
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       // int_u<n> -> bool
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       // int_u<n> -> unsigned
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     } // end of namespace mln::convert::over_load
00261 
00262   } // end of namespace mln::convert
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   } // end of namespace mln::value
00359 
00360 
00361 # endif // ! MLN_INCLUDE_ONLY
00362 
00363 } // end of namespace mln
00364 
00365 
00366 #endif // ! MLN_VALUE_LABEL_HH

Generated on Tue Oct 4 2011 15:24:01 for Milena (Olena) by  doxygen 1.7.1