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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_MODULO_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_NUM_MODULO_INL
00047
00048 #include "num_common.h"
00049 #include "modulo.h"
00050 #include "basic_ops.h"
00051
00052
00053
00054 namespace lass
00055 {
00056 namespace num
00057 {
00058
00059
00060
00061 template <unsigned N, typename T>
00062 Modulo<N, T>::Modulo(TParam iValue):
00063 value_(mod(iValue, N))
00064 {
00065 LASS_ASSERT(static_cast<T>(N) > 0 && static_cast<T>(N) < NumTraits<T>::max);
00066 }
00067
00068
00069
00070 template <unsigned N, typename T> inline
00071 Modulo<N, T> Modulo<N, T>::operator+() const
00072 {
00073 return *this;
00074 }
00075
00076
00077
00078 template <unsigned N, typename T>
00079 Modulo<N, T> Modulo<N, T>::operator-() const
00080 {
00081 return Modulo<N, T>(-value_);
00082 }
00083
00084
00085
00086 template <unsigned N, typename T>
00087 Modulo<N, T>& Modulo<N, T>::operator++()
00088 {
00089 ++value_;
00090 if (value_ == N)
00091 {
00092 value_ = 0;
00093 }
00094 LASS_ASSERT(isInRange(value_));
00095 return *this;
00096 }
00097
00098
00099
00100 template <unsigned N, typename T>
00101 Modulo<N, T>& Modulo<N, T>::operator--()
00102 {
00103 if (value_ == 0)
00104 {
00105 value_ = N;
00106 }
00107 --value_;
00108 LASS_ASSERT(isInRange(value_));
00109 return *this;
00110 }
00111
00112
00113
00114 template <unsigned N, typename T>
00115 Modulo<N, T> Modulo<N, T>::operator++(int)
00116 {
00117 Modulo<N, T> result(*this);
00118 ++*this;
00119 return result;
00120 }
00121
00122
00123
00124 template <unsigned N, typename T>
00125 Modulo<N, T> Modulo<N, T>::operator--(int)
00126 {
00127 Modulo<N, T> result(*this);
00128 --*this;
00129 return result;
00130 }
00131
00132
00133
00134 template <unsigned N, typename T>
00135 Modulo<N, T>& Modulo<N, T>::operator+=(const Modulo<N, T>& iOther)
00136 {
00137 value_ += iOther.value_;
00138 if (value_ >= static_cast<T>(N))
00139 {
00140 value_ -= N;
00141 }
00142 LASS_ASSERT(isInRange(value_));
00143 return *this;
00144 }
00145
00146
00147
00148 template <unsigned N, typename T>
00149 Modulo<N, T>& Modulo<N, T>::operator-=(const Modulo<N, T>& iOther)
00150 {
00151 value_ -= iOther.value_;
00152 if (value_ < 0)
00153 {
00154 value_ += N;
00155 }
00156 LASS_ASSERT(isInRange(value_));
00157 return *this;
00158 }
00159
00160
00161
00162 template <unsigned N, typename T>
00163 Modulo<N, T>& Modulo<N, T>::operator*=(const Modulo<N, T>& iOther)
00164 {
00165 value_ *= iOther.value_;
00166 value_ = mod(value_, N);
00167 LASS_ASSERT(isInRange(value_));
00168 return *this;
00169 }
00170
00171
00172
00173 template <unsigned N, typename T>
00174 Modulo<N, T>& Modulo<N, T>::operator/=(const Modulo<N, T>& iOther)
00175 {
00176 value_ /= iOther.value_;
00177 value_ = mod(value_, N);
00178 LASS_ASSERT(isInRange(value_));
00179 return *this;
00180 }
00181
00182
00183
00184 template <unsigned N, typename T> inline
00185 Modulo<N, T>::operator T() const
00186 {
00187 return value_;
00188 }
00189
00190
00191
00192 template <unsigned N, typename T> inline
00193 typename Modulo<N, T>::TParam Modulo<N, T>::value() const
00194 {
00195 return value_;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 template <unsigned N, typename T>
00207 bool Modulo<N, T>::isInRange(TParam iValue) const
00208 {
00209 return iValue >= 0 && iValue < static_cast<T>(N);
00210 }
00211
00212
00213
00214
00215
00216 template <unsigned N, typename T>
00217 bool operator==(const Modulo<N, T>& iA, const Modulo<N, T>& iB)
00218 {
00219 return iA.value() == iB.value();
00220 }
00221
00222
00223
00224 template <unsigned N, typename T>
00225 bool operator!=(const Modulo<N, T>& iA, const Modulo<N, T>& iB)
00226 {
00227 return !(iA == iB);
00228 }
00229
00230
00231
00232 template <unsigned N, typename T>
00233 bool operator<(const Modulo<N, T>& iA, const Modulo<N, T>& iB)
00234 {
00235 return iA.value() < iB.value_();
00236 }
00237
00238
00239
00240 template <unsigned N, typename T>
00241 bool operator>(const Modulo<N, T>& iA, const Modulo<N, T>& iB)
00242 {
00243 return iB < iA;
00244 }
00245
00246
00247
00248 template <unsigned N, typename T>
00249 bool operator<=(const Modulo<N, T>& iA, const Modulo<N, T>& iB)
00250 {
00251 return !(iB < iA);
00252 }
00253
00254
00255
00256 template <unsigned N, typename T>
00257 bool operator>=(const Modulo<N, T>& iA, const Modulo<N, T>& iB)
00258 {
00259 return !(iA < iB);
00260 }
00261
00262
00263
00264 template <unsigned N, typename T>
00265 std::ostream& operator<<(std::ostream& oS, Modulo<N, T> iM)
00266 {
00267 oS << iM.value();
00268 return oS;
00269 }
00270
00271
00272
00273 template <unsigned N, typename T>
00274 std::istream& operator>>(std::istream& iS, Modulo<N, T>& iM)
00275 {
00276 int result;
00277 LASS_ENFORCE(iS) >> result;
00278 iM = Modulo<N, T>(result);
00279 return iS;
00280 }
00281
00282
00283
00284 }
00285
00286 }
00287
00288 #endif
00289
00290