00001 #ifndef L1GCTUNSIGNEDINT_H 00002 #define L1GCTUNSIGNEDINT_H 00003 00004 #include <boost/cstdint.hpp> 00005 #include <ostream> 00006 00028 template <int nBits> 00029 class L1GctUnsignedInt { 00030 00031 public: 00032 00034 L1GctUnsignedInt(); 00036 L1GctUnsignedInt(unsigned value); 00038 ~L1GctUnsignedInt(); 00039 00041 template <int mBits> L1GctUnsignedInt(const L1GctUnsignedInt<mBits>& rhs); 00042 00044 void reset() { m_value = static_cast<unsigned>(0); m_overFlow = false; } 00045 00047 void setValue(unsigned value); 00048 00050 void setOverFlow(bool oflow) { m_overFlow = oflow; } 00051 00053 unsigned value() const { return m_value; } 00054 00056 bool overFlow() const { return m_overFlow; } 00057 00059 int size() const { return m_nBits; } 00060 00062 L1GctUnsignedInt operator+ (const L1GctUnsignedInt &rhs) const; 00063 00065 L1GctUnsignedInt& operator= (int value); 00066 00067 protected: 00068 00069 // number of bits 00070 int m_nBits; 00071 00072 // value 00073 unsigned m_value; 00074 00075 // overflow 00076 bool m_overFlow; 00077 00078 static const int MAX_NBITS = 24; 00079 00080 }; 00081 00082 template <int nBits> 00083 std::ostream& operator<<(std::ostream& s, const L1GctUnsignedInt<nBits>& data); 00084 00085 template <int nBits> 00086 L1GctUnsignedInt<nBits>::L1GctUnsignedInt() { 00087 00088 m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ; 00089 this->reset(); 00090 } 00091 00092 template <int nBits> 00093 L1GctUnsignedInt<nBits>::L1GctUnsignedInt(unsigned value) { 00094 00095 m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ; 00096 m_overFlow = false; 00097 this->setValue(value); 00098 } 00099 00100 template <int nBits> 00101 L1GctUnsignedInt<nBits>::~L1GctUnsignedInt() 00102 { 00103 00104 } 00105 00106 // copy contructor to move data between 00107 // representations with different numbers of bits 00108 template <int nBits> 00109 template <int mBits> 00110 L1GctUnsignedInt<nBits>::L1GctUnsignedInt(const L1GctUnsignedInt<mBits>& rhs) { 00111 m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ; 00112 this->setValue( rhs.value() ); 00113 this->setOverFlow( this->overFlow() || rhs.overFlow() ); 00114 } 00115 00116 // set value, checking for overflow 00117 template <int nBits> 00118 void L1GctUnsignedInt<nBits>::setValue(unsigned value) 00119 { 00120 // check for overflow 00121 if (value >= (static_cast<unsigned>(1<<m_nBits)) ) { 00122 m_overFlow = true; 00123 } 00124 00125 // set value with bitmask 00126 m_value = value & ((1<<m_nBits) - 1); 00127 00128 } 00129 00130 // add two unsigneds 00131 template <int nBits> 00132 L1GctUnsignedInt<nBits> 00133 L1GctUnsignedInt<nBits>::operator+ (const L1GctUnsignedInt<nBits> &rhs) const { 00134 00135 // temporary variable for storing the result (need to set its size) 00136 L1GctUnsignedInt<nBits> temp; 00137 00138 unsigned sum; 00139 bool ofl; 00140 00141 // do the addition here 00142 sum = this->value() + rhs.value(); 00143 ofl = this->overFlow() || rhs.overFlow(); 00144 00145 //fill the temporary argument 00146 temp.setValue(sum); 00147 temp.setOverFlow(temp.overFlow() || ofl); 00148 00149 // return the temporary 00150 return temp; 00151 00152 } 00153 00154 // overload assignment by int 00155 template <int nBits> 00156 L1GctUnsignedInt<nBits>& L1GctUnsignedInt<nBits>::operator= (int value) { 00157 00158 this->setValue(value); 00159 return *this; 00160 00161 } 00162 00163 00164 // overload ostream<< 00165 template <int nBits> 00166 std::ostream& operator<<(std::ostream& s, const L1GctUnsignedInt<nBits>& data) { 00167 00168 s << "L1GctUnsignedInt value : " << data.value(); 00169 if (data.overFlow()) { s << " Overflow set! "; } 00170 00171 return s; 00172 00173 } 00174 00175 00176 #endif 00177