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