00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef MTL_DILATED_INT_INCLUDE
00015 #define MTL_DILATED_INT_INCLUDE
00016
00017 #include <boost/numeric/mtl/detail/masked_dilation_tables.hpp>
00018 #include <iostream>
00019
00020 namespace mtl { namespace dilated {
00021
00022 template <typename T>
00023 struct even_bits
00024 {
00025 static T const value = T(-1) / T(3);
00026 };
00027
00028 template <typename T>
00029 struct odd_bits
00030 {
00031 static T const value = ~even_bits<T>::value;
00032 };
00033
00034
00035 template <typename T, T BitMask, bool Normalized>
00036 struct masking
00037 {
00038 inline void operator() (T& x) const
00039 {
00040 x &= BitMask;
00041 }
00042 };
00043
00044
00045 template <typename T, T BitMask>
00046 struct masking<T, BitMask, false>
00047 {
00048 inline void operator() (T& x) const
00049 {
00050 static T const anti_mask = ~BitMask;
00051 x |= anti_mask;
00052 }
00053 };
00054
00055 template <typename T, T BitMask>
00056 struct last_bit;
00057
00058 template <typename T, T BitMask, bool IsZero>
00059 struct last_bit_helper {
00060 static T const tmp = BitMask >> 1;
00061 static T const value = BitMask & 1 ? 1 : last_bit<T, tmp>::value << 1;
00062 };
00063
00064 template <typename T, T BitMask>
00065 struct last_bit_helper<T, BitMask, true> {
00066 static T const value = 0;
00067 };
00068
00069 template <typename T, T BitMask>
00070 struct last_bit
00071 {
00072 static T const value = last_bit_helper<T, BitMask, BitMask == 0>::value;
00073 };
00074
00075
00076 template <typename T, T BitMask, bool Normalized>
00077 struct dilated_int
00078 {
00079 typedef T value_type;
00080 typedef dilated_int<T, BitMask, Normalized> self;
00081
00082 typedef masking<T, BitMask, Normalized> clean_carry;
00083 typedef masking<T, BitMask, !Normalized> init_carry;
00084
00085 static T const bit_mask = BitMask,
00086 anti_mask = ~BitMask,
00087 dilated_zero = Normalized ? 0 : anti_mask,
00088 dilated_one = dilated_zero + last_bit<T, bit_mask>::value;
00089 protected:
00090 masked_dilation_tables<T, bit_mask> mask_tables;
00091
00092
00093
00094 public:
00095 T i;
00096
00097 void dilate(T x)
00098 {
00099 static const T to_switch_on = Normalized ? 0 : anti_mask;
00100 i = mask<bit_mask>(x) | to_switch_on;
00101 }
00102
00103 public:
00104
00105
00106 dilated_int()
00107 {
00108 i = Normalized ? 0 : anti_mask;
00109 }
00110
00111
00112 explicit dilated_int(T x)
00113 {
00114 dilate(x);
00115 }
00116
00117
00118 T undilate()
00119 {
00120 return unmask<bit_mask>(i);
00121 }
00122
00123 T dilated_value() const
00124 {
00125 return i;
00126 }
00127
00128 self& operator= (self const& x)
00129 {
00130 i = x.i;
00131 return *this;
00132 }
00133
00134 self& operator= (T x)
00135 {
00136 dilate(x);
00137 return *this;
00138 }
00139
00140 self& operator++ ()
00141 {
00142 static T const x = Normalized ? bit_mask : T(-1);
00143 i -= x;
00144 clean_carry()(i);
00145 return *this;
00146 }
00147
00148 self operator++ (int)
00149 {
00150 self tmp(*this);
00151 ++*this;
00152 return tmp;
00153 }
00154
00155 self& operator+= (self const& x)
00156 {
00157 init_carry()(i);
00158 i+= x.i;
00159 clean_carry()(i);
00160 return *this;
00161 }
00162
00163 self operator+ (self const& x)
00164 {
00165 self tmp(*this);
00166 return tmp += x;
00167 }
00168
00169 self& operator-- ()
00170 {
00171 i -= dilated_one;
00172 clean_carry()(i);
00173 return *this;
00174 }
00175
00176 self operator-- (int)
00177 {
00178 self tmp(*this);
00179 --*this;
00180 return tmp;
00181 }
00182
00183 self& operator-= (self const& x)
00184 {
00185 i -= x.i;
00186 clean_carry()(i);
00187 return *this;
00188 }
00189
00190 self operator- (self const& x) const
00191 {
00192 self tmp(*this);
00193 return tmp -= x;
00194 }
00195
00196
00197 self& advance(int inc)
00198 {
00199 value_type incv(inc >= 0 ? inc : -inc);
00200 self incd(incv);
00201 if (inc >= 0)
00202 operator+=(incd);
00203 else
00204 operator-=(incd);
00205 return *this;
00206 }
00207
00208 bool operator== (self const& x) const
00209 {
00210 return i == x.i;
00211 }
00212
00213 bool operator!= (self const& x) const
00214 {
00215 return i != x.i;
00216 }
00217
00218 bool operator<= (self const& x) const
00219 {
00220 return i <= x.i;
00221 }
00222
00223 bool operator< (self const& x) const
00224 {
00225 return i < x.i;
00226 }
00227
00228 bool operator>= (self const& x) const
00229 {
00230 return i >= x.i;
00231 }
00232
00233 bool operator> (self const& x) const
00234 {
00235 return i > x.i;
00236 }
00237
00238
00239 };
00240
00241 }
00242
00243 using dilated::dilated_int;
00244
00245 }
00246
00247 template <typename T, T BitMask, bool Normalized>
00248 inline std::ostream& operator<< (std::ostream& os, mtl::dilated::dilated_int<T, BitMask, Normalized> d)
00249 {
00250 os.setf(std::ios_base::hex, std::ios_base::basefield);
00251 return os << d.i;
00252 }
00253
00254 #endif // MTL_DILATED_INT_INCLUDE