Milena (Olena)
User documentation 2.0a Id
|
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