Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

misc.h

00001 #ifndef CRYPTOPP_MISC_H
00002 #define CRYPTOPP_MISC_H
00003 
00004 #include "cryptlib.h"
00005 
00006 #ifdef INTEL_INTRINSICS
00007 #include <stdlib.h>
00008 #endif
00009 
00010 NAMESPACE_BEGIN(CryptoPP)
00011 
00012 // ************** compile-time assertion ***************
00013 
00014 template <bool b>
00015 struct CompileAssert
00016 {
00017         static char dummy[2*b-1];
00018 };
00019 
00020 #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
00021 #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
00022 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
00023 #else
00024 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
00025 #endif
00026 #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
00027 #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
00028 
00029 // ************** misc classes ***************
00030 
00031 class CRYPTOPP_DLL Empty
00032 {
00033 };
00034 
00035 template <class BASE1, class BASE2>
00036 class TwoBases : public BASE1, public BASE2
00037 {
00038 };
00039 
00040 template <class BASE1, class BASE2, class BASE3>
00041 class ThreeBases : public BASE1, public BASE2, public BASE3
00042 {
00043 };
00044 
00045 template <class T>
00046 class ObjectHolder
00047 {
00048 protected:
00049         T m_object;
00050 };
00051 
00052 class NotCopyable
00053 {
00054 public:
00055         NotCopyable() {}
00056 private:
00057     NotCopyable(const NotCopyable &);
00058     void operator=(const NotCopyable &);
00059 };
00060 
00061 // ************** misc functions ***************
00062 
00063 // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
00064 template <class _Tp> inline const _Tp& STDMIN(const _Tp& __a, const _Tp& __b)
00065 {
00066         return __b < __a ? __b : __a;
00067 }
00068 
00069 template <class _Tp> inline const _Tp& STDMAX(const _Tp& __a, const _Tp& __b)
00070 {
00071         return  __a < __b ? __b : __a;
00072 }
00073 
00074 #define RETURN_IF_NONZERO(x) unsigned int returnedValue = x; if (returnedValue) return returnedValue
00075 
00076 // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
00077 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
00078 // these may be faster on other CPUs/compilers
00079 // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
00080 // #define GETBYTE(x, y) (((byte *)&(x))[y])
00081 
00082 CRYPTOPP_DLL unsigned int Parity(unsigned long);
00083 CRYPTOPP_DLL unsigned int BytePrecision(unsigned long);
00084 CRYPTOPP_DLL unsigned int BitPrecision(unsigned long);
00085 CRYPTOPP_DLL unsigned long Crop(unsigned long, unsigned int size);
00086 
00087 inline unsigned int BitsToBytes(unsigned int bitCount)
00088 {
00089         return ((bitCount+7)/(8));
00090 }
00091 
00092 inline unsigned int BytesToWords(unsigned int byteCount)
00093 {
00094         return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
00095 }
00096 
00097 inline unsigned int BitsToWords(unsigned int bitCount)
00098 {
00099         return ((bitCount+WORD_BITS-1)/(WORD_BITS));
00100 }
00101 
00102 CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, unsigned int count);
00103 CRYPTOPP_DLL void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count);
00104 
00105 template <class T>
00106 inline bool IsPowerOf2(T n)
00107 {
00108         return n > 0 && (n & (n-1)) == 0;
00109 }
00110 
00111 template <class T1, class T2>
00112 inline T2 ModPowerOf2(T1 a, T2 b)
00113 {
00114         assert(IsPowerOf2(b));
00115         return T2(a) & (b-1);
00116 }
00117 
00118 template <class T>
00119 inline T RoundDownToMultipleOf(T n, T m)
00120 {
00121         return n - (IsPowerOf2(m) ? ModPowerOf2(n, m) : (n%m));
00122 }
00123 
00124 template <class T>
00125 inline T RoundUpToMultipleOf(T n, T m)
00126 {
00127         return RoundDownToMultipleOf(n+m-1, m);
00128 }
00129 
00130 template <class T>
00131 inline unsigned int GetAlignment(T *dummy=NULL) // VC60 workaround
00132 {
00133 #if (_MSC_VER >= 1300)
00134         return __alignof(T);
00135 #elif defined(__GNUC__)
00136         return __alignof__(T);
00137 #else
00138         return sizeof(T);
00139 #endif
00140 }
00141 
00142 inline bool IsAlignedOn(const void *p, unsigned int alignment)
00143 {
00144         return IsPowerOf2(alignment) ? ModPowerOf2((unsigned int)p, alignment) == 0 : (unsigned int)p % alignment == 0;
00145 }
00146 
00147 template <class T>
00148 inline bool IsAligned(const void *p, T *dummy=NULL)     // VC60 workaround
00149 {
00150         return IsAlignedOn(p, GetAlignment<T>());
00151 }
00152 
00153 #ifdef IS_LITTLE_ENDIAN
00154         typedef LittleEndian NativeByteOrder;
00155 #else
00156         typedef BigEndian NativeByteOrder;
00157 #endif
00158 
00159 inline ByteOrder GetNativeByteOrder()
00160 {
00161         return NativeByteOrder::ToEnum();
00162 }
00163 
00164 inline bool NativeByteOrderIs(ByteOrder order)
00165 {
00166         return order == GetNativeByteOrder();
00167 }
00168 
00169 template <class T>              // can't use <sstream> because GCC 2.95.2 doesn't have it
00170 std::string IntToString(T a, unsigned int base = 10)
00171 {
00172         if (a == 0)
00173                 return "0";
00174         bool negate = false;
00175         if (a < 0)
00176         {
00177                 negate = true;
00178                 a = 0-a;        // VC .NET does not like -a
00179         }
00180         std::string result;
00181         while (a > 0)
00182         {
00183                 T digit = a % base;
00184                 result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
00185                 a /= base;
00186         }
00187         if (negate)
00188                 result = "-" + result;
00189         return result;
00190 }
00191 
00192 template <class T1, class T2>
00193 inline T1 SaturatingSubtract(T1 a, T2 b)
00194 {
00195         CRYPTOPP_COMPILE_ASSERT_INSTANCE(T1(-1)>0, 0);  // T1 is unsigned type
00196         CRYPTOPP_COMPILE_ASSERT_INSTANCE(T2(-1)>0, 1);  // T2 is unsigned type
00197         return T1((a > b) ? (a - b) : 0);
00198 }
00199 
00200 template <class T>
00201 inline CipherDir GetCipherDir(const T &obj)
00202 {
00203         return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
00204 }
00205 
00206 // ************** rotate functions ***************
00207 
00208 template <class T> inline T rotlFixed(T x, unsigned int y)
00209 {
00210         assert(y < sizeof(T)*8);
00211         return (x<<y) | (x>>(sizeof(T)*8-y));
00212 }
00213 
00214 template <class T> inline T rotrFixed(T x, unsigned int y)
00215 {
00216         assert(y < sizeof(T)*8);
00217         return (x>>y) | (x<<(sizeof(T)*8-y));
00218 }
00219 
00220 template <class T> inline T rotlVariable(T x, unsigned int y)
00221 {
00222         assert(y < sizeof(T)*8);
00223         return (x<<y) | (x>>(sizeof(T)*8-y));
00224 }
00225 
00226 template <class T> inline T rotrVariable(T x, unsigned int y)
00227 {
00228         assert(y < sizeof(T)*8);
00229         return (x>>y) | (x<<(sizeof(T)*8-y));
00230 }
00231 
00232 template <class T> inline T rotlMod(T x, unsigned int y)
00233 {
00234         y %= sizeof(T)*8;
00235         return (x<<y) | (x>>(sizeof(T)*8-y));
00236 }
00237 
00238 template <class T> inline T rotrMod(T x, unsigned int y)
00239 {
00240         y %= sizeof(T)*8;
00241         return (x>>y) | (x<<(sizeof(T)*8-y));
00242 }
00243 
00244 #ifdef INTEL_INTRINSICS
00245 
00246 #pragma intrinsic(_lrotl, _lrotr)
00247 
00248 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00249 {
00250         assert(y < 32);
00251         return y ? _lrotl(x, y) : x;
00252 }
00253 
00254 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00255 {
00256         assert(y < 32);
00257         return y ? _lrotr(x, y) : x;
00258 }
00259 
00260 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00261 {
00262         assert(y < 32);
00263         return _lrotl(x, y);
00264 }
00265 
00266 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00267 {
00268         assert(y < 32);
00269         return _lrotr(x, y);
00270 }
00271 
00272 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00273 {
00274         return _lrotl(x, y);
00275 }
00276 
00277 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00278 {
00279         return _lrotr(x, y);
00280 }
00281 
00282 #endif // #ifdef INTEL_INTRINSICS
00283 
00284 #ifdef PPC_INTRINSICS
00285 
00286 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00287 {
00288         assert(y < 32);
00289         return y ? __rlwinm(x,y,0,31) : x;
00290 }
00291 
00292 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00293 {
00294         assert(y < 32);
00295         return y ? __rlwinm(x,32-y,0,31) : x;
00296 }
00297 
00298 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00299 {
00300         assert(y < 32);
00301         return (__rlwnm(x,y,0,31));
00302 }
00303 
00304 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00305 {
00306         assert(y < 32);
00307         return (__rlwnm(x,32-y,0,31));
00308 }
00309 
00310 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00311 {
00312         return (__rlwnm(x,y,0,31));
00313 }
00314 
00315 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00316 {
00317         return (__rlwnm(x,32-y,0,31));
00318 }
00319 
00320 #endif // #ifdef PPC_INTRINSICS
00321 
00322 // ************** endian reversal ***************
00323 
00324 template <class T>
00325 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
00326 {
00327         if (order == LITTLE_ENDIAN_ORDER)
00328                 return GETBYTE(value, index);
00329         else
00330                 return GETBYTE(value, sizeof(T)-index-1);
00331 }
00332 
00333 inline byte ByteReverse(byte value)
00334 {
00335         return value;
00336 }
00337 
00338 inline word16 ByteReverse(word16 value)
00339 {
00340         return rotlFixed(value, 8U);
00341 }
00342 
00343 inline word32 ByteReverse(word32 value)
00344 {
00345 #ifdef PPC_INTRINSICS
00346         // PPC: load reverse indexed instruction
00347         return (word32)__lwbrx(&value,0);
00348 #elif defined(FAST_ROTATE)
00349         // 5 instructions with rotate instruction, 9 without
00350         return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00351 #else
00352         // 6 instructions with rotate instruction, 8 without
00353         value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00354         return rotlFixed(value, 16U);
00355 #endif
00356 }
00357 
00358 #ifdef WORD64_AVAILABLE
00359 inline word64 ByteReverse(word64 value)
00360 {
00361 #ifdef SLOW_WORD64
00362         return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
00363 #else
00364         value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00365         value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00366         return rotlFixed(value, 32U);
00367 #endif
00368 }
00369 #endif
00370 
00371 inline byte BitReverse(byte value)
00372 {
00373         value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00374         value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00375         return rotlFixed(value, 4);
00376 }
00377 
00378 inline word16 BitReverse(word16 value)
00379 {
00380         value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00381         value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00382         value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00383         return ByteReverse(value);
00384 }
00385 
00386 inline word32 BitReverse(word32 value)
00387 {
00388         value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00389         value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00390         value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00391         return ByteReverse(value);
00392 }
00393 
00394 #ifdef WORD64_AVAILABLE
00395 inline word64 BitReverse(word64 value)
00396 {
00397 #ifdef SLOW_WORD64
00398         return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
00399 #else
00400         value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00401         value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00402         value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00403         return ByteReverse(value);
00404 #endif
00405 }
00406 #endif
00407 
00408 template <class T>
00409 inline T BitReverse(T value)
00410 {
00411         if (sizeof(T) == 1)
00412                 return (T)BitReverse((byte)value);
00413         else if (sizeof(T) == 2)
00414                 return (T)BitReverse((word16)value);
00415         else if (sizeof(T) == 4)
00416                 return (T)BitReverse((word32)value);
00417         else
00418         {
00419 #ifdef WORD64_AVAILABLE
00420                 assert(sizeof(T) == 8);
00421                 return (T)BitReverse((word64)value);
00422 #else
00423                 assert(false);
00424                 return 0;
00425 #endif
00426         }
00427 }
00428 
00429 template <class T>
00430 inline T ConditionalByteReverse(ByteOrder order, T value)
00431 {
00432         return NativeByteOrderIs(order) ? value : ByteReverse(value);
00433 }
00434 
00435 template <class T>
00436 void ByteReverse(T *out, const T *in, unsigned int byteCount)
00437 {
00438         assert(byteCount % sizeof(T) == 0);
00439         unsigned int count = byteCount/sizeof(T);
00440         for (unsigned int i=0; i<count; i++)
00441                 out[i] = ByteReverse(in[i]);
00442 }
00443 
00444 template <class T>
00445 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, unsigned int byteCount)
00446 {
00447         if (!NativeByteOrderIs(order))
00448                 ByteReverse(out, in, byteCount);
00449         else if (in != out)
00450                 memcpy(out, in, byteCount);
00451 }
00452 
00453 template <class T>
00454 inline void GetUserKey(ByteOrder order, T *out, unsigned int outlen, const byte *in, unsigned int inlen)
00455 {
00456         const unsigned int U = sizeof(T);
00457         assert(inlen <= outlen*U);
00458         memcpy(out, in, inlen);
00459         memset((byte *)out+inlen, 0, outlen*U-inlen);
00460         ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
00461 }
00462 
00463 inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, byte*)
00464 {
00465         return block[0];
00466 }
00467 
00468 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word16*)
00469 {
00470         return (order == BIG_ENDIAN_ORDER)
00471                 ? block[1] | (block[0] << 8)
00472                 : block[0] | (block[1] << 8);
00473 }
00474 
00475 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word32*)
00476 {
00477         return (order == BIG_ENDIAN_ORDER)
00478                 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
00479                 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
00480 }
00481 
00482 template <class T>
00483 inline T UnalignedGetWord(ByteOrder order, const byte *block, T*dummy=NULL)
00484 {
00485         return UnalignedGetWordNonTemplate(order, block, dummy);
00486 }
00487 
00488 inline void UnalignedPutWord(ByteOrder order, byte *block, byte value, const byte *xorBlock = NULL)
00489 {
00490         block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
00491 }
00492 
00493 inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value, const byte *xorBlock = NULL)
00494 {
00495         if (order == BIG_ENDIAN_ORDER)
00496         {
00497                 block[0] = GETBYTE(value, 1);
00498                 block[1] = GETBYTE(value, 0);
00499         }
00500         else
00501         {
00502                 block[0] = GETBYTE(value, 0);
00503                 block[1] = GETBYTE(value, 1);
00504         }
00505 
00506         if (xorBlock)
00507         {
00508                 block[0] ^= xorBlock[0];
00509                 block[1] ^= xorBlock[1];
00510         }
00511 }
00512 
00513 inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value, const byte *xorBlock = NULL)
00514 {
00515         if (order == BIG_ENDIAN_ORDER)
00516         {
00517                 block[0] = GETBYTE(value, 3);
00518                 block[1] = GETBYTE(value, 2);
00519                 block[2] = GETBYTE(value, 1);
00520                 block[3] = GETBYTE(value, 0);
00521         }
00522         else
00523         {
00524                 block[0] = GETBYTE(value, 0);
00525                 block[1] = GETBYTE(value, 1);
00526                 block[2] = GETBYTE(value, 2);
00527                 block[3] = GETBYTE(value, 3);
00528         }
00529 
00530         if (xorBlock)
00531         {
00532                 block[0] ^= xorBlock[0];
00533                 block[1] ^= xorBlock[1];
00534                 block[2] ^= xorBlock[2];
00535                 block[3] ^= xorBlock[3];
00536         }
00537 }
00538 
00539 template <class T>
00540 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
00541 {
00542         if (assumeAligned)
00543         {
00544                 assert(IsAligned<T>(block));
00545                 return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
00546         }
00547         else
00548                 return UnalignedGetWord<T>(order, block);
00549 }
00550 
00551 template <class T>
00552 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
00553 {
00554         result = GetWord<T>(assumeAligned, order, block);
00555 }
00556 
00557 template <class T>
00558 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
00559 {
00560         if (assumeAligned)
00561         {
00562                 assert(IsAligned<T>(block));
00563                 if (xorBlock)
00564                         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ *reinterpret_cast<const T *>(xorBlock);
00565                 else
00566                         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value);
00567         }
00568         else
00569                 UnalignedPutWord(order, block, value, xorBlock);
00570 }
00571 
00572 template <class T, class B, bool A=true>
00573 class GetBlock
00574 {
00575 public:
00576         GetBlock(const void *block)
00577                 : m_block((const byte *)block) {}
00578 
00579         template <class U>
00580         inline GetBlock<T, B, A> & operator()(U &x)
00581         {
00582                 CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
00583                 x = GetWord<T>(A, B::ToEnum(), m_block);
00584                 m_block += sizeof(T);
00585                 return *this;
00586         }
00587 
00588 private:
00589         const byte *m_block;
00590 };
00591 
00592 template <class T, class B, bool A=true>
00593 class PutBlock
00594 {
00595 public:
00596         PutBlock(const void *xorBlock, void *block)
00597                 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
00598 
00599         template <class U>
00600         inline PutBlock<T, B, A> & operator()(U x)
00601         {
00602                 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
00603                 m_block += sizeof(T);
00604                 if (m_xorBlock)
00605                         m_xorBlock += sizeof(T);
00606                 return *this;
00607         }
00608 
00609 private:
00610         const byte *m_xorBlock;
00611         byte *m_block;
00612 };
00613 
00614 template <class T, class B, bool A=true>
00615 struct BlockGetAndPut
00616 {
00617         // function needed because of C++ grammatical ambiguity between expression-statements and declarations
00618         static inline GetBlock<T, B, A> Get(const void *block) {return GetBlock<T, B, A>(block);}
00619         typedef PutBlock<T, B, A> Put;
00620 };
00621 
00622 template <class T>
00623 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
00624 {
00625         if (!NativeByteOrderIs(order))
00626                 value = ByteReverse(value);
00627 
00628         return std::string((char *)&value, sizeof(value));
00629 }
00630 
00631 template <class T>
00632 T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
00633 {
00634         T value = 0;
00635         memcpy(&value, str.data(), STDMIN(sizeof(value), str.size()));
00636         return NativeByteOrderIs(order) ? value : ByteReverse(value);
00637 }
00638 
00639 // ************** help remove warning on g++ ***************
00640 
00641 template <bool overflow> struct SafeShifter;
00642 
00643 template<> struct SafeShifter<true>
00644 {
00645         template <class T>
00646         static inline T RightShift(T value, unsigned int bits)
00647         {
00648                 return 0;
00649         }
00650 
00651         template <class T>
00652         static inline T LeftShift(T value, unsigned int bits)
00653         {
00654                 return 0;
00655         }
00656 };
00657 
00658 template<> struct SafeShifter<false>
00659 {
00660         template <class T>
00661         static inline T RightShift(T value, unsigned int bits)
00662         {
00663                 return value >> bits;
00664         }
00665 
00666         template <class T>
00667         static inline T LeftShift(T value, unsigned int bits)
00668         {
00669                 return value << bits;
00670         }
00671 };
00672 
00673 template <unsigned int bits, class T>
00674 inline T SafeRightShift(T value)
00675 {
00676         return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
00677 }
00678 
00679 template <unsigned int bits, class T>
00680 inline T SafeLeftShift(T value)
00681 {
00682         return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
00683 }
00684 
00685 NAMESPACE_END
00686 
00687 #endif // MISC_H

Generated on Tue Jul 8 23:34:20 2003 for Crypto++ by doxygen 1.3.2