source: source/ariba/utility/vtypes/vint.hpp@ 6786

Last change on this file since 6786 was 6786, checked in by mies, 15 years ago

Changed Data to Message conversion constructor in Message to explicit
Fixed some general bugs in Data: operator<<
Fixed bug in DHTMessage: allow unspecified key/values
Added local DHT message delivery
Adapted sources to work with gcc 4.4.1

File size: 11.6 KB
Line 
1// [The FreeBSD Licence]
2//
3// Copyright (c) 2008
4// Sebastian Mies, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11// * Redistributions of source code must retain the above copyright notice,
12// this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above copyright
14// notice, this list of conditions and the following disclaimer in the
15// documentation and/or other materials provided with the distribution.
16// * Neither the name of the author nor the names of its contributors may be
17// used to endorse or promote products derived from this software without
18// specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31//
32#ifndef VINT_HPP_
33#define VINT_HPP_
34
35#include <boost/mpl/if.hpp>
36
37#include "detail/helper.hpp"
38#include "detail/vint_big.hpp"
39#include "detail/vint_small.hpp"
40
41using namespace _vint::detail;
42
43template<size_t l, bool s> class vint;
44template<size_t l, bool s>
45std::ostream& operator<<(std::ostream&, const vint<l, s>& v);
46
47/**
48 * This class implements an adaptive, scalable integer type.<br />
49 *
50 * Key features include:<br />
51 * <ul>
52 * <li>Transparent type switching according to native types</li>
53 * <li>Optimal memory consumption and optimization properties</li>
54 * <li>Automatic big integer arithmetic using gmp or other libraries</li>
55 * <li>Unconventional integer types (e.g. length not a power of 2)</li>
56 * <li>Additional math, like intervals, log2, divrem, gcd, ...</li>
57 * </ul>
58 *
59 * ... short: a real scalable integer type at compile-time cost!<br />
60 *
61 * @author Sebastian Mies <mies@tm.uka.de>
62 */
63template<size_t __length = 0, bool __sign = false>
64class vint {
65 // stream operator
66 friend std::ostream& operator<< <__length, __sign> (std::ostream&,
67 const vint<__length, __sign>&);
68
69public:
70 // select proper type
71 typedef typename boost::mpl::if_<
72 boost::mpl::bool_<(__length> 64 || __length == 0)>,
73 vint_big<__length, __sign>, vint_small<__length, __sign>
74 >::type type;
75
76 // selected value type
77 type value;
78
79 // internal self-template
80 typedef vint<__length, __sign> _self;
81
82public:
83 /* construct an zero integer */
84 finline vint() : value() {}
85
86 /* construct an integer from a constant */
87 template<typename T> finline vint(const T v, if_integral(T) ) : value(v) {}
88
89 /* construct a variable integer from a given string */
90 finline vint(const char* text, int base = 10) : value(text,base) {}
91
92 /* copy constructor */
93 finline vint( const type& v ) {value = v;}
94
95 /* copy constructor */
96 finline vint( const _self& v ) {value = v.value;}
97
98 //-- conversion -----------------------------------------------------------
99
100 template<size_t ___length, bool ___sign>
101 finline void convert_to(vint<___length, ___sign>& v ) const {
102 return value.convert_to(v.value);
103 }
104
105 template<class T>
106 finline void convert_to( T& v, if_integral(T) ) const {
107 return value.convert_to(v);
108 }
109
110 finline std::string to_string(int base = 10,
111 int str_size = 0, char str_fill = '0') const {
112 return value.to_string(base,str_size,str_fill);
113 }
114
115 std::string to_debug_string(int base = 10,
116 int str_size = 0, char str_fill = '0') const {
117 return value.to_debug_string(base,str_size,str_fill);
118 }
119
120 //-- sub integers ---------------------------------------------------------
121
122 finline bool get_bit(size_t index) const {
123 return value.get_bit(index);
124 }
125
126 finline void set_bit(size_t index, bool v) {
127 value.set_bit(index, v);
128 }
129
130 finline void set_subint(_self& v, size_t index) {
131 value.set_subint(v.value,index);
132 }
133
134 finline void set_subint(uintmax_t v, size_t index) {
135 value.set_subint(v,index);
136 }
137
138 finline _self get_subint(size_t index, size_t length) const {
139 return value.get_subint(index,length);
140 }
141
142 finline uintmax_t get_subint(size_t index) const {
143 return value.get_subint(index);
144 }
145
146 //-- assignment -----------------------------------------------------------
147
148public:
149
150 template<size_t _len, bool _sign>
151 finline void assign( const vint<_len,_sign>& v ) {
152 value.assign(v.value);
153 }
154
155 template<typename T>
156 finline void assign(const T& v, if_integral(T) ) {
157 value.assign(v);
158 }
159
160 finline void assign(const std::string& text, int base = 10) {
161 value.assign( text, base );
162 }
163
164 void assign(const char*& text, int base = 10) {
165 assign(std::string(text), base);
166 }
167
168 //-- compare operations ---------------------------------------------------
169
170 finline int compare_to(const _self& v) const {
171 return value.compare_to(v.value);
172 }
173
174 template<class T>
175 finline int compare_to(const T& v, if_integral(T) ) const {
176 return value.compare_to(v);
177 }
178
179 //-- arithmetic operations ------------------------------------------------
180
181 // addition
182 template<class T>
183 finline void add(const T& rhs, if_integral(T) ) {value.add(rhs.value);}
184 finline void add(const _self& rhs) {value.add(rhs.value);}
185
186 // subtraction
187 template<class T>
188 finline void sub(const T& rhs, if_integral(T) ) {value.sub(rhs.value);}
189 finline void sub(const _self& rhs) {value.sub(rhs.value);}
190
191 // multiplication
192 template<class T>
193 finline void mul( const T& rhs, if_integral(T) ) {value.mul(rhs);}
194 finline void mul( _self& rhs) {value.mul(rhs.value);}
195 finline void mul( _self& res, const _self& rhs ) const {value.mul(res.value,rhs.value);}
196
197 // division
198 template<class T>
199 finline void div( const T& rhs, if_integral(T) ) {value.div(rhs);}
200 finline void div(_self& rhs) {value.div(rhs.value);}
201 finline void div(_self& res, const _self& rhs ) const {value.div(res.value, rhs);}
202
203 // modulo
204 template<class T>
205 finline void mod( const T& rhs, if_integral(T) ) {value.mod(rhs);}
206 finline void mod(_self& rhs) {value.mod(rhs.value);}
207 finline void mod(_self& res, const _self& rhs ) const {value.mod(res.value, rhs);}
208
209 // exception of modulo: result may be of integral type
210 template<class T>
211 finline void mod( T& res, const T& rhs, if_integral(T) ) const {value.mod(res,rhs);}
212
213 // division with remainder
214 template<class T>
215 finline void divrem(_self& res_div, T& res_rem, const T& rhs, if_integral(T) ) const {
216 value.divrem(res_div.value, res_rem, rhs );
217 }
218 finline void divrem(_self& res_div, _self& res_rem, const _self& rhs ) const {
219 value.divrem(res_div.value, res_rem.value, rhs.value);
220 }
221 template<class T>
222 finline void divrem( T& res_rem, const T& rhs, if_integral(T) ) {
223 value.div(res_rem, rhs.value);
224 }
225 finline void divrem( _self& res_rem, const _self& rhs ) {
226 value.div(res_rem.value, rhs.value);
227 }
228
229 // logarithm to the base of 2
230 finline uintmax_t log2() const {return value.log2();}
231
232 //-- logical bit operations -----------------------------------------------
233
234 finline void or_ (const _self& v) {value.or_(v.value);}
235 finline void and_(const _self& v) {value.and_(v.value);}
236 finline void xor_(const _self& v) {value.xor_(v.value);}
237 finline void complement() {value.complement();}
238 finline void lshift(size_t steps) {value.lshift(steps);}
239 finline void rshift(size_t steps) {value.rshift(steps);}
240
241 //-- integer dynamic ------------------------------------------------------
242
243 inline _self normalized() const {return value.normalized();}
244
245 //-- general information --------------------------------------------------
246
247 finline size_t length() const {return value.length();}
248 finline void set_length(size_t length) {value.set_length(length);}
249 finline bool is_unspecified() {return value.is_unspecified();}
250
251 finline _self max() const {_self v; v.value = value.max(); return v;}
252 finline _self min() const {_self v; v.value = value.min(); return v;}
253 finline _self zero() const {_self v; v.value = value.zero(); return v;}
254
255 //-- general extensions ---------------------------------------------------
256
257 finline void convert_to( std::string& str ) const {
258 str = to_string();
259 }
260
261 /**
262 * Returns true, if the integer is inside the interval [a,b]
263 */
264 finline bool is_between(const _self& a, const _self& b) const {
265 return (a <= b) ?
266 ((*this >= a) && (*this <= b))
267 :
268 ((*this <= a) && (*this >= b))
269 ;
270 }
271
272 /**
273 * Returns true, if the integer is inside the interval [a,b] on
274 * a ring.
275 */
276 finline bool is_between_ring(const _self& a, const _self& b) const {
277 return (b<a) ?
278 (is_between(a, a.max())||is_between(b.zero(), b))
279 :
280 ((*this >= a) && (*this <= b))
281 ;
282 }
283
284 //-- convenience operator overloads ---------------------------------------
285
286 // conversion operators
287 template<typename T> finline T convert() const {T v;convert_to(v);return v;}
288 template<typename T> finline operator T () const {return convert<T>();}
289
290 // assign operators
291 template<class T>
292 finline _self& operator=(const T& copy) {assign(copy);return *this;}
293
294 // add operators
295 template<class T>
296 finline _self& operator+=(const T& v) {add(v);return *this;}
297 template<class T>
298 finline _self& operator++() {add(1);return *this;}
299 template<class T>
300 finline _self operator+ (const T& v) const {_self x=*this;x.add(v);return x;}
301
302 // substract operators
303 template<class T>
304 finline _self& operator-=(const T& v) {sub_model(v);return *this;}
305 finline _self& operator--() {sub(1);return *this;}
306 template<class T>
307 finline _self operator- (const T& v) const {
308 _self x(*this); x.sub_model(v); return x;
309 }
310
311 // multiply operators
312 template<class T> finline _self& operator*=(const T& v) {
313 value.mul(v);
314 return *this;
315 }
316 template<class T> finline _self operator*(const T& v) const {
317 _self res = *this;res.mul(v); return res;
318 }
319
320 // bit shift operators convenience
321 finline _self operator<< (size_t steps) {_self x=*this;return(x<<=steps);}
322 finline _self& operator>>=(size_t steps) {rshift(steps);return *this;}
323 finline _self operator>> (size_t steps) {_self x=*this;return(x<<=steps);}
324 finline _self& operator<<=(size_t steps) {lshift(steps);return *this;}
325
326 // bit operators convenience
327 finline _self& operator&=(const _self& v) {and_(v); return *this;}
328 finline _self operator & (const _self& v) {_self x=*this;return(x&=v);}
329 finline _self& operator|=(const _self& v) {or_(v); return *this;}
330 finline _self operator | (const _self& v) {_self x=*this;return(x|=v);}
331 finline _self& operator^=(const _self& v) {xor_(v);return *this;}
332 finline _self operator^ (const _self& v) {_self x=*this;return(x ^= v);}
333 finline _self operator~() {_self x=*this;return x.complement();}
334
335 // compare operators convenience
336 template<class T>
337 finline bool operator< (const T& v) const {return compare_to(v)< 0;}
338 template<class T>
339 finline bool operator> (const T& v) const {return compare_to(v)> 0;}
340 template<class T>
341 finline bool operator<=(const T& v) const {return compare_to(v)<=0;}
342 template<class T>
343 finline bool operator>=(const T& v) const {return compare_to(v)>=0;}
344 template<class T>
345 finline bool operator==(const T& v) const {return compare_to(v)==0;}
346 template<class T>
347 finline bool operator!=(const T& v) const {return compare_to(v)!=0;}
348};
349
350template<size_t l, bool s>
351std::ostream& operator<<(std::ostream& os, const vint<l, s>& v) {
352 return os << v.value;
353}
354
355#endif /* VINT_HPP_ */
356
Note: See TracBrowser for help on using the repository browser.