#include "sole.h"
|
|
#define SOLE_BUILD_DEMO
|
|
#ifdef SOLE_BUILD_DEMO
|
// g++ users: `g++ demo.cc -std=c++11 -lrt -o sample`
|
// visual studio: `cl.exe demo.cc sole.cpp`
|
|
#include <iostream>
|
|
int main() {
|
sole::uuid u0 = sole::uuid0(), u1 = sole::uuid1(), u4 = sole::uuid4();
|
|
std::cout << "uuid v0 string : " << u0 << std::endl;
|
std::cout << "uuid v0 base62 : " << u0.base62() << std::endl;
|
std::cout << "uuid v0 pretty : " << u0.pretty() << std::endl << std::endl;
|
|
std::cout << "uuid v1 string : " << u1 << std::endl;
|
std::cout << "uuid v1 base62 : " << u1.base62() << std::endl;
|
std::cout << "uuid v1 pretty : " << u1.pretty() << std::endl << std::endl;
|
|
std::cout << "uuid v4 string : " << u4 << std::endl;
|
std::cout << "uuid v4 base62 : " << u4.base62() << std::endl;
|
std::cout << "uuid v4 pretty : " << u4.pretty() << std::endl << std::endl;
|
|
std::cout << "uuid v4 length : " << u4.str().length() << std::endl;
|
|
std::string test("123");
|
std::cout << "test length : " << test.length() << std::endl;
|
u1 = sole::rebuild("F81D4FAE-7DEC-11D0-A765-00A0C91E6BF6");
|
u4 = sole::rebuild("GITheR4tLlg-BagIW20DGja");
|
|
std::cout << "uuid v1 rebuilt : " << u1 << " -> " << u1.pretty() << std::endl;
|
std::cout << "uuid v4 rebuilt : " << u4 << " -> " << u4.pretty() << std::endl;
|
}
|
|
#endif
|
|
#ifdef SOLE_BUILD_TESTS
|
// g++ users: `g++ sole.cxx -std=c++11 -lrt -o tests`
|
// visual studio: `cl.exe sole.cxx`
|
|
#include <cassert>
|
#include <set>
|
#include <ratio>
|
#include <chrono>
|
#include <iostream>
|
|
using namespace sole;
|
|
namespace run
|
{
|
auto epoch = [](){
|
return std::chrono::system_clock::to_time_t( std::chrono::system_clock::now() );
|
};
|
|
template<typename FN>
|
void benchmark( const FN &fn, const std::string &name ) {
|
std::cout << "Benchmarking " << name << "... " << std::flush;
|
|
auto then = epoch();
|
|
while( epoch() == then );
|
then = epoch();
|
|
unsigned c = 0;
|
while( epoch() == then ) c = ( fn(), ++c );
|
|
std::cout << (c) << " uuids/sec" << std::endl;
|
}
|
|
template<typename FN>
|
void tests( const FN &fn ) {
|
unsigned numtests = ~0;
|
std::cout << "Testing for " << numtests << " collisions... " << std::endl;
|
|
auto then = epoch();
|
|
std::set<uuid> all;
|
for( unsigned i = 0; i < numtests; ++i ) {
|
auto now = epoch();
|
if( now != then ) {
|
then = now;
|
double pct6digs = ( int( ( double(i) / (unsigned)(~0) ) * 1e4 ) / double(1e4) );
|
std::cout << '\r' << i << " uuids generated, no collision (" << pct6digs << "%)" << std::flush;
|
}
|
sole::uuid my_uuid = fn();
|
assert( all.find(my_uuid) == all.end() && "error: UUIDs just collided! is std::random_device a real random generator?" );
|
all.insert( my_uuid );
|
}
|
}
|
|
template<typename FN>
|
void verify( const FN &fn ) {
|
std::cout << "Verifying serialization of 1 million UUIDs... " << std::flush;
|
|
for( unsigned i = 0; i < 1000000; ++i ) {
|
sole::uuid uuid = fn();
|
sole::uuid rebuilt1 = sole::rebuild( uuid.str() );
|
sole::uuid rebuilt2 = sole::rebuild( uuid.base62() );
|
assert( rebuilt1 == uuid && "error: rebuild() or .str() failed" );
|
assert( rebuilt2 == uuid && "error: rebuild() or .base62() failed" );
|
}
|
|
std::cout << "ok" << std::endl;
|
}
|
}
|
|
int main() {
|
assert( sizeof(sole::uuid ) * 8 == 128 );
|
assert( sizeof(sole::uuid0().ab) * 8 == 64 );
|
assert( sizeof(sole::uuid0().cd) * 8 == 64 );
|
|
run::benchmark(uuid0, "v0");
|
run::benchmark(uuid1, "v1");
|
run::benchmark(uuid4, "v4");
|
|
run::verify(uuid4); // use fastest implementation
|
|
// run::tests(uuid0); // not applicable
|
// run::tests(uuid1); // not applicable
|
run::tests(uuid4);
|
}
|
|
#endif
|