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 #ifndef VINT_HPP_
00033 #define VINT_HPP_
00034
00035 #include <boost/mpl/if.hpp>
00036
00037 #include "detail/helper.hpp"
00038 #include "detail/vint_big.hpp"
00039 #include "detail/vint_small.hpp"
00040
00041 using namespace _vint::detail;
00042
00043 template<size_t l, bool s> class vint;
00044 template<size_t l, bool s>
00045 std::ostream& operator<<(std::ostream&, const vint<l, s>& v);
00046
00063 template<size_t __length = 0, bool __sign = false>
00064 class vint {
00065
00066 friend std::ostream& operator<< <__length, __sign> (std::ostream&,
00067 const vint<__length, __sign>&);
00068
00069 public:
00070
00071 typedef typename boost::mpl::if_<
00072 boost::mpl::bool_<(__length> 64 || __length == 0)>,
00073 vint_big<__length, __sign>, vint_small<__length, __sign>
00074 >::type type;
00075
00076
00077 type value;
00078
00079
00080 typedef vint<__length, __sign> _self;
00081
00082 public:
00083
00084 finline vint() : value() {}
00085
00086
00087 template<typename T> finline vint(const T v, if_integral(T) ) : value(v) {}
00088
00089
00090 finline vint(const char* text, int base = 10) : value(text,base) {}
00091
00092
00093 finline vint( const type& v ) {value = v;}
00094
00095
00096 finline vint( const _self& v ) {value = v.value;}
00097
00098
00099
00100 template<size_t ___length, bool ___sign>
00101 finline void convert_to(vint<___length, ___sign>& v ) const {
00102 return value.convert_to(v.value);
00103 }
00104
00105 template<class T>
00106 finline void convert_to( T& v, if_integral(T) ) const {
00107 return value.convert_to(v);
00108 }
00109
00110 finline std::string to_string(int base = 10,
00111 int str_size = 0, char str_fill = '0') const {
00112 return value.to_string(base,str_size,str_fill);
00113 }
00114
00115 std::string to_debug_string(int base = 10,
00116 int str_size = 0, char str_fill = '0') const {
00117 return value.to_debug_string(base,str_size,str_fill);
00118 }
00119
00120
00121
00122 finline bool get_bit(size_t index) const {
00123 return value.get_bit(index);
00124 }
00125
00126 finline void set_bit(size_t index, bool v) {
00127 value.set_bit(index, v);
00128 }
00129
00130 finline void set_subint(_self& v, size_t index) {
00131 value.set_subint(v.value,index);
00132 }
00133
00134 finline void set_subint(uintmax_t v, size_t index) {
00135 value.set_subint(v,index);
00136 }
00137
00138 finline _self get_subint(size_t index, size_t length) const {
00139 return value.get_subint(index,length);
00140 }
00141
00142 finline uintmax_t get_subint(size_t index) const {
00143 return value.get_subint(index);
00144 }
00145
00146
00147
00148 public:
00149
00150 template<size_t _len, bool _sign>
00151 finline void assign( const vint<_len,_sign>& v ) {
00152 value.assign(v.value);
00153 }
00154
00155 template<typename T>
00156 finline void assign(const T& v, if_integral(T) ) {
00157 value.assign(v);
00158 }
00159
00160 finline void assign(const std::string& text, int base = 10) {
00161 value.assign( text, base );
00162 }
00163
00164 void assign(const char*& text, int base = 10) {
00165 assign(std::string(text), base);
00166 }
00167
00168
00169
00170 finline int compare_to(const _self& v) const {
00171 return value.compare_to(v.value);
00172 }
00173
00174 template<class T>
00175 finline int compare_to(const T& v, if_integral(T) ) const {
00176 return value.compare_to(v);
00177 }
00178
00179
00180
00181
00182 template<class T>
00183 finline void add(const T& rhs, if_integral(T) ) {value.add(rhs.value);}
00184 finline void add(const _self& rhs) {value.add(rhs.value);}
00185
00186
00187 template<class T>
00188 finline void sub(const T& rhs, if_integral(T) ) {value.sub(rhs.value);}
00189 finline void sub(const _self& rhs) {value.sub(rhs.value);}
00190
00191
00192 template<class T>
00193 finline void mul( const T& rhs, if_integral(T) ) {value.mul(rhs);}
00194 finline void mul( _self& rhs) {value.mul(rhs.value);}
00195 finline void mul( _self& res, const _self& rhs ) const {value.mul(res.value,rhs.value);}
00196
00197
00198 template<class T>
00199 finline void div( const T& rhs, if_integral(T) ) {value.div(rhs);}
00200 finline void div(_self& rhs) {value.div(rhs.value);}
00201 finline void div(_self& res, const _self& rhs ) const {value.div(res.value, rhs);}
00202
00203
00204 template<class T>
00205 finline void mod( const T& rhs, if_integral(T) ) {value.mod(rhs);}
00206 finline void mod(_self& rhs) {value.mod(rhs.value);}
00207 finline void mod(_self& res, const _self& rhs ) const {value.mod(res.value, rhs);}
00208
00209
00210 template<class T>
00211 finline void mod( T& res, const T& rhs, if_integral(T) ) const {value.mod(res,rhs);}
00212
00213
00214 template<class T>
00215 finline void divrem(_self& res_div, T& res_rem, const T& rhs, if_integral(T) ) const {
00216 value.divrem(res_div.value, res_rem, rhs );
00217 }
00218 finline void divrem(_self& res_div, _self& res_rem, const _self& rhs ) const {
00219 value.divrem(res_div.value, res_rem.value, rhs.value);
00220 }
00221 template<class T>
00222 finline void divrem( T& res_rem, const T& rhs, if_integral(T) ) {
00223 value.div(res_rem, rhs.value);
00224 }
00225 finline void divrem( _self& res_rem, const _self& rhs ) {
00226 value.div(res_rem.value, rhs.value);
00227 }
00228
00229
00230 finline uintmax_t log2() const {return value.log2();}
00231
00232
00233
00234 finline void or_ (const _self& v) {value.or_(v.value);}
00235 finline void and_(const _self& v) {value.and_(v.value);}
00236 finline void xor_(const _self& v) {value.xor_(v.value);}
00237 finline void complement() {value.complement();}
00238 finline void lshift(size_t steps) {value.lshift(steps);}
00239 finline void rshift(size_t steps) {value.rshift(steps);}
00240
00241
00242
00243 inline _self normalized() const {return value.normalized();}
00244
00245
00246
00247 finline size_t length() const {return value.length();}
00248 finline void set_length(size_t length) {value.set_length(length);}
00249 finline bool is_unspecified() {return value.is_unspecified();}
00250
00251 finline _self max() const {_self v; v.value = value.max(); return v;}
00252 finline _self min() const {_self v; v.value = value.min(); return v;}
00253 finline _self zero() const {_self v; v.value = value.zero(); return v;}
00254
00255
00256
00257 finline void convert_to( std::string& str ) const {
00258 str = to_string();
00259 }
00260
00264 finline bool is_between(const _self& a, const _self& b) const {
00265 return (a <= b) ?
00266 ((*this >= a) && (*this <= b))
00267 :
00268 ((*this <= a) && (*this >= b))
00269 ;
00270 }
00271
00276 finline bool is_between_ring(const _self& a, const _self& b) const {
00277 return (b<a) ?
00278 (is_between(a, a.max())||is_between(b.zero(), b))
00279 :
00280 ((*this >= a) && (*this <= b))
00281 ;
00282 }
00283
00284
00285
00286
00287 template<typename T> finline T convert() const {T v;convert_to(v);return v;}
00288 template<typename T> finline operator T () const {return convert<T>();}
00289
00290
00291 template<class T>
00292 finline _self& operator=(const T& copy) {assign(copy);return *this;}
00293
00294
00295 template<class T>
00296 finline _self& operator+=(const T& v) {add(v);return *this;}
00297 template<class T>
00298 finline _self& operator++() {add(1);return *this;}
00299 template<class T>
00300 finline _self operator+ (const T& v) const {_self x=*this;x.add(v);return x;}
00301
00302
00303 template<class T>
00304 finline _self& operator-=(const T& v) {sub_model(v);return *this;}
00305 finline _self& operator--() {sub(1);return *this;}
00306 template<class T>
00307 finline _self operator- (const T& v) const {
00308 _self x(*this); x.sub_model(v); return x;
00309 }
00310
00311
00312 template<class T> finline _self& operator*=(const T& v) {
00313 value.mul(v);
00314 return *this;
00315 }
00316 template<class T> finline _self operator*(const T& v) const {
00317 _self res = *this;res.mul(v); return res;
00318 }
00319
00320
00321 finline _self operator<< (size_t steps) {_self x=*this;return(x<<=steps);}
00322 finline _self& operator>>=(size_t steps) {rshift(steps);return *this;}
00323 finline _self operator>> (size_t steps) {_self x=*this;return(x<<=steps);}
00324 finline _self& operator<<=(size_t steps) {lshift(steps);return *this;}
00325
00326
00327 finline _self& operator&=(const _self& v) {and_(v); return *this;}
00328 finline _self operator & (const _self& v) {_self x=*this;return(x&=v);}
00329 finline _self& operator|=(const _self& v) {or_(v); return *this;}
00330 finline _self operator | (const _self& v) {_self x=*this;return(x|=v);}
00331 finline _self& operator^=(const _self& v) {xor_(v);return *this;}
00332 finline _self operator^ (const _self& v) {_self x=*this;return(x ^= v);}
00333 finline _self operator~() {_self x=*this;return x.complement();}
00334
00335
00336 template<class T>
00337 finline bool operator< (const T& v) const {return compare_to(v)< 0;}
00338 template<class T>
00339 finline bool operator> (const T& v) const {return compare_to(v)> 0;}
00340 template<class T>
00341 finline bool operator<=(const T& v) const {return compare_to(v)<=0;}
00342 template<class T>
00343 finline bool operator>=(const T& v) const {return compare_to(v)>=0;}
00344 template<class T>
00345 finline bool operator==(const T& v) const {return compare_to(v)==0;}
00346 template<class T>
00347 finline bool operator!=(const T& v) const {return compare_to(v)!=0;}
00348 };
00349
00350 template<size_t l, bool s>
00351 std::ostream& operator<<(std::ostream& os, const vint<l, s>& v) {
00352 return os << v.value;
00353 }
00354
00355 #endif
00356