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

label.hh

00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
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   // Forward declarations.
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   } // end of namespace trait
00090 
00091 
00092   namespace convert
00093   {
00094 
00095     namespace over_load
00096     {
00097 
00098       // int_u -> label.
00099       template <unsigned n>
00100       void
00101       from_to_(const value::int_u<n>& from, value::label<n>& to_);
00102 
00103       // int_u -> label.
00104       template <unsigned n, unsigned m>
00105       void
00106       from_to_(const value::int_u<n>& from, value::label<m>& to_);
00107 
00108       // label -> bool.
00109       template <unsigned n>
00110       void
00111       from_to_(const value::label<n>& from, bool& to_);
00112 
00113     } // end of namespace mln::convert::over_load
00114 
00115   } // end of namespace mln::convert
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,    // Equivalent.
00129                                       typename internal::encoding_unsigned_<n>::ret, // Enc.
00130                                       int,    // Interoperation.
00131                                       label<n> >   // Exact.
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     // Safety.
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   } // end of namespace mln::value
00187 
00188 
00189 # ifndef MLN_INCLUDE_ONLY
00190 
00191 
00192   namespace convert
00193   {
00194 
00195     namespace over_load
00196     {
00197 
00198       // int_u -> label.
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       // int_u<n> -> label<m> with n < m.
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     } // end of namespace mln::convert::over_load
00227 
00228   } // end of namespace mln::convert
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   } // end of namespace mln::value
00325 
00326 
00327 # endif // ! MLN_INCLUDE_ONLY
00328 
00329 } // end of namespace mln
00330 
00331 
00332 #endif // ! MLN_VALUE_LABEL_HH

Generated on Thu Sep 8 2011 18:32:03 for Milena (Olena) by  doxygen 1.7.1