52 #include <sys/types.h>
68 bool operator==(
const uuid &other )
const;
69 bool operator!=(
const uuid &other )
const;
70 bool operator <(
const uuid &other )
const;
72 std::string base62()
const;
73 std::string str()
const;
75 template<
typename ostream>
76 inline friend ostream &operator<<( ostream &os,
const uuid &
self ) {
77 return os <<
self.str(), os;
85 uuid rebuild( uint64_t ab, uint64_t cd );
86 uuid rebuild(
const std::string &uustr );
91 #pragma warning(disable:4127)
96 struct hash<
sole::uuid > {
99 size_t operator()(
const sole::uuid &uuid )
const {
100 if(
sizeof(
size_t) > 4 ) {
101 return size_t( uuid.ab ^ uuid.cd );
103 uint64_t hash64 = uuid.ab ^ uuid.cd;
104 return size_t( uint32_t( hash64 >> 32 ) ^ uint32_t( hash64 ) );
132 inline bool sole::uuid::operator==(
const sole::uuid &other )
const {
133 return ab == other.ab && cd == other.cd;
135 inline bool sole::uuid::operator!=(
const sole::uuid &other )
const {
136 return !operator==(other);
138 inline bool sole::uuid::operator<(
const sole::uuid &other )
const {
139 if( ab < other.ab )
return true;
140 if( ab > other.ab )
return false;
141 if( cd < other.cd )
return true;
147 inline std::string uuid::str()
const {
148 std::stringstream ss;
149 ss << std::hex << std::nouppercase << std::setfill(
'0');
151 uint32_t a = (ab >> 32);
152 uint32_t b = (ab & 0xFFFFFFFF);
153 uint32_t c = (cd >> 32);
154 uint32_t d = (cd & 0xFFFFFFFF);
156 ss << std::setw(8) << (a) <<
'-';
157 ss << std::setw(4) << (b >> 16) <<
'-';
158 ss << std::setw(4) << (b & 0xFFFF) <<
'-';
159 ss << std::setw(4) << (c >> 16 ) <<
'-';
160 ss << std::setw(4) << (c & 0xFFFF);
161 ss << std::setw(8) << d;
166 inline std::string uuid::base62()
const {
167 int base62len = 10 + 26 + 26;
168 const char base62[] =
170 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
171 "abcdefghijklmnopqrstuvwxyz";
172 char res[24], *end = &res[24]; *(--end) =
'\0';
173 uint64_t rem, AB = ab, CD = cd;
175 rem = CD % base62len;
176 *--end = base62[int(rem)];
181 rem = AB % base62len;
182 *--end = base62[int(rem)];
191 inline uuid uuid4() {
192 static std::random_device rd;
193 static std::uniform_int_distribution<uint64_t> dist(0, (uint64_t)(~0));
200 my.ab = (my.ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;
201 my.cd = (my.cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;
206 inline uuid rebuild( uint64_t ab, uint64_t cd ) {
208 u.ab = ab; u.cd = cd;
212 inline uuid rebuild(
const std::string &uustr ) {
216 auto idx = uustr.find_first_of(
"-");
217 if( idx != std::string::npos ) {
219 if( uustr.find_first_of(
"-",idx+1) == std::string::npos ) {
220 auto rebase62 = [&](
const char *input,
size_t limit ) -> uint64_t {
221 int base62len = 10 + 26 + 26;
222 auto strpos = [](
char ch ) ->
size_t {
223 if( ch >=
'a' )
return ch -
'a' + 10 + 26;
224 if( ch >=
'A' )
return ch -
'A' + 10;
227 uint64_t res = strpos( input[0] );
228 for(
size_t i = 1; i < limit; ++i )
229 res = base62len * res + strpos( input[i] );
232 u.ab = rebase62( &uustr[0], idx );
233 u.cd = rebase62( &uustr[idx+1], uustr.size() - (idx+1) );
237 std::stringstream ss( uustr );
238 if( ss >> std::hex >> a >> sep >> b >> sep >> c >> sep >> d >> sep >> e ) {
240 u.ab = (a << 32) | (b << 16) | c;
241 u.cd = (d << 48) | e;