00001 /** 00002 * \file RandomType.hpp 00003 * \brief Class to hold bit-width and unsigned type 00004 * 00005 * This provides a simple class to couple a bit-width and an unsigned type 00006 * capable of holding all the bits. In addition is offers static methods for 00007 * I/O and checksumming. 00008 * 00009 * Written by <a href="http://charles.karney.info/">Charles Karney</a> 00010 * <charles@karney.com> and licensed under the LGPL. For more information, see 00011 * http://charles.karney.info/random/ 00012 **********************************************************************/ 00013 #if !defined(RANDOMTYPE_HPP) 00014 #define RANDOMTYPE_HPP "$Id: RandomType.hpp 6490 2008-11-10 21:53:54Z ckarney $" 00015 00016 #include <limits> 00017 #include <string> 00018 #include <iostream> 00019 00020 namespace RandomLib { 00021 /** 00022 * \brief Class to hold bit-width and unsigned type 00023 * 00024 * This provides a simple class to couple a bit-width and an unsigned type 00025 * capable of holding all the bits. In addition is offers static methods for 00026 * I/O and checksumming. 00027 **********************************************************************/ 00028 template<int bits, typename UIntType> 00029 class RandomType { 00030 public: 00031 /** 00032 * The unsigned C++ type 00033 **********************************************************************/ 00034 typedef UIntType type; 00035 /** 00036 * The number of significant bits 00037 **********************************************************************/ 00038 static const unsigned width = bits; 00039 /** 00040 * A mask for the significant bits. 00041 **********************************************************************/ 00042 static const type mask = 00043 ~type(0) >> (std::numeric_limits<type>::digits - width); 00044 /** 00045 * The minimum representable value 00046 **********************************************************************/ 00047 static const type min = type(0); 00048 /** 00049 * The maximum representable value 00050 **********************************************************************/ 00051 static const type max = mask; 00052 /** 00053 * A combined masking and casting operation 00054 **********************************************************************/ 00055 template<typename IntType> static type cast(IntType x) throw() 00056 { return type(x) & mask; } 00057 /** 00058 * Read a data value from a stream of 32-bit quantities (binary or text) 00059 **********************************************************************/ 00060 static void Read32(std::istream& is, bool bin, type& x) 00061 throw(std::ios::failure); 00062 /** 00063 * Read the data value to a stream of 32-bit quantities (binary or text) 00064 **********************************************************************/ 00065 static void Write32(std::ostream& os, bool bin, int& cnt, type x) 00066 throw(std::ios::failure); 00067 /** 00068 * Accumulate a checksum of a integer into a 32-bit check. This implements 00069 * a very simple checksum and is intended to avoid accidental corruption 00070 * only. 00071 **********************************************************************/ 00072 static void CheckSum(type n, uint32_t& check) throw(); 00073 }; 00074 00075 /** 00076 * The standard unit for 32-bit quantities 00077 **********************************************************************/ 00078 typedef RandomType<32, uint32_t> Random_u32; 00079 /** 00080 * The standard unit for 64-bit quantities 00081 **********************************************************************/ 00082 typedef RandomType<64, uint64_t> Random_u64; 00083 00084 /// \cond SKIP 00085 00086 // Accumulate a checksum of a 32-bit quantity into check 00087 template<> 00088 inline void Random_u32::CheckSum(Random_u32::type n, Random_u32::type& check) 00089 throw() { 00090 // Circular shift left by one bit and add new word. 00091 check = (check << 1 | (check >> 31 & Random_u32::type(1))) + n; 00092 check &= Random_u32::mask; 00093 } 00094 00095 // Accumulate a checksum of a 64-bit quantity into check 00096 template<> 00097 inline void Random_u64::CheckSum(Random_u64::type n, Random_u32::type& check) 00098 throw() { 00099 Random_u32::CheckSum(Random_u32::cast(n >> 32), check); 00100 Random_u32::CheckSum(Random_u32::cast(n ), check); 00101 } 00102 /// \endcond 00103 00104 } // namespace RandomLib 00105 00106 #endif // RANDOMTYPE_HPP