Servus  1.5.1
C++ network oriented utilities including a zeroconf implementation
servus::uint128_t Class Reference

A base type for 128 bit unsigned integer values. More...

#include <uint128_t.h>

+ Collaboration diagram for servus::uint128_t:

Public Member Functions

 uint128_t (const unsigned long long low_=0)
 Construct a new 128 bit integer with a default value.
 
 uint128_t (const unsigned long low_)
 Construct a new 128 bit integer with a default value.
 
 uint128_t (const int low_)
 Construct a new 128 bit integer with a default value.
 
 uint128_t (const uint64_t high_, const uint64_t low_)
 Construct a new 128 bit integer with default values.
 
 uint128_t (const std::string &string)
 Construct a new 128 bit integer from a string representation.
 
bool isUUID () const
 
uint128_toperator= (const servus::uint128_t &rhs)
 Assign another 128 bit value. More...
 
uint128_toperator= (const uint64_t rhs)
 Assign another 64 bit value. More...
 
uint128_toperator= (const int rhs)
 Assign an integer value. More...
 
uint128_toperator= (const std::string &from)
 Assign an 128 bit value from a std::string. More...
 
bool operator== (const servus::uint128_t &rhs) const
 
bool operator!= (const servus::uint128_t &rhs) const
 
bool operator== (const unsigned long long &low_) const
 
bool operator!= (const unsigned long long &low_) const
 
bool operator< (const servus::uint128_t &rhs) const
 
bool operator> (const servus::uint128_t &rhs) const
 
bool operator<= (const servus::uint128_t &rhs) const
 
bool operator>= (const servus::uint128_t &rhs) const
 
uint128_toperator++ ()
 Increment the value. More...
 
uint128_toperator-- ()
 Decrement the value. More...
 
uint128_toperator+= (const servus::uint128_t &rhs)
 Add value and return the new value. More...
 
const uint64_t & low () const
 
const uint64_t & high () const
 
uint64_t & low ()
 
uint64_t & high ()
 
std::string getShortString () const
 
std::string getString () const
 
template<class Archive >
void serialize (Archive &ar, const unsigned int)
 Serialize this object to a boost archive. More...
 

Detailed Description

A base type for 128 bit unsigned integer values.

Example:

/* Copyright (c) 2010-2016, Stefan Eilemann <eile@equalizergraphics.com>
* Juan Hernando <jhernando@fi.upm.es>
*
* This file is part of Servus <https://github.com/HBPVIS/Servus>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// Tests the functionality of universally unique identifiers and 128 bit ints
#define BOOST_TEST_MODULE servus_uint128_t
#include <boost/test/unit_test.hpp>
#include <boost/functional/hash.hpp>
#include <boost/unordered_map.hpp>
#include <iostream>
#include <servus/uint128_t.h>
#include <mutex>
#include <random>
#include <thread>
const size_t N_THREADS = 10;
const size_t N_UUIDS = 10000;
typedef boost::unordered_map<servus::uint128_t, bool> TestHash;
namespace boost
{
template <>
struct hash<servus::uint128_t>
{
std::size_t operator()(const servus::uint128_t& in) const
{
hash<uint64_t> forward;
return forward(in.high() ^ in.low());
}
};
}
void testConvertUint128ToUUID();
void testIncrement();
BOOST_AUTO_TEST_CASE(basic)
{
servus::uint128_t id1 = servus::make_UUID();
BOOST_CHECK(id1 != servus::uint128_t());
BOOST_CHECK(id1 != id2);
BOOST_CHECK(id1.isUUID());
BOOST_CHECK(!id2.isUUID());
id2 = servus::make_UUID();
BOOST_CHECK(id1 != id2);
BOOST_CHECK(id2.isUUID());
id1 = id2;
BOOST_CHECK_EQUAL(id1, id2);
servus::uint128_t* id4 = new servus::uint128_t(servus::make_UUID());
BOOST_CHECK_EQUAL(id1, *id3);
BOOST_CHECK(*id4 != *id3);
*id4 = *id3;
BOOST_CHECK_EQUAL(*id4, *id3);
delete id3;
delete id4;
BOOST_CHECK_EQUAL(id5, servus::uint128_t());
BOOST_CHECK_EQUAL(id5, id6);
const servus::uint128_t& empty = servus::make_uint128("");
const servus::uint128_t& fox =
servus::make_uint128("The quick brown fox jumps over the lazy dog.");
// Values from http://en.wikipedia.org/wiki/MD5#MD5_hashes
BOOST_CHECK(empty != fox);
BOOST_CHECK_EQUAL(empty, servus::uint128_t(0xD41D8CD98F00B204ull,
0xE9800998ECF8427Eull));
BOOST_CHECK_EQUAL(fox, servus::uint128_t(0xE4D909C290D0FB1Cull,
0xA068FFADDF22CBD0ull));
const servus::uint128_t& stringFox = servus::make_uint128(
std::string("The quick brown fox jumps over the lazy dog."));
BOOST_CHECK_EQUAL(fox, stringFox);
const servus::uint128_t random = servus::make_UUID();
const uint16_t high = random.high();
const int32_t low = random.low();
id6 = servus::uint128_t(high, low);
BOOST_CHECK_EQUAL(id6.high(), high);
BOOST_CHECK_EQUAL(id6.low(), uint64_t(low));
id6 = servus::uint128_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);
id6 = std::string();
BOOST_CHECK_EQUAL(id6.high(), 0);
BOOST_CHECK_EQUAL(id6.low(), 0);
std::cout << id6 << std::endl; // for coverage
id6 = std::string("0xD41D8CD98F00B204\\0580xE9800998ECF8427E");
BOOST_CHECK_EQUAL(id6.high(), 0xD41D8CD98F00B204ull);
BOOST_CHECK_EQUAL(id6.low(), 0xE9800998ECF8427Eull);
std::cout << id6 << std::endl; // for coverage
}
class Thread
{
public:
void run()
{
size_t i = N_UUIDS;
while (i--)
{
const servus::uint128_t uuid = servus::make_UUID();
{
// Boost.Test is not thread safe
std::unique_lock<std::mutex> lock(_mutex);
BOOST_CHECK(uuid.isUUID());
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)
{
servus::uint128_t uuid(j->first);
BOOST_CHECK_EQUAL(uuid, j->first);
std::ostringstream stream;
stream << uuid;
uuid = stream.str();
BOOST_CHECK_EQUAL(uuid, j->first);
// BOOST_CHECK_EQUAL fails to compile
BOOST_CHECK(first.find(uuid) == first.end());
first[uuid] = true;
}
}
}
BOOST_AUTO_TEST_CASE(convert_uint128_to_uuid)
{
const uint64_t low = 1212;
const uint64_t high = 2314;
servus::uint128_t test128(high, low);
BOOST_CHECK_EQUAL(test128.low(), low);
BOOST_CHECK_EQUAL(test128.high(), high);
testUUID = test128;
const servus::uint128_t compare128 = testUUID;
BOOST_CHECK_EQUAL(compare128, test128);
}
BOOST_AUTO_TEST_CASE(increment)
{
servus::uint128_t test128(0, 0);
++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 = servus::uint128_t(0, std::numeric_limits<uint64_t>::max());
++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());
}

Definition at line 48 of file uint128_t.h.

Member Function Documentation

std::string servus::uint128_t::getShortString ( ) const
inline
Returns
a short, but not necessarily unique, string of the value.

Definition at line 251 of file uint128_t.h.

std::string servus::uint128_t::getString ( ) const
inline
Returns
the full string representation of the value.

Definition at line 261 of file uint128_t.h.

References high(), and low().

+ Here is the call graph for this function:

const uint64_t& servus::uint128_t::high ( ) const
inline
Returns
the reference to the high 64 bits of this 128 bit value.

Definition at line 245 of file uint128_t.h.

Referenced by getString(), isUUID(), and serialize().

+ Here is the caller graph for this function:

uint64_t& servus::uint128_t::high ( )
inline
Returns
the reference to the high 64 bits of this 128 bit value.

Definition at line 249 of file uint128_t.h.

bool servus::uint128_t::isUUID ( ) const
inline
Returns
true if the uint128_t is a generated universally unique identifier.

Definition at line 101 of file uint128_t.h.

References high().

+ Here is the call graph for this function:

const uint64_t& servus::uint128_t::low ( ) const
inline
Returns
the reference to the lower 64 bits of this 128 bit value.

Definition at line 243 of file uint128_t.h.

Referenced by getString(), and serialize().

+ Here is the caller graph for this function:

uint64_t& servus::uint128_t::low ( )
inline
Returns
the reference to the lower 64 bits of this 128 bit value.

Definition at line 247 of file uint128_t.h.

bool servus::uint128_t::operator!= ( const servus::uint128_t rhs) const
inline
Returns
true if the values are different, false otherwise.

Definition at line 140 of file uint128_t.h.

bool servus::uint128_t::operator!= ( const unsigned long long &  low_) const
inline
Returns
true if the values are different, false otherwise.

Definition at line 156 of file uint128_t.h.

References uint128_t().

+ Here is the call graph for this function:

uint128_t& servus::uint128_t::operator++ ( )
inline

Increment the value.

Definition at line 212 of file uint128_t.h.

uint128_t& servus::uint128_t::operator+= ( const servus::uint128_t rhs)
inline

Add value and return the new value.

Definition at line 231 of file uint128_t.h.

uint128_t& servus::uint128_t::operator-- ( )
inline

Decrement the value.

Definition at line 222 of file uint128_t.h.

bool servus::uint128_t::operator< ( const servus::uint128_t rhs) const
inline
Returns
true if this value is smaller than the RHS value.

Definition at line 164 of file uint128_t.h.

bool servus::uint128_t::operator<= ( const servus::uint128_t rhs) const
inline
Returns
true if this value is smaller or equal than the RHS value.

Definition at line 189 of file uint128_t.h.

uint128_t& servus::uint128_t::operator= ( const servus::uint128_t rhs)
inline

Assign another 128 bit value.

Definition at line 103 of file uint128_t.h.

Referenced by operator=().

+ Here is the caller graph for this function:

uint128_t& servus::uint128_t::operator= ( const uint64_t  rhs)
inline

Assign another 64 bit value.

Definition at line 111 of file uint128_t.h.

uint128_t& servus::uint128_t::operator= ( const int  rhs)
inline

Assign an integer value.

Definition at line 119 of file uint128_t.h.

References operator=().

+ Here is the call graph for this function:

uint128_t& servus::uint128_t::operator= ( const std::string &  from)

Assign an 128 bit value from a std::string.

bool servus::uint128_t::operator== ( const servus::uint128_t rhs) const
inline
Returns
true if the values are equal, false if not.

Definition at line 132 of file uint128_t.h.

bool servus::uint128_t::operator== ( const unsigned long long &  low_) const
inline
Returns
true if the values are equal, false otherwise.

Definition at line 148 of file uint128_t.h.

References uint128_t().

+ Here is the call graph for this function:

bool servus::uint128_t::operator> ( const servus::uint128_t rhs) const
inline
Returns
true if this value is bigger than the rhs value.

Definition at line 176 of file uint128_t.h.

bool servus::uint128_t::operator>= ( const servus::uint128_t rhs) const
inline
Returns
true if this value is smaller or equal than the RHS value.

Definition at line 202 of file uint128_t.h.

template<class Archive >
void servus::uint128_t::serialize ( Archive &  ar,
const unsigned  int 
)
inline

Serialize this object to a boost archive.

Definition at line 271 of file uint128_t.h.

References high(), and low().

+ Here is the call graph for this function:


The documentation for this class was generated from the following file: