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

label.hh

00001 // Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
00002 // 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     } // end of namespace mln::convert::over_load
00123 
00124   } // end of namespace mln::convert
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,    // Equivalent.
00138                                       typename internal::encoding_unsigned_<n>::ret, // Enc.
00139                                       int,    // Interoperation.
00140                                       label<n> >   // Exact.
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     // Safety.
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   } // end of namespace mln::value
00196 
00197 
00198 # ifndef MLN_INCLUDE_ONLY
00199 
00200 
00201   namespace convert
00202   {
00203 
00204     namespace over_load
00205     {
00206 
00207       // int_u -> label.
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       // label -> int_u.
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       // int_u<n> -> label<m> with n < m.
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     } // end of namespace mln::convert::over_load
00245 
00246   } // end of namespace mln::convert
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   } // end of namespace mln::value
00343 
00344 
00345 # endif // ! MLN_INCLUDE_ONLY
00346 
00347 } // end of namespace mln
00348 
00349 
00350 #endif // ! MLN_VALUE_LABEL_HH

Generated on Fri Oct 19 2012 04:15:57 for Milena (Olena) by  doxygen 1.7.1