Generic.h

00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #if !defined(_GENERIC_H)
00019 #define _GENERIC_H
00020 
00021 #include <stdint.h>
00022 
00023 #include <list>
00024 #include <iostream>
00025 #include <ostream>
00026 #include <utility>
00027 #include <vector>
00028 
00029 template <typename T>
00030 inline T abs(T x)
00031 {
00032     return (x < 0) ? -x : x;
00033 }
00034 
00035 //
00036 // this is safe for signed/unsigned:
00037 //
00038 template <typename T>
00039 inline T absDiff(T x, T y)
00040 {
00041     return (x < y) ? (y - x) : (x - y);
00042 }
00043 
00044 //
00045 //
00046 template <typename T>
00047 inline T in(T x, T y, T z)
00048 {
00049     return (x >= y && x < z);
00050 }
00051 
00052 //
00053 // These overloaded operators and functions are largely
00054 // for diagnostic debug printing.  The underlying problem
00055 // is that gdb is unable to decipher any STL use, let alone
00056 // complex STL use.  printf debugging is a poor second choice,
00057 // but these functions at least make it practical to do rapidly.
00058 //
00059 
00060 //
00061 // Write a std::pair to a stream
00062 //
00063 template <typename A, typename B>
00064 std::ostream &operator << (std::ostream &stream, std::pair<A, B> p)
00065 {
00066     stream << "(" << p.first << ", " << p.second << ")";
00067     return stream;
00068 }
00069 
00070 //
00071 // generic vector print -- in normal use, you should
00072 // be able to simply do foostream << somevector, and get
00073 // sane results, provided that the vector elements themselves
00074 // can be written to the stream.
00075 //
00076 // Example code is in Generic.cpp
00077 //
00078 template <typename T>
00079 std::ostream &operator << (std::ostream &stream, std::vector<T> const &v)
00080 {
00081 
00082     typename std::vector<T>::const_iterator i;
00083     for (i = v.begin(); i != v.end(); i++)
00084     {
00085         stream << (i - v.begin()) << ": " << *i << std::endl;
00086     }
00087     return stream;
00088 }
00089 
00090 //
00091 // same overload as above, except for std::list
00092 //
00093 template <typename T>
00094 std::ostream &operator << (std::ostream &stream, std::list<T> const &l)
00095 {
00096 
00097     typename std::list<T>::const_iterator i;
00098     int j = 0;
00099     for (i = l.begin(); i != l.end(); i++, j++)
00100     {
00101         stream << j << ": " << *i << std::endl;
00102     }
00103     return stream;
00104 }
00105 
00106 template <typename TITLE, typename ITEM, typename EXPECT, typename GOT>
00107 void check(int &returnCode, TITLE title, ITEM item, EXPECT expect, GOT got)
00108 {
00109     if (expect!=got)
00110     {
00111         std::cout << "Test " << title << ": expect " << item << " = '" << expect << "', but got '" << got << "'." << std::endl;
00112         returnCode += 1;
00113     }
00114 }
00115 
00116 //
00117 // specialization of template below:
00118 // load a set of lines from a file into a vector of strings.
00119 //
00120 inline std::istream &operator >> (std::istream &stream, std::vector<std::string> &vec)
00121 {
00122     std::string val;
00123     while (true)
00124     {
00125         if (!stream.good()) break;
00126         getline(stream, val);
00127         stream >> val;
00128         vec.push_back(val);
00129     }
00130     return stream;
00131 }
00132 
00133 
00134 //
00135 // read values from a stream, appending to the provided
00136 // vec.  stops when the stream is consumed.
00137 //
00138 template<typename T>
00139 std::istream &operator >> (std::istream &stream, std::vector<T> &vec)
00140 {
00141     T val;
00142     while (true)
00143     {
00144         if (!stream.good()) break;
00145         stream >> val;
00146         vec.push_back(val);
00147     }
00148     return stream;
00149 }
00150 
00151 
00152 #if 0
00153 //
00154 // generic vector of iterators print
00155 //
00156 template <typename T>
00157 std::ostream &operator << (
00158     std::ostream &stream,
00159     std::vector<
00160     std::pair< std::vector<typename T>::iterator , std::vector< typename T>::iterator >
00161     > v
00162 )
00163 {
00164 
00165     typename IteratorType i;
00166     typename std::vector<T>::iterator i;
00167     for (i = v.begin(); i != v.end(); i++)
00168     {
00169         stream << *i << std::endl;
00170     }
00171     return stream;
00172 }
00173 
00174 #endif
00175 
00176 
00177 //
00178 // These are packed set/get functions for dealing with
00179 // packed 1, 2 and 4 bit unsigned values inside of arbitrary
00180 // arrays of data (char */std::vector<char> whatever).
00181 //
00182 template<typename T>
00183 inline uint32_t PackedAccess_1Bit(T byteSequence, uint32_t bitIndex)
00184 {
00185     return (((byteSequence)[bitIndex>>3] >> (bitIndex&0x7)) & 0x1);
00186 }
00187 
00188 template<typename T>
00189 inline void PackedAssign_1Bit(T byteSequence, uint32_t bitIndex, uint32_t value)
00190 {
00191     (byteSequence)[bitIndex>>3] =
00192         ((byteSequence)[bitIndex>>3]
00193         & ~(1<<(bitIndex&0x07)))
00194         | ((value&0x01)<<(bitIndex&0x7));
00195 }
00196 
00197 inline size_t Packed1BitElementCount2Bytes(uint32_t i)
00198 {
00199     return (size_t)(i+7)/8;
00200 }
00201 
00202 template<typename T>
00203 inline uint32_t PackedAccess_2Bit(T byteSequence, uint32_t index)
00204 {
00205     return (((byteSequence)[index>>2] >> ((index&0x3)<<1)) & 0x3);
00206 }
00207 
00208 template<typename T>
00209 inline void PackedAssign_2Bit(T byteSequence, uint32_t index, uint32_t value)
00210 {
00211     (byteSequence)[index>>2] =
00212         ((byteSequence)[index>>2]
00213         & ~(3<<((index&0x03)<<1)))
00214         | ((value&0x03)<<((index&0x3)<<1));
00215 }
00216 
00217 inline size_t Packed2BitElementCount2Bytes(uint32_t i)
00218 {
00219     return (size_t)(i+3)/4;
00220 }
00221 
00222 template<typename T>
00223 inline uint32_t PackedAccess_4Bit(T byteSequence, uint32_t index)
00224 {
00225     return (((byteSequence)[index>>1] >> ((index&0x1)<<2)) & 0xf);
00226 }
00227 
00228 template<typename T>
00229 inline void PackedAssign_4Bit(T byteSequence, uint32_t index, uint32_t value)
00230 {
00231     (byteSequence)[index>>1] =
00232         ((byteSequence)[index>>1]
00233         & ~(7<<((index&0x01)<<2)))
00234         | ((value&0x0f)<<((index&0x1)<<2));
00235 }
00236 
00237 inline size_t Packed4BitElementCount2Bytes(uint32_t i)
00238 {
00239     return (size_t)(i+1)/2;
00240 }
00241 
00242 #endif
Generated on Mon Feb 11 13:45:18 2013 for libStatGen Software by  doxygen 1.6.3