Lunchbox
1.6.0
|
00001 00002 /* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com> 00003 * 2010-2012, Stefan Eilemann <eile@eyescale.ch> 00004 * 2010, Daniel Nachbaur <danielnachbaur@gmail.com> 00005 * 00006 * This library is free software; you can redistribute it and/or modify it under 00007 * the terms of the GNU Lesser General Public License version 2.1 as published 00008 * by the Free Software Foundation. 00009 * 00010 * This library is distributed in the hope that it will be useful, but WITHOUT 00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00012 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00013 * details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this library; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 00020 #ifndef LUNCHBOX_UINT128_H 00021 #define LUNCHBOX_UINT128_H 00022 00023 #include <lunchbox/api.h> 00024 #include <sstream> 00025 00026 #ifdef _MSC_VER 00027 // Don't include <lunchbox/types.h> to be minimally intrusive for apps 00028 // using uint128_t 00029 # include <basetsd.h> 00030 typedef UINT64 uint64_t; 00031 #else 00032 # include <stdint.h> 00033 #endif 00034 00035 namespace lunchbox 00036 { 00037 class uint128_t; 00038 std::ostream& operator << ( std::ostream& os, const uint128_t& id ); 00039 00041 class uint128_t 00042 { 00043 public: 00048 uint128_t( const uint64_t low_ = 0 ) 00049 : _high( 0 ), _low( low_ ) {} 00050 00055 explicit uint128_t( const uint64_t high_, const uint64_t low_ ) 00056 : _high( high_ ), _low( low_ ) {} 00057 00062 explicit uint128_t( const std::string& string ) 00063 : _high( 0 ), _low( 0 ) { *this = string; } 00064 00066 uint128_t& operator = ( const uint128_t& rhs ) 00067 { 00068 _high = rhs._high; 00069 _low = rhs._low; 00070 return *this; 00071 } 00072 00074 uint128_t& operator = ( const uint64_t rhs ) 00075 { 00076 _high = 0; 00077 _low = rhs; 00078 return *this; 00079 } 00080 00082 LUNCHBOX_API uint128_t& operator = ( const std::string& from ); 00083 00088 bool operator == ( const uint128_t& rhs ) const 00089 { return _high == rhs._high && _low == rhs._low; } 00090 00095 bool operator != ( const uint128_t& rhs ) const 00096 { return _high != rhs._high || _low != rhs._low; } 00097 00102 bool operator < ( const uint128_t& rhs ) const 00103 { 00104 if( _high < rhs._high ) 00105 return true; 00106 if( _high > rhs._high ) 00107 return false; 00108 return _low < rhs._low; 00109 } 00110 00115 bool operator > ( const uint128_t& rhs ) const 00116 { 00117 if( _high > rhs._high ) 00118 return true; 00119 if( _high < rhs._high ) 00120 return false; 00121 return _low > rhs._low; 00122 } 00123 00129 bool operator <= ( const uint128_t& rhs ) const 00130 { 00131 if( _high < rhs._high ) 00132 return true; 00133 if( _high > rhs._high ) 00134 return false; 00135 return _low <= rhs._low; 00136 } 00137 00143 bool operator >= ( const uint128_t& rhs ) const 00144 { 00145 if( _high > rhs._high ) 00146 return true; 00147 if( _high < rhs._high ) 00148 return false; 00149 return _low >= rhs._low; 00150 } 00151 00153 uint128_t& operator ++() 00154 { 00155 ++_low; 00156 if( !_low ) 00157 ++_high; 00158 00159 return *this; 00160 } 00161 00163 uint128_t& operator --() 00164 { 00165 if( !_low ) 00166 --_high; 00167 --_low; 00168 return *this; 00169 } 00170 00172 uint128_t& operator +=( const uint128_t& rhs ) 00173 { 00174 const uint64_t oldLow = _low; 00175 _low += rhs._low; 00176 if( _low < oldLow ) // overflow 00177 _high += rhs._high + 1; 00178 else 00179 _high += rhs._high; 00180 return *this; 00181 } 00182 00184 const uint64_t& low() const { return _low; } 00186 const uint64_t& high() const { return _high; } 00187 00189 uint64_t& low() { return _low; } 00191 uint64_t& high() { return _high; } 00192 00194 std::string getShortString() const 00195 { 00196 std::stringstream stream; 00197 stream << std::hex << _high << _low; 00198 const std::string str = stream.str(); 00199 return str.substr( 0, 3 ) + ".." + 00200 str.substr( str.length() - 3, std::string::npos ); 00201 } 00202 00204 std::string getString() const 00205 { 00206 std::stringstream stream; 00207 stream << *this; 00208 return stream.str(); 00209 } 00210 00212 template< class Archive > 00213 void serialize( Archive& ar, const unsigned int version ) 00214 { 00215 ar & low(); 00216 ar & high(); 00217 } 00218 00220 static LUNCHBOX_API const uint128_t ZERO; 00221 00222 private: 00223 uint64_t _high; 00224 uint64_t _low; 00225 }; 00226 00228 inline std::ostream& operator << ( std::ostream& os, const uint128_t& id ) 00229 { 00230 if( id.high() == 0 ) 00231 os << std::hex << id.low() << std::dec; 00232 else 00233 os << std::hex << id.high() << ':' << id.low() << std::dec; 00234 return os; 00235 } 00236 00238 inline uint128_t operator+ ( const uint128_t& a, const uint64_t& b ) 00239 { 00240 uint128_t result = a; 00241 result.low() += b; 00242 if( result.low() < a.low( )) 00243 ++result.high(); 00244 return result; 00245 }; 00246 00248 inline uint128_t operator+ ( const uint128_t& a, const uint128_t& b ) 00249 { 00250 uint128_t result = a; 00251 result += b; 00252 return result; 00253 }; 00254 00256 inline uint128_t operator- ( const uint128_t& a, const uint64_t& b ) 00257 { 00258 uint128_t result = a; 00259 result.low() -= b; 00260 if( result.low() > a.low( )) 00261 --result.high(); 00262 return result; 00263 }; 00264 00266 inline uint128_t operator & ( const uint128_t& a, const uint128_t& b ) 00267 { 00268 uint128_t result = a; 00269 result.high() &= b.high(); 00270 result.low() &= b.low(); 00271 return result; 00272 } 00273 00275 inline uint128_t operator | ( const uint128_t& a, const uint128_t& b ) 00276 { 00277 uint128_t result = a; 00278 result.high() |= b.high(); 00279 result.low() |= b.low(); 00280 return result; 00281 } 00282 00291 LUNCHBOX_API uint128_t make_uint128( const char* string ); 00292 } 00293 #endif // LUNCHBOX_UINT128_H