00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef VINT_SMALL_HPP_
00035 #define VINT_SMALL_HPP_
00036
00037 #include<boost/mpl/if.hpp>
00038 #include<boost/integer.hpp>
00039
00040 #include "helper.hpp"
00041 #include <cmath>
00042
00043 #define NO_INT64
00044
00045 using boost::mpl::if_;
00046 using boost::mpl::bool_;
00047
00048 namespace _vint {
00049 namespace detail {
00050 template<size_t l, bool s> class vint_small;
00051 }}
00052
00053 template<size_t l, bool s>
00054 std::ostream& operator<<(std::ostream& os, const _vint::detail::vint_small<l, s>& v);
00055
00056 namespace _vint {
00057 namespace detail {
00058
00069 template<size_t __length = 0, bool __sign = false>
00070 class vint_small {
00071 friend std::ostream& operator<< <__length, __sign> (std::ostream&,
00072 const vint_small<__length, __sign>&);
00073 private:
00074
00075 typedef
00076 #ifndef NO_INT64
00077 typename if_<
00078 bool_<(__length> 32 && __length <= 64)>,
00079 typename if_<bool_<__sign>, boost::int64_t, boost::uint64_t>::type,
00080 #endif
00081 #ifndef NO_INT32
00082 typename if_<
00083 bool_<(__length> 16 && __length <= 32)>,
00084 typename if_<bool_<__sign>, boost::int32_t, boost::uint32_t>::type,
00085 #endif
00086 typename if_<
00087 bool_<(__length> 8 && __length <= 16)>,
00088 typename if_<bool_<__sign>, boost::int16_t, boost::uint16_t>::type,
00089 typename if_<
00090 bool_<(__length> 0 && __length <= 8)>,
00091 typename if_<bool_<__sign>, boost::int8_t, boost::uint8_t>::type,
00092 void
00093 > ::type
00094 #ifndef NO_INT32
00095 > ::type
00096 #endif
00097 #ifndef NO_INT64
00098 > ::type
00099 #endif
00100 > ::type type;
00101
00102
00103 type value;
00104
00105
00106 finline void trim() {
00107 value &= (((type)1) << __length) - 1;
00108 }
00109
00110
00111 typedef vint_small<__length,__sign> _self;
00112 public:
00113 finline vint_small() {
00114 value = 0;
00115 }
00116
00117 finline vint_small( const type& value ) {
00118 this->value = value;
00119 trim();
00120 }
00121
00122 finline vint_small(const char* text, int base = 10) {
00123 assign(std::string(text),base);
00124 }
00125
00126
00127
00128 template<class T>
00129 finline void convert_to( T& v, if_integral(T) ) const {
00130 v = (T)value;
00131 }
00132
00133 finline std::string to_string(int base = 10,
00134 int str_size = 0, char str_fill = '0') const {
00135
00136
00137 std::string s = "\0";
00138 int last_non_zero = 0;
00139 int last = 0;
00140 type _val = value;
00141
00142 while (_val != 0) {
00143
00144 type rem = _val % base;
00145 type _div = _val / base;
00146
00147
00148 s += (char) rem;
00149 if (rem != 0) last_non_zero = last;
00150 last++;
00151
00152
00153 _val = _div;
00154 }
00155 last = last_non_zero + 1;
00156
00157
00158 for (int i = 0; i < last / 2; i++) {
00159 char dummy = s[i];
00160 s[i] = s[last - i - 1];
00161 s[last - i - 1] = (int) dummy;
00162 }
00163
00164
00165 s.resize(last);
00166 for (int i = 0; i < last; i++)
00167 s[i] = ("0123456789ABCDEF")[(int) s[i]];
00168
00169
00170 if (last < str_size) {
00171 char zeros[str_size - last+1];
00172 memset(zeros, str_fill, str_size - last);
00173 zeros[str_size - last] = 0;
00174 return std::string(zeros) + s;
00175 } else {
00176 return s;
00177 }
00178 }
00179
00180 std::string to_debug_string(int base = 10,
00181 int str_size = 0, char str_fill = '0') const {
00182 std::ostringstream str;
00183 str << "vint_small(static,";
00184 str << "length=" << __length << ",";
00185 str << "mem=" << sizeof(*this) << ",";
00186 str << "val=" << to_string(base, str_size, str_fill) << ")";
00187 return str.str();
00188 }
00189
00190
00191
00192 finline bool get_bit(size_t index) const {
00193 return false;
00194 }
00195
00196 finline void set_bit(size_t index, bool v) {
00197 }
00198
00199 finline void set_subint(_self& v, size_t index) {
00200 }
00201
00202 finline void set_subint(uintmax_t v, size_t index) {
00203 }
00204
00205 finline _self get_subint(size_t index, size_t length) const {
00206 }
00207
00208 finline uintmax_t get_subint(size_t index) const {
00209 return 0;
00210 }
00211
00212
00213
00214 template<typename T>
00215 finline void assign(const T& v, if_integral(T) ) {
00216 value = v;
00217 }
00218
00219 finline void assign(const std::string& text, int base = 10) {
00220 int x;
00221 sscanf(text.c_str(), "%d", &x);
00222 value = x;
00223 }
00224
00225
00226
00227 finline int compare_to(const _self& v) const {
00228 return (int)(value-v.value);
00229 }
00230
00231 template<class T>
00232 finline int compare_to(const T& v, if_integral(T) ) const {
00233 return (int)(value-v);
00234 }
00235
00236
00237
00238
00239 template<class T>
00240 finline void add(const T& rhs, if_integral(T) ) {
00241 value += rhs; trim();
00242 }
00243
00244 finline void add(const _self& rhs) {
00245 value += rhs.value; trim();
00246 }
00247
00248
00249 template<class T>
00250 finline void sub(const T& rhs, if_integral(T) ) {
00251 value -= rhs; trim();
00252 }
00253
00254 finline void sub(const _self& rhs) {
00255 value -= rhs.value; trim();
00256 }
00257
00258
00259 template<class T>
00260 finline void mul(const T& rhs, if_integral(T) ) {
00261 value *= rhs; trim();
00262 }
00263
00264 finline void mul(const _self& rhs) {
00265 value *= rhs.value; trim();
00266 }
00267
00268 finline void mul(_self& res_l, _self& res_h, _self& rhs) {
00269 res_l.value = rhs.value * value;
00270 res_h.value = (rhs.value >> __length) * value;
00271 }
00272
00273
00274 template<class T>
00275 finline void mod(const T& rhs, if_integral(T) ) {
00276 value %= rhs; trim();
00277 }
00278
00279 finline void mod( const _self& rhs ) {
00280 value %= rhs.value; trim();
00281 }
00282
00283 finline void mod( _self& res, const _self& rhs ) {
00284 res.value = value % rhs.value; res.trim();
00285 }
00286
00287
00288 template<class T>
00289 finline void mod( T& res, const T& rhs, if_integral(T) ) const {
00290 res = value % rhs;
00291 }
00292
00293
00294 template<class T>
00295 finline void div( const T& rhs, if_integral(T) ) {
00296 value /= rhs; trim();
00297 }
00298
00299 finline void div( const _self& rhs ) {
00300 value /= rhs.value; trim();
00301 }
00302
00303 finline void div( _self& res, const _self& rhs ) {
00304 res.value = value / rhs.value; res.trim();
00305 }
00306
00307
00308 template<class T>
00309 finline void divrem(_self& res_div, _self& res_rem, const T& rhs, if_integral(T)) {
00310 res_div.value = value / rhs;
00311 res_rem.value = value % rhs;
00312 }
00313
00314 finline void divrem(_self& res_rem, const _self& rhs) {
00315 value = value / rhs.value;
00316 res_rem.value = value % rhs.value;
00317 }
00318
00319 finline void divrem(_self& res_div, _self& res_rem, const _self& rhs) {
00320 res_div.value = value / rhs.value;
00321 res_rem.value = value % rhs.value;
00322 }
00323
00324
00325 template<class T>
00326 finline void divrem(_self& res_div, T& res_rem, const T& rhs, if_integral(T)) {
00327 res_div.value = value / rhs;
00328 res_rem = value % rhs;
00329 }
00330
00331
00332 finline uintmax_t log2() const {
00333 return ::log2(value);
00334 }
00335
00336
00337
00338 finline void or_ (const _self& rhs) {value |= rhs.value;}
00339 finline void and_(const _self& rhs) {value &= rhs.value;}
00340 finline void xor_(const _self& rhs) {value ^= rhs.value;}
00341 finline void complement() {value = ~value; trim();}
00342 finline void lshift(size_t steps) {value <<= steps; trim();}
00343 finline void rshift(size_t steps) {value >>= steps; trim();}
00344
00345
00346
00347
00348
00349
00350
00351 finline size_t length() const {return __length;}
00352 finline void set_length(size_t length) {}
00353 finline bool is_unspecified() {return false;}
00354
00355 finline _self max() const {return ~(type)0;}
00356 finline _self min() const {return (type)0;}
00357 finline _self zero() const {return (type)0;}
00358 };
00359
00360 }}
00361
00362 template<size_t l, bool s>
00363 std::ostream& operator<<(std::ostream& os, const _vint::detail::vint_small<l, s>& v) {
00364 return os << v.to_string();
00365 }
00366
00367 #endif