//! \brief Restricts the instantiation of a class to one static object without locks
//! \details This class safely initializes a static object in a multithreaded environment without using locks (for portability). Note that if two threads call Ref() at the same time, they may get back different references, and one object may end up being memory leaked. This is by design.
//! \brief Bounds checking replacement for \p memcpy
//! \param dest pointer to the desination memory block
//! \param sizeInBytes the size of the desination memory block, in bytes
//! \param src pointer to the source memory block
//! \param count the size of the source memory block, in bytes
//! \throws InvalidArgument
//! \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially unsafe functions like \p memcpy, \p strcpy and \p memmove. However, not all standard libraries provides them, like Glibc. The library's \p memcpy_s is a near-drop in replacement. Its only a near-replacement because the library's version throws an \p InvalidArgument on a bounds violation.
//! \note \p memcpy_s will \p assert the pointers \p src and \p dest are not \p NULL in debug builds. Passing \p NULL for either pointer is undefined behavior.
//! \brief Bounds checking replacement for \p memmove
//! \param dest pointer to the desination memory block
//! \param sizeInBytes the size of the desination memory block, in bytes
//! \param src pointer to the source memory block
//! \param count the size of the source memory block, in bytes
//! \throws InvalidArgument
//! \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially unsafe functions like \p memcpy, \p strcpy and \p memmove. However, not all standard libraries provides them, like Glibc. The library's \p memmove_s is a near-drop in replacement. Its only a near-replacement because the library's version throws an \p InvalidArgument on a bounds violation.
//! \note \p memcmove_s will \p assert the pointers \p src and \p dest are not \p NULL in debug builds. Passing \p NULL for either pointer is undefined behavior.
// C++Builder 2010 workaround: can't use std::memcpy_s because it doesn't allow 0 lengths
# define memcpy_s CryptoPP::memcpy_s
# define memmove_s CryptoPP::memmove_s
#endif
#endif // __STDC_WANT_SECURE_LIB__
//! \brief Memory block initializer and eraser that attempts to survive optimizations
//! \param ptr pointer to the memory block being written
//! \param value the integer value to write for each byte
//! \param num the size of the source memory block, in bytes
//! \details Internally the function calls \p memset with the value \p value, and receives the return value from \p memset as a <tt>volatile</tt> pointer.
inlinevoid*memset_z(void*ptr,intvalue,size_tnum)
{
// avoid extranous warning on GCC 4.3.2 Ubuntu 8.10
#if CRYPTOPP_GCC_VERSION >= 30001
if(__builtin_constant_p(num)&&num==0)
returnptr;
#endif
volatilevoid*x=memset(ptr,value,num);
returnconst_cast<void*>(x);
}
//! \brief Replacement function for \p std::min
//! \param a the first value
//! \param b the second value
//! \returns the minimum value based on a comparison of <tt>b < a</tt> using <tt>operator<</tt>
//! \details \p STDMIN was provided because the library could not use \p std::min or \p std::max in MSVC60 or Cygwin 1.1.0
//! \returns 1 if the number 1-bits in the value is odd, 0 otherwise
template<classT>
unsignedintParity(Tvalue)
{
for(unsignedinti=8*sizeof(value)/2;i>0;i/=2)
value^=value>>i;
return(unsignedint)value&1;
}
//! \brief Returns the number of 8-bit bytes or octets required for a value
//! \param value the value to test
//! \returns the minimum number of 8-bit bytes or octets required to represent a value
template<classT>
unsignedintBytePrecision(constT&value)
{
if(!value)
return0;
unsignedintl=0,h=8*sizeof(value);
while(h-l>8)
{
unsignedintt=(l+h)/2;
if(value>>t)
l=t;
else
h=t;
}
returnh/8;
}
//! \brief Returns the number of bits required for a value
//! \param value the value to test
//! \returns the maximum number of bits required to represent a value.
template<classT>
unsignedintBitPrecision(constT&value)
{
if(!value)
return0;
unsignedintl=0,h=8*sizeof(value);
while(h-l>1)
{
unsignedintt=(l+h)/2;
if(value>>t)
l=t;
else
h=t;
}
returnh;
}
//! Determines the number of trailing 0-bits in a value
//! \param v the 32-bit value to test
//! \returns the number of trailing 0-bits in \p v, starting at the least significant bit position
//! \details \p TrailingZeros returns the number of trailing 0-bits in \p v, starting at the least significant bit position. The return value is undefined if there are no 1-bits set in the value \p v.
//! \note The function does \a not return 0 if no 1-bits are set because 0 collides with a 1-bit at the 0-th position.
//! Determines the number of trailing 0-bits in a value
//! \param v the 64-bit value to test
//! \returns the number of trailing 0-bits in \p v, starting at the least significant bit position
//! \details \p TrailingZeros returns the number of trailing 0-bits in \p v, starting at the least significant bit position. The return value is undefined if there are no 1-bits set in the value \p v.
//! \note The function does \a not return 0 if no 1-bits are set because 0 collides with a 1-bit at the 0-th position.
//! \brief Truncates the value to the specified number of bits.
//! \param value the value to truncate or mask
//! \param bits the number of bits to truncate or mask
//! \returns the value truncated to the specified number of bits, starting at the least significant bit position
//! \details This function masks the low-order bits of value and returns the result. The mask is created with <tt>(1 << bits) - 1</tt>.
template<classT>
inlineTCrop(Tvalue,size_tbits)
{
if(bits<8*sizeof(value))
returnT(value&((T(1)<<bits)-1));
else
returnvalue;
}
//! \brief Returns the number of 8-bit bytes or octets required for the specified number of bits
//! \param bitCount the number of bits
//! \returns the minimum number of 8-bit bytes or octets required by bitCount
//! \details \p BitsToBytes is effectively a ceiling function based on 8-bit bytes.
inlinesize_tBitsToBytes(size_tbitCount)
{
return((bitCount+7)/(8));
}
//! \brief Returns the number of words required for the specified number of bytes
//! \param byteCount the number of bytes
//! \returns the minimum number of words required by byteCount
//! \details \p BytesToWords is effectively a ceiling function based on <tt>WORD_SIZE</tt>. <tt>WORD_SIZE</tt> is defined in config.h
inlinesize_tBytesToWords(size_tbyteCount)
{
return((byteCount+WORD_SIZE-1)/WORD_SIZE);
}
//! \brief Returns the number of words required for the specified number of bits
//! \param bitCount the number of bits
//! \returns the minimum number of words required by bitCount
//! \details \p BitsToWords is effectively a ceiling function based on <tt>WORD_BITS</tt>. <tt>WORD_BITS</tt> is defined in config.h
inlinesize_tBitsToWords(size_tbitCount)
{
return((bitCount+WORD_BITS-1)/(WORD_BITS));
}
//! \brief Returns the number of double words required for the specified number of bits
//! \param bitCount the number of bits
//! \returns the minimum number of double words required by bitCount
//! \details \p BitsToDwords is effectively a ceiling function based on <tt>2*WORD_BITS</tt>. <tt>WORD_BITS</tt> is defined in config.h
inlinesize_tBitsToDwords(size_tbitCount)
{
return((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
}
//! Performs an XOR of a buffer with a mask
//! \param buf the buffer to XOR with the mask
//! \param mask the mask to XOR with the buffer
//! \param count the size of the buffers, in bytes
//! \details The function effectively visits each element in the buffers and performs <tt>buf[i] ^= mask[i]</tt>. \p buf and \p mask must be of equal size.
//! Performs an XOR of an input buffer with a mask and stores the result in an output buffer
//! \param output the destination buffer
//! \param input the source buffer to XOR with the mask
//! \param mask the mask buffer to XOR with the input buffer
//! \param count the size of the buffers, in bytes
//! \details The function effectively visits each element in the buffers and performs <tt>output[i] = input[i] ^ mask[i]</tt>. \p output, \p input and \p mask must be of equal size.
//! \brief Performs a near constant-time comparison of two equally sized buffers
//! \param buf1 the first buffer
//! \param buf2 the second buffer
//! \param count the size of the buffers, in bytes
//! \details The function effectively Performs an XOR of the elements in two equally sized buffers and retruns a result based on the XOR operation. The function is near constant-time because CPU micro-code timings could affect the "constant-ness". Calling code is responsible for mitigating timing attacks if the buffers are \a not equally sized.
//! \returns true if \p value is a power of 2, false otherwise
//! \details The function effectively creates a mask of <tt>value - 1</tt> and returns the result of an AND operation compared to 0. If \p value is 0 or less than 0, then the function freturns \p false.
template<classT>
inlineboolIsPowerOf2(constT&value)
{
returnvalue>0&&(value&(value-1))==0;
}
//! \brief Tests whether the residue of a value is a power of 2
//! \param a the value to test
//! \param b the value to use to reduce \a to its residue
//! \returns true if <tt>a%b</tt> is a power of 2, false otherwise
//! \details The function effectively creates a mask of <tt>b - 1</tt> and returns the result of an AND operation compared to 0. \b must be a power of 2 or the result is undefined.
template<classT1,classT2>
inlineT2ModPowerOf2(constT1&a,constT2&b)
{
assert(IsPowerOf2(b));
returnT2(a)&(b-1);
}
//! \brief Rounds a value down to a multiple of a second value
//! \param n the value to reduce
//! \param m the value to reduce \n to to a multiple
//! \returns the possibly unmodified value \n
//! \details \p RoundDownToMultipleOf is effectively a floor function based on \p m. The function returns the value <tt>n - n%m</tt>. If \p n is a multiple of \p m, then the original value is returned.
//! \brief Rounds a value up to a multiple of a second value
//! \param n the value to reduce
//! \param m the value to reduce \n to to a multiple
//! \returns the possibly unmodified value \n
//! \details \p RoundUpToMultipleOf is effectively a ceiling function based on \p m. The function returns the value <tt>n + n%m</tt>. If \p n is a multiple of \p m, then the original value is returned. If the value \p n would overflow, then an \p InvalidArgument exception is thrown.
//! \brief Returns the minimum alignment requirements of a type
//! \param dummy an unused Visual C++ 6.0 workaround
//! \returns the minimum alignment requirements of a type, in bytes
//! \details Internally the function calls C++11's \p alignof if available. If not available, the the function uses compiler specific extensions such as \p __alignof and \p _alignof_. \p sizeof(T) is used if the others are not available. In all cases, if \p CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is defined, then the function returns 1.
// GCC 4.6 (circa 2008) and above aggressively uses vectorization.
#if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS)
if(sizeof(T)<16)
return1;
#endif
CRYPTOPP_UNUSED(dummy);
#if defined(CRYPTOPP_CXX11_ALIGNOF)
returnalignof(T);
#elif (_MSC_VER >= 1300)
return__alignof(T);
#elif defined(__GNUC__)
return__alignof__(T);
#elif CRYPTOPP_BOOL_SLOW_WORD64
returnUnsignedMin(4U,sizeof(T));
#else
returnsizeof(T);
#endif
}
//! \brief Determines whether \p ptr is aligned to a minimum value
//! \param ptr the pointer being checked for alignment
//! \param alignment the alignment value to test the pointer against
//! \returns true if \p ptr is aligned on at least \p align boundary
//! \details Internally the function tests whether \p alignment is 1. If so, the function returns true. If not, then the function effectively performs a modular reduction and returns \p true if the residue is 0
//! \brief Returns \p NativeByteOrder as an enumerated \p ByteOrder value
//! \returns \p LittleEndian if the native byte order is little-endian, and \p BigEndian if the native byte order is big-endian
//! \details \p NativeByteOrder is a typedef depending on the platform. If \p IS_LITTLE_ENDIAN is set in \headerfile config.h, then \p GetNativeByteOrder returns \p LittleEndian. If \p IS_BIG_ENDIAN is set, then \p GetNativeByteOrder returns \p BigEndian.
//! \note There are other byte orders besides little- and big-endian, and they include bi-endian and PDP-endian. If a system is neither little-endian nor big-endian, then a compile time error occurs.
inlineByteOrderGetNativeByteOrder()
{
returnNativeByteOrder::ToEnum();
}
//! \brief Determines whether \p order follows native byte ordering
//! \param order the ordering being tested against native byte ordering
//! \returns true if \p order follows native byte ordering, false otherwise
inlineboolNativeByteOrderIs(ByteOrderorder)
{
returnorder==GetNativeByteOrder();
}
//! \brief Performs a saturating subtract.
//! \param a the minuend
//! \param b the subtrahend
//! \returns the difference produced by the saturating subtract
//! \details Saturating arithmetic restricts results to a fixed range. Results that are less than 0 are clamped at 0.
template<classT1,classT2>
inlineT1SaturatingSubtract(constT1&a,constT2&b)
{
returnT1((a>b)?(a-b):0);
}
//! \brief Returns the direction the cipher is being operated
//! \param obj the cipher object being queried
//! \returns /p ENCRYPTION if the cipher \p obj is being operated in its forward direction, \p DECRYPTION otherwise
//! \details ciphers can be operated in a "forward" direction (encryption) and a "reverse" direction (decryption). The operations do not have to be symmetric, meaning a second application of the transformation does not necessariy return the original message. That is, <tt>E(D(m))</tt> may not equal <tt>E(E(m))</tt>; and <tt>D(E(m))</tt> may not equal <tt>D(D(m))</tt>.
//! \details In the normal course of running a program, a request for memory normally succeeds. If a call to \p AlignedAllocate or \p UnalignedAllocate fails, then \p CallNewHandler is called in an effort to recover. Internally, \p CallNewHandler calls \p set_new_handler(NULL) in an effort to free memory. There is no guarantee \p CallNewHandler will be able to procure more memory so an allocation succeeds. If the call to \p set_new_handler fails, then \p CallNewHandler throws a \p bad_alloc exception.
CRYPTOPP_DLLvoidCRYPTOPP_APICallNewHandler();
//! \brief Performs an addition with carry on a block of bytes
//! \param inout the byte block
//! \param size the size of the block, in bytes
//! \details Performs an addition with carry by adding 1 on a block of bytes starting at the least significant byte. Once \p carry is 0, the function terminates and returns to the caller.
//! \note The function is not constant time because it stops processing when the \p carry is 0.
//! \brief Performs an addition with carry on a block of bytes
//! \param output the destination block of bytes
//! \param input the source block of bytes
//! \param size the size of the block
//! \details Performs an addition with carry on a block of bytes starting at the least significant byte. Once \p carry is 0, the remaining bytes from \p input are copied to \p output using \p memcpy.
//! \details The function is \a close to near-constant time because it operates on all the bytes in the blocks.
//! \brief Converts a wide character C-string to a multibyte \p string
//! \param str a C-string consiting of wide characters
//! \param throwOnError specifies the function should throw an \p InvalidArgument exception on error
//! \returns \p str converted to a multibyte string or an empty string.
//! \details This function converts a wide string to a string using C++ \p wcstombs under the executing thread's locale. A locale must be set before using this function, and it can be set with \p setlocale.
//! Upon success, the converted string is returned. Upon failure with \p throwOnError as \p false, the function returns an empty string. Upon failure with \p throwOnError as \p true, the function throws InvalidArgument exception.
//! \note If you try to convert, say, the Chinese character for "bone" from UTF-16 (0x9AA8) to UTF-8 (0xE9 0xAA 0xA8), then you should ensure the locales are available. If the locales are not available, then a 0x21 error is returned which eventually results in an \p InvalidArgument exception
//! \details \p AlignedAllocate is primarily used when the data will be proccessed by MMX and SSE2 instructions. The assembly language routines rely on the alignment. If the alignment is not respected, then a \p SIGBUS is generated under Unix and an \p EXCEPTION_DATATYPE_MISALIGNMENT is generated under Windows.
//! \note \p AlignedAllocate and \p AlignedDeallocate are available when \p CRYPTOPP_BOOL_ALIGN16 is defined. \p CRYPTOPP_BOOL_ALIGN16 is defined in config.h
//! \brief Frees a buffer allocated with \p AlignedAllocate
//! \param ptr the buffer to free
//! \note \p AlignedAllocate and \p AlignedDeallocate are available when \p CRYPTOPP_BOOL_ALIGN16 is defined. \p CRYPTOPP_BOOL_ALIGN16 is defined in config.h
//! \param y the number of bit positions to rotate the value
//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
//! \note \p rotlFixed attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register counterparts.
template<classT>inlineTrotlFixed(Tx,unsignedinty)
{
// Portable rotate that reduces to single instruction...
// and https://llvm.org/bugs/show_bug.cgi?id=24226
staticconstunsignedintTHIS_SIZE=sizeof(T)*8;
staticconstunsignedintMASK=THIS_SIZE-1;
assert(y<THIS_SIZE);
returnT((x<<y)|(x>>(-y&MASK)));
}
//! \brief Performs a right rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
//! \note \p rotrFixed attempts to enlist a <tt>rotate IMM</tt> instruction because its often faster than a <tt>rotate REG</tt>. Immediate rotates can be up to three times faster than their register counterparts.
template<classT>inlineTrotrFixed(Tx,unsignedinty)
{
// Portable rotate that reduces to single instruction...
// and https://llvm.org/bugs/show_bug.cgi?id=24226
staticconstunsignedintTHIS_SIZE=sizeof(T)*8;
staticconstunsignedintMASK=THIS_SIZE-1;
assert(y<THIS_SIZE);
returnT((x>>y)|(x<<(-y&MASK)));
}
//! \brief Performs a left rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
//! \note \p rotlVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
//! \param y the number of bit positions to rotate the value
//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
//! \details \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior. Use \p rotlMod if the rotate amount \p y is outside the range.
//! \note \p rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
//! \param y the number of bit positions to rotate the value
//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
//! \details \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
template<classT>inlineTrotlMod(Tx,unsignedinty)
{
staticconstunsignedintTHIS_SIZE=sizeof(T)*8;
staticconstunsignedintMASK=THIS_SIZE-1;
returnT((x<<(y&MASK))|(x>>(-y&MASK)));
}
//! \brief Performs a right rotate
//! \param x the value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a portable C/C++ implementation. The value to be rotated can be 8 to 64-bits.
//! \details \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotrVariable will use either <tt>rotate IMM</tt> or <tt>rotate REG</tt>.
template<classT>inlineTrotrMod(Tx,unsignedinty)
{
staticconstunsignedintTHIS_SIZE=sizeof(T)*8;
staticconstunsignedintMASK=THIS_SIZE-1;
returnT((x>>(y&MASK))|(x<<(-y&MASK)));
}
#ifdef _MSC_VER
//! \brief Performs a left rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
assert(y<8*sizeof(x));
returny?_lrotl(x,static_cast<byte>(y)):x;
}
//! \brief Performs a right rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
assert(y<8*sizeof(x));
returny?_lrotr(x,static_cast<byte>(y)):x;
}
//! \brief Performs a left rotate
//! \param x the 32-bit value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 32-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions
//! \brief Performs a left rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
assert(y<8*sizeof(x));
returny?_rotl64(x,static_cast<byte>(y)):x;
}
//! \brief Performs a right rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
// Uses Microsoft <stdlib.h> call, bound to C/C++ language rules.
assert(y<8*sizeof(x));
returny?_rotr64(x,static_cast<byte>(y)):x;
}
//! \brief Performs a left rotate
//! \param x the 64-bit value to rotate
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotl</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y must be in the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \note \p rotlFixed will \p assert in Debug builds if \p is outside the allowed range.
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \param y the number of bit positions to rotate the value
//! \details This is a Microsoft specific implementation using <tt>_lrotr</tt> provided by \headerfile <stdlib.h>. The value to be rotated is 64-bits. \p y is reduced to the range <tt>[0, sizeof(T)*8 - 1]</tt> to avoid undefined behavior.
//! \details The template overload of \p BitReverse operates on signed and unsigned values. Internally the size of \p T is checked, and then \p value is cast to a \p byte, \p word16, \p word32 or \p word64. After the cast, the appropriate \p BitReverse overload is called.
template<classT>
inlineTBitReverse(Tvalue)
{
if(sizeof(T)==1)
return(T)BitReverse((byte)value);
elseif(sizeof(T)==2)
return(T)BitReverse((word16)value);
elseif(sizeof(T)==4)
return(T)BitReverse((word32)value);
else
{
assert(sizeof(T)==8);
return(T)BitReverse((word64)value);
}
}
//! \brief Reverses bytes in a value depending upon endianess
//! \param order the \p ByteOrder the data is represented
//! \param value the value to conditionally reverse
//! \details Internally, the \p ConditionalByteReverse calls \p NativeByteOrderIs. If \p order matches native byte order, then the original \p value is returned. If not, then \p ByteReverse is called on the value before returning to the caller.