Milena (Olena)
User documentation 2.0a Id
|
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_INT_U_HH 00028 # define MLN_VALUE_INT_U_HH 00029 00033 00034 # include <mln/trait/all.hh> // FIXME! 00035 00036 # include <mln/value/ops.hh> 00037 00038 # include <mln/metal/math/pow.hh> 00039 # include <mln/value/internal/value_like.hh> 00040 # include <mln/value/internal/encoding.hh> 00041 # include <mln/value/concept/integer.hh> 00042 # include <mln/trait/value_.hh> 00043 # include <mln/debug/format.hh> 00044 00045 # include <mln/value/internal/make_generic_name.hh> 00046 00047 00048 namespace mln 00049 { 00050 00051 namespace value 00052 { 00053 // Forward declaration. 00054 template <unsigned n> struct int_u; 00055 } 00056 00057 namespace literal 00058 { 00059 // Forward declarations. 00060 struct zero_t; 00061 struct one_t; 00062 } 00063 00064 00065 namespace trait 00066 { 00067 00068 template <unsigned n> 00069 struct set_precise_unary_< op::uminus, mln::value::int_u<n> > 00070 { 00071 typedef int ret; 00072 }; 00073 00074 00075 template <unsigned n> 00076 struct value_< mln::value::int_u<n> > 00077 { 00078 private: 00079 typedef mln::value::int_u<n> self_; 00080 typedef typename mln::value::internal::encoding_unsigned_<n>::ret enc_; 00081 public: 00082 00083 enum constants_ { 00084 dim = 1, 00085 nbits = n, 00086 card = mln_value_card_from_(n) 00087 }; 00088 00089 typedef trait::value::nature::integer nature; 00090 typedef trait::value::kind::data kind; 00091 typedef mln_value_quant_from_(card) quant; 00092 00093 static const self_ min() { return 0; } 00094 static const self_ max() { return mlc_pow_int(2, n) - 1; } 00095 static const self_ epsilon() { return 0; } 00096 00097 typedef unsigned comp; 00098 00099 typedef float sum; 00100 00101 static const char* name() 00102 { 00103 static std::string 00104 s = mln::value::internal::make_generic_name("int_u", n); 00105 return s.c_str(); 00106 } 00107 00108 }; 00109 00110 } // end of namespace mln::trait 00111 00112 00113 namespace convert 00114 { 00115 00116 namespace over_load 00117 { 00118 00119 // int_u -> unsigned. 00120 template <unsigned n> 00121 void 00122 from_to_(const value::int_u<n>& from, unsigned& to_); 00123 00124 00125 // int_u -> bool. 00126 template <unsigned n> 00127 void 00128 from_to_(const value::int_u<n>& from, bool& to_); 00129 00130 00131 // int_u -> float. 00132 template <unsigned n> 00133 void 00134 from_to_(const value::int_u<n>& from, float& to_); 00135 00136 00137 // int_u -> double. 00138 template <unsigned n> 00139 void 00140 from_to_(const value::int_u<n>& from, double& to_); 00141 00142 00143 } // end of namespace mln::convert::over_load 00144 00145 } // end of namespace mln::convert 00146 00147 00148 00149 namespace value 00150 { 00151 00155 template <unsigned n> 00156 struct int_u 00157 : 00158 public Integer< int_u<n> >, 00159 00160 public internal::value_like_< unsigned, // Equivalent. 00161 typename internal::encoding_unsigned_<n>::ret, // Enc. 00162 int, // Interoperation. 00163 int_u<n> > // Exact. 00164 { 00165 protected: 00167 typedef typename internal::encoding_unsigned_<n>::ret enc_; 00168 00169 public: 00170 00172 int_u(); 00173 00175 int_u(int i); 00176 00178 int_u(const mln::literal::zero_t&); 00179 int_u& operator=(const mln::literal::zero_t&); 00180 int_u(const mln::literal::one_t&); 00181 int_u& operator=(const mln::literal::one_t&); 00183 00185 operator unsigned() const; 00186 00188 int operator-() const; 00189 00191 int_u<n>& operator=(int i); 00192 00194 int_u<n> next() const; 00195 }; 00196 00197 00198 // Safety. 00199 template <> struct int_u<0>; 00200 template <> struct int_u<1>; 00201 00202 00203 00211 template <unsigned n> 00212 std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i); 00213 00214 00215 // FIXME: Doc! 00216 template <unsigned n> 00217 std::istream& operator>>(std::istream& istr, int_u<n>& i); 00218 00219 } // end of namespace mln::value 00220 00221 # ifndef MLN_INCLUDE_ONLY 00222 00223 namespace convert 00224 { 00225 00226 namespace over_load 00227 { 00228 00229 // int_u -> unsigned. 00230 template <unsigned n> 00231 inline 00232 void 00233 from_to_(const value::int_u<n>& from, unsigned& to_) 00234 { 00235 to_ = from; 00236 } 00237 00238 // int_u -> bool. 00239 template <unsigned n> 00240 inline 00241 void 00242 from_to_(const value::int_u<n>& from, bool& to_) 00243 { 00244 to_ = (from != 0u); 00245 } 00246 00247 // int_u -> float. 00248 template <unsigned n> 00249 inline 00250 void 00251 from_to_(const value::int_u<n>& from, float& to_) 00252 { 00253 to_ = static_cast<float>(from); 00254 } 00255 00256 // int_u -> double. 00257 template <unsigned n> 00258 inline 00259 void 00260 from_to_(const value::int_u<n>& from, double& to_) 00261 { 00262 to_ = static_cast<double>(from); 00263 } 00264 00265 00266 } // end of namespace mln::convert::over_load 00267 00268 } // end of namespace mln::convert 00269 00270 00271 namespace value 00272 { 00273 00274 template <unsigned n> 00275 inline 00276 int_u<n>::int_u() 00277 { 00278 } 00279 00280 template <unsigned n> 00281 inline 00282 int_u<n>::int_u(int i) 00283 { 00284 mln_precondition(i >= 0); 00285 mln_precondition(unsigned(i) <= mln_max(enc_)); 00286 this->v_ = static_cast<enc_>(i); 00287 } 00288 00289 template <unsigned n> 00290 inline 00291 int_u<n>::int_u(const mln::literal::zero_t&) 00292 { 00293 this->v_ = 0; 00294 } 00295 00296 template <unsigned n> 00297 inline 00298 int_u<n>& 00299 int_u<n>::operator=(const mln::literal::zero_t&) 00300 { 00301 this->v_ = 0; 00302 return *this; 00303 } 00304 00305 template <unsigned n> 00306 inline 00307 int_u<n>::int_u(const mln::literal::one_t&) 00308 { 00309 this->v_ = 1; 00310 } 00311 00312 template <unsigned n> 00313 inline 00314 int_u<n>& 00315 int_u<n>::operator=(const mln::literal::one_t&) 00316 { 00317 this->v_ = 1; 00318 return *this; 00319 } 00320 00321 template <unsigned n> 00322 inline 00323 int_u<n>::operator unsigned() const 00324 { 00325 return this->v_; 00326 } 00327 00328 template <unsigned n> 00329 inline 00330 int 00331 int_u<n>::operator-() const 00332 { 00333 return - int(this->v_); 00334 } 00335 00336 template <unsigned n> 00337 inline 00338 int_u<n>& 00339 int_u<n>::operator=(int i) 00340 { 00341 mln_precondition(i >= 0); 00342 mln_precondition(unsigned(i) <= mln_max(enc_)); 00343 this->v_ = static_cast<enc_>(i); 00344 return *this; 00345 } 00346 00347 template <unsigned n> 00348 inline 00349 int_u<n> 00350 int_u<n>::next() const 00351 { 00352 return this->v_ + 1; 00353 } 00354 00355 template <unsigned n> 00356 inline 00357 std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i) 00358 { 00359 // FIXME: This code could be factored for almost every Value<*>... 00360 return ostr << debug::format(i.to_equiv()); // FIXME: is to_equiv OK? 00361 } 00362 00363 template <unsigned n> 00364 inline 00365 std::istream& operator>>(std::istream& istr, int_u<n>& i) 00366 { 00367 return istr >> i.handle_(); 00368 } 00369 00370 } // end of namespace mln::value 00371 00372 # endif // ! MLN_INCLUDE_ONLY 00373 00374 } // end of namespace mln 00375 00376 00377 #endif // ! MLN_VALUE_INT_U_HH 00378