RandomType.hpp
Go to the documentation of this file.
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