A base type for 128 bit unsigned integer values.
#define BOOST_TEST_MODULE servus_uint128_t
#include <boost/test/unit_test.hpp>
#include <servus/uint128_t.h>
#include <boost/unordered_map.hpp>
#include <boost/functional/hash.hpp>
#include <iostream>
#ifndef SERVUS_USE_CXX03
# include <mutex>
# include <random>
# include <thread>
const size_t N_THREADS = 10;
#endif
const size_t N_UUIDS = 10000;
typedef boost::unordered_map< servus::uint128_t, bool > TestHash;
namespace boost
{
{
{
hash< uint64_t > forward;
return forward( in.
high() ^ in.
low( ));
}
};
}
void testConvertUint128ToUUID();
void testIncrement();
BOOST_AUTO_TEST_CASE(basic)
{
BOOST_CHECK( id1 != id2 );
id2 = servus::make_UUID();
BOOST_CHECK( id1 != id2 );
BOOST_CHECK( id2.isUUID( ));
id1 = id2;
BOOST_CHECK_EQUAL( id1, id2 );
BOOST_CHECK_EQUAL( id1, *id3 );
BOOST_CHECK( *id4 != *id3 );
*id4 = *id3;
BOOST_CHECK_EQUAL( *id4, *id3 );
delete id3;
delete id4;
BOOST_CHECK_EQUAL( id5, id6 );
"The quick brown fox jumps over the lazy dog." );
BOOST_CHECK( empty != fox );
0xE9800998ECF8427Eull ));
0xA068FFADDF22CBD0ull ));
std::string( "The quick brown fox jumps over the lazy dog." ));
BOOST_CHECK_EQUAL( fox, stringFox );
const int32_t
low = random.
low();
BOOST_CHECK_EQUAL( id6.
low(), uint64_t( low ));
BOOST_CHECK_EQUAL( id6.high(), 0 );
BOOST_CHECK_EQUAL( id6.low(), uint64_t( low ));
id6 = std::string( "0xD41D8CD98F00B204" );
BOOST_CHECK_EQUAL( id6.high(), 0 );
BOOST_CHECK_EQUAL( id6.low(), 0xD41D8CD98F00B204ull );
id6 = std::string( "0xD41D8CD98F00B204:0xE9800998ECF8427E" );
BOOST_CHECK_EQUAL( id6.high(), 0xD41D8CD98F00B204ull );
BOOST_CHECK_EQUAL( id6.low(), 0xE9800998ECF8427Eull );
}
#ifndef SERVUS_USE_CXX03
class Thread
{
public:
void run()
{
size_t i = N_UUIDS;
while( i-- )
{
{
std::unique_lock< std::mutex > lock( _mutex );
BOOST_CHECK( hash.find( uuid ) == hash.end( ));
}
hash[ uuid ] = true;
}
}
TestHash hash;
private:
static std::mutex _mutex;
};
std::mutex Thread::_mutex;
BOOST_AUTO_TEST_CASE(concurrent)
{
Thread maps[ N_THREADS ];
std::thread threads[ N_THREADS ];
const auto startTime = std::chrono::system_clock::now();
for( size_t i = 0; i < N_THREADS; ++i )
threads[ i ] = std::thread( std::bind( &Thread::run, maps[ i ]));
for( size_t i = 0; i < N_THREADS; ++i )
threads[ i ].join();
const std::chrono::duration<double> elapsed =
std::chrono::system_clock::now() - startTime;
std::cerr << N_UUIDS * N_THREADS / elapsed.count()
<< " UUID generations and hash ops / ms" << std::endl;
TestHash& first = maps[0].hash;
for( size_t i = 1; i < N_THREADS; ++i )
{
TestHash& current = maps[i].hash;
for( TestHash::const_iterator j = current.begin();
j != current.end(); ++j )
{
BOOST_CHECK_EQUAL( uuid, j->first );
std::ostringstream stream;
stream << uuid;
uuid = stream.str();
BOOST_CHECK_EQUAL( uuid, j->first );
BOOST_CHECK( first.find( uuid ) == first.end( ));
first[ uuid ] = true;
}
}
}
#endif
BOOST_AUTO_TEST_CASE(convert_uint128_to_uuid)
{
const uint64_t low = 1212;
const uint64_t high = 2314;
BOOST_CHECK_EQUAL( test128.low(),
low );
BOOST_CHECK_EQUAL( test128.high(),
high );
testUUID = test128;
BOOST_CHECK_EQUAL( compare128, test128 );
}
BOOST_AUTO_TEST_CASE(increment)
{
++test128;
BOOST_CHECK_EQUAL( test128.high(), 0 );
BOOST_CHECK_EQUAL( test128.low(), 1 );
--test128;
BOOST_CHECK_EQUAL( test128.high(), 0 );
BOOST_CHECK_EQUAL( test128.low(), 0 );
test128 = test128 + 1;
BOOST_CHECK_EQUAL( test128.high(), 0 );
BOOST_CHECK_EQUAL( test128.low(), 1 );
test128 = test128 - 1;
BOOST_CHECK_EQUAL( test128.high(), 0 );
BOOST_CHECK_EQUAL( test128.low(), 0 );
++test128;
BOOST_CHECK_EQUAL( test128.high(), 1 );
BOOST_CHECK_EQUAL( test128.low(), 0 );
--test128;
BOOST_CHECK_EQUAL( test128.high(), 0 );
BOOST_CHECK_EQUAL( test128.low(), std::numeric_limits< uint64_t >::max( ));
test128 = test128 + 1;
BOOST_CHECK_EQUAL( test128.high(), 1 );
BOOST_CHECK_EQUAL( test128.low(), 0 );
test128 = test128 - 1;
BOOST_CHECK_EQUAL( test128.high(), 0 );
BOOST_CHECK_EQUAL( test128.low(), std::numeric_limits< uint64_t >::max( ));
}