stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,74 @@
/*
* Copyright Andrey Semashev 2013.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file uuid/detail/config.hpp
*
* \brief This header defines configuration macros for Boost.UUID.
*/
#ifndef BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_
#define BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if !defined(BOOST_UUID_NO_SIMD)
#if defined(__GNUC__) && defined(__SSE2__)
// GCC and its pretenders go here
#ifndef BOOST_UUID_USE_SSE2
#define BOOST_UUID_USE_SSE2
#endif
#if defined(__SSE3__) && !defined(BOOST_UUID_USE_SSE3)
#define BOOST_UUID_USE_SSE3
#endif
#if defined(__SSE4_1__) && !defined(BOOST_UUID_USE_SSE41)
#define BOOST_UUID_USE_SSE41
#endif
#elif defined(_MSC_VER)
#if (defined(_M_X64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) && !defined(BOOST_UUID_USE_SSE2)
#define BOOST_UUID_USE_SSE2
#endif
#if defined(__AVX__)
#if !defined(BOOST_UUID_USE_SSE41)
#define BOOST_UUID_USE_SSE41
#endif
#if !defined(BOOST_UUID_USE_SSE3)
#define BOOST_UUID_USE_SSE3
#endif
#if !defined(BOOST_UUID_USE_SSE2)
#define BOOST_UUID_USE_SSE2
#endif
#endif
#endif
// More advanced ISA extensions imply less advanced are also available
#if !defined(BOOST_UUID_USE_SSE3) && defined(BOOST_UUID_USE_SSE41)
#define BOOST_UUID_USE_SSE3
#endif
#if !defined(BOOST_UUID_USE_SSE2) && defined(BOOST_UUID_USE_SSE3)
#define BOOST_UUID_USE_SSE2
#endif
#if !defined(BOOST_UUID_NO_SIMD) && !defined(BOOST_UUID_USE_SSE41) && !defined(BOOST_UUID_USE_SSE3) && !defined(BOOST_UUID_USE_SSE2)
#define BOOST_UUID_NO_SIMD
#endif
#endif // !defined(BOOST_UUID_NO_SIMD)
#endif // BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_
@@ -0,0 +1,51 @@
/*
* Copyright Andy Tompkins 2006.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file uuid/detail/uuid_generic.hpp
*
* \brief This header contains generic implementation of \c boost::uuid operations.
*/
#ifndef BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
#include <string.h>
namespace boost {
namespace uuids {
inline bool uuid::is_nil() const BOOST_NOEXCEPT
{
for (std::size_t i = 0; i < sizeof(data); ++i)
{
if (data[i] != 0U)
return false;
}
return true;
}
inline void uuid::swap(uuid& rhs) BOOST_NOEXCEPT
{
uuid tmp = *this;
*this = rhs;
rhs = tmp;
}
inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) == 0;
}
inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) < 0;
}
} // namespace uuids
} // namespace boost
#endif // BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
@@ -0,0 +1,135 @@
/*
* Copyright Andrey Semashev 2013.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file uuid/detail/uuid_x86.hpp
*
* \brief This header contains optimized SSE implementation of \c boost::uuid operations.
*/
#ifndef BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
// MSVC does not always have immintrin.h (at least, not up to MSVC 10), so include the appropriate header for each instruction set
#if defined(BOOST_UUID_USE_SSE41)
#include <smmintrin.h>
#elif defined(BOOST_UUID_USE_SSE3)
#include <pmmintrin.h>
#else
#include <emmintrin.h>
#endif
#if defined(BOOST_MSVC) && defined(_M_X64) && !defined(BOOST_UUID_USE_SSE3) && (BOOST_MSVC < 1900 /* Fixed in Visual Studio 2015 */ )
// At least MSVC 9 (VS2008) and 12 (VS2013) have an optimizer bug that sometimes results in incorrect SIMD code
// generated in Release x64 mode. In particular, it affects operator==, where the compiler sometimes generates
// pcmpeqd with a memory opereand instead of movdqu followed by pcmpeqd. The problem is that uuid can be
// not aligned to 16 bytes and pcmpeqd causes alignment violation in this case. We cannot be sure that other
// MSVC versions are not affected so we apply the workaround for all versions, except VS2015 on up where
// the bug has been fixed.
//
// https://svn.boost.org/trac/boost/ticket/8509#comment:3
// https://connect.microsoft.com/VisualStudio/feedbackdetail/view/981648#tabs
#define BOOST_UUID_DETAIL_MSVC_BUG981648
#if BOOST_MSVC >= 1600
extern "C" void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier)
#endif
#endif
namespace boost {
namespace uuids {
namespace detail {
BOOST_FORCEINLINE __m128i load_unaligned_si128(const uint8_t* p) BOOST_NOEXCEPT
{
#if defined(BOOST_UUID_USE_SSE3)
return _mm_lddqu_si128(reinterpret_cast< const __m128i* >(p));
#elif !defined(BOOST_UUID_DETAIL_MSVC_BUG981648)
return _mm_loadu_si128(reinterpret_cast< const __m128i* >(p));
#elif defined(BOOST_MSVC) && BOOST_MSVC >= 1600
__m128i mm = _mm_loadu_si128(reinterpret_cast< const __m128i* >(p));
// Make sure this load doesn't get merged with the subsequent instructions
_ReadWriteBarrier();
return mm;
#else
// VS2008 x64 doesn't respect _ReadWriteBarrier above, so we have to generate this crippled code to load unaligned data
return _mm_unpacklo_epi64(_mm_loadl_epi64(reinterpret_cast< const __m128i* >(p)), _mm_loadl_epi64(reinterpret_cast< const __m128i* >(p + 8)));
#endif
}
} // namespace detail
inline bool uuid::is_nil() const BOOST_NOEXCEPT
{
__m128i mm = uuids::detail::load_unaligned_si128(data);
#if defined(BOOST_UUID_USE_SSE41)
return _mm_test_all_zeros(mm, mm) != 0;
#else
mm = _mm_cmpeq_epi32(mm, _mm_setzero_si128());
return _mm_movemask_epi8(mm) == 0xFFFF;
#endif
}
inline void uuid::swap(uuid& rhs) BOOST_NOEXCEPT
{
__m128i mm_this = uuids::detail::load_unaligned_si128(data);
__m128i mm_rhs = uuids::detail::load_unaligned_si128(rhs.data);
_mm_storeu_si128(reinterpret_cast< __m128i* >(rhs.data), mm_this);
_mm_storeu_si128(reinterpret_cast< __m128i* >(data), mm_rhs);
}
inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
__m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
__m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
#if defined(BOOST_UUID_USE_SSE41)
__m128i mm = _mm_xor_si128(mm_left, mm_right);
return _mm_test_all_zeros(mm, mm) != 0;
#else
__m128i mm_cmp = _mm_cmpeq_epi32(mm_left, mm_right);
return _mm_movemask_epi8(mm_cmp) == 0xFFFF;
#endif
}
inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
__m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
__m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
// To emulate lexicographical_compare behavior we have to perform two comparisons - the forward and reverse one.
// Then we know which bytes are equivalent and which ones are different, and for those different the comparison results
// will be opposite. Then we'll be able to find the first differing comparison result (for both forward and reverse ways),
// and depending on which way it is for, this will be the result of the operation. There are a few notes to consider:
//
// 1. Due to little endian byte order the first bytes go into the lower part of the xmm registers,
// so the comparison results in the least significant bits will actually be the most signigicant for the final operation result.
// This means we have to determine which of the comparison results have the least significant bit on, and this is achieved with
// the "(x - 1) ^ x" trick.
// 2. Because there is only signed comparison in SSE/AVX, we have to invert byte comparison results whenever signs of the corresponding
// bytes are different. I.e. in signed comparison it's -1 < 1, but in unsigned it is the opposite (255 > 1). To do that we XOR left and right,
// making the most significant bit of each byte 1 if the signs are different, and later apply this mask with another XOR to the comparison results.
// 3. pcmpgtw compares for "greater" relation, so we swap the arguments to get what we need.
const __m128i mm_signs_mask = _mm_xor_si128(mm_left, mm_right);
__m128i mm_cmp = _mm_cmpgt_epi8(mm_right, mm_left), mm_rcmp = _mm_cmpgt_epi8(mm_left, mm_right);
mm_cmp = _mm_xor_si128(mm_signs_mask, mm_cmp);
mm_rcmp = _mm_xor_si128(mm_signs_mask, mm_rcmp);
uint32_t cmp = static_cast< uint32_t >(_mm_movemask_epi8(mm_cmp)), rcmp = static_cast< uint32_t >(_mm_movemask_epi8(mm_rcmp));
cmp = (cmp - 1u) ^ cmp;
rcmp = (rcmp - 1u) ^ rcmp;
return cmp < rcmp;
}
} // namespace uuids
} // namespace boost
#endif // BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
@@ -0,0 +1,125 @@
// Boost name_generator.hpp header file ----------------------------------------------//
// Copyright 2010 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UUID_NAME_GENERATOR_HPP
#define BOOST_UUID_NAME_GENERATOR_HPP
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/sha1.hpp>
#include <boost/assert.hpp>
#include <string>
#include <cstring> // for strlen, wcslen
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::strlen;
using ::wcslen;
} //namespace std
#endif //BOOST_NO_STDC_NAMESPACE
namespace boost {
namespace uuids {
// generate a name-based uuid
// TODO: add in common namesspace uuids
class name_generator {
public:
typedef uuid result_type;
explicit name_generator(uuid const& namespace_uuid_)
: namespace_uuid(namespace_uuid_)
{}
uuid operator()(const char* name) {
reset();
process_characters(name, std::strlen(name));
return sha_to_uuid();
}
uuid operator()(const wchar_t* name) {
reset();
process_characters(name, std::wcslen(name));
return sha_to_uuid();
}
template <typename ch, typename char_traits, typename alloc>
uuid operator()(std::basic_string<ch, char_traits, alloc> const& name) {
reset();
process_characters(name.c_str(), name.length());
return sha_to_uuid();
}
uuid operator()(void const* buffer, std::size_t byte_count) {
reset();
sha.process_bytes(buffer, byte_count);
return sha_to_uuid();
};
private:
// we convert all characters to uint32_t so that each
// character is 4 bytes reguardless of sizeof(char) or
// sizeof(wchar_t). We want the name string on any
// platform / compiler to generate the same uuid
// except for char
template <typename char_type>
void process_characters(char_type const*const characters, size_t count) {
BOOST_ASSERT(sizeof(uint32_t) >= sizeof(char_type));
for (size_t i=0; i<count; i++) {
uint32_t c = characters[i];
sha.process_byte(static_cast<unsigned char>((c >> 0) & 0xFF));
sha.process_byte(static_cast<unsigned char>((c >> 8) & 0xFF));
sha.process_byte(static_cast<unsigned char>((c >> 16) & 0xFF));
sha.process_byte(static_cast<unsigned char>((c >> 24) & 0xFF));
}
}
void process_characters(char const*const characters, size_t count) {
sha.process_bytes(characters, count);
}
void reset()
{
sha.reset();
sha.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
}
uuid sha_to_uuid()
{
unsigned int digest[5];
sha.get_digest(digest);
uuid u;
for (int i=0; i<4; ++i) {
*(u.begin() + i*4+0) = static_cast<uint8_t>((digest[i] >> 24) & 0xFF);
*(u.begin() + i*4+1) = static_cast<uint8_t>((digest[i] >> 16) & 0xFF);
*(u.begin() + i*4+2) = static_cast<uint8_t>((digest[i] >> 8) & 0xFF);
*(u.begin() + i*4+3) = static_cast<uint8_t>((digest[i] >> 0) & 0xFF);
}
// set variant
// must be 0b10xxxxxx
*(u.begin()+8) &= 0xBF;
*(u.begin()+8) |= 0x80;
// set version
// must be 0b0101xxxx
*(u.begin()+6) &= 0x5F; //0b01011111
*(u.begin()+6) |= 0x50; //0b01010000
return u;
}
private:
uuid namespace_uuid;
detail::sha1 sha;
};
}} // namespace boost::uuids
#endif // BOOST_UUID_NAME_GENERATOR_HPP
@@ -0,0 +1,34 @@
// Boost nil_generator.hpp header file ----------------------------------------------//
// Copyright 2010 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UUID_NIL_GENERATOR_HPP
#define BOOST_UUID_NIL_GENERATOR_HPP
#include <boost/uuid/uuid.hpp>
namespace boost {
namespace uuids {
// generate a nil uuid
struct nil_generator {
typedef uuid result_type;
uuid operator()() const {
// initialize to all zeros
uuid u = {{0}};
return u;
}
};
inline uuid nil_uuid() {
return nil_generator()();
}
}} // namespace boost::uuids
#endif // BOOST_UUID_NIL_GENERATOR_HPP
@@ -0,0 +1,119 @@
// Boost random_generator.hpp header file ----------------------------------------------//
// Copyright 2010 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UUID_RANDOM_GENERATOR_HPP
#define BOOST_UUID_RANDOM_GENERATOR_HPP
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/seed_rng.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/assert.hpp>
#include <boost/shared_ptr.hpp>
#include <limits>
namespace boost {
namespace uuids {
// generate a random-based uuid
template <typename UniformRandomNumberGenerator>
class basic_random_generator {
private:
typedef uniform_int<unsigned long> distribution_type;
typedef variate_generator<UniformRandomNumberGenerator*, distribution_type> generator_type;
struct null_deleter
{
void operator()(void const *) const {}
};
public:
typedef uuid result_type;
// default constructor creates the random number generator
basic_random_generator()
: pURNG(new UniformRandomNumberGenerator)
, generator
( pURNG.get()
, distribution_type
( (std::numeric_limits<unsigned long>::min)()
, (std::numeric_limits<unsigned long>::max)()
)
)
{
// seed the random number generator
detail::seed(*pURNG);
}
// keep a reference to a random number generator
// don't seed a given random number generator
explicit basic_random_generator(UniformRandomNumberGenerator& gen)
: pURNG(&gen, null_deleter())
, generator
( pURNG.get()
, distribution_type
( (std::numeric_limits<unsigned long>::min)()
, (std::numeric_limits<unsigned long>::max)()
)
)
{}
// keep a pointer to a random number generator
// don't seed a given random number generator
explicit basic_random_generator(UniformRandomNumberGenerator* pGen)
: pURNG(pGen, null_deleter())
, generator
( pURNG.get()
, distribution_type
( (std::numeric_limits<unsigned long>::min)()
, (std::numeric_limits<unsigned long>::max)()
)
)
{
BOOST_ASSERT(pURNG);
}
uuid operator()()
{
uuid u;
int i=0;
unsigned long random_value = generator();
for (uuid::iterator it=u.begin(); it!=u.end(); ++it, ++i) {
if (i==sizeof(unsigned long)) {
random_value = generator();
i = 0;
}
// static_cast gets rid of warnings of converting unsigned long to boost::uint8_t
*it = static_cast<uuid::value_type>((random_value >> (i*8)) & 0xFF);
}
// set variant
// must be 0b10xxxxxx
*(u.begin()+8) &= 0xBF;
*(u.begin()+8) |= 0x80;
// set version
// must be 0b0100xxxx
*(u.begin()+6) &= 0x4F; //0b01001111
*(u.begin()+6) |= 0x40; //0b01000000
return u;
}
private:
shared_ptr<UniformRandomNumberGenerator> pURNG;
generator_type generator;
};
typedef basic_random_generator<mt19937> random_generator;
}} // namespace boost::uuids
#endif //BOOST_UUID_RANDOM_GENERATOR_HPP
@@ -0,0 +1,321 @@
// Boost seed_rng.hpp header file ----------------------------------------------//
// Copyright 2007 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History
// 09 Nov 2007 - Initial Revision
// 25 Feb 2008 - moved to namespace boost::uuids::detail
// 28 Nov 2009 - disabled deprecated warnings for MSVC
// 28 Jul 2014 - fixed valgrind warnings and better entropy sources for MSVC
// seed_rng models a UniformRandomNumberGenerator (see Boost.Random).
// Random number generators are hard to seed well. This is intended to provide
// good seed values for random number generators.
// It creates random numbers from a sha1 hash of data from a variary of sources,
// all of which are standard function calls. It produces random numbers slowly.
// Peter Dimov provided the details of sha1_random_digest_().
// see http://archives.free.net.ph/message/20070507.175609.4c4f503a.en.html
#ifndef BOOST_UUID_SEED_RNG_HPP
#define BOOST_UUID_SEED_RNG_HPP
#include <boost/config.hpp>
#include <cstring> // for memcpy
#include <limits>
#include <ctime> // for time_t, time, clock_t, clock
#include <cstdlib> // for rand
#include <cstdio> // for FILE, fopen, fread, fclose
#include <boost/core/noncopyable.hpp>
#include <boost/uuid/sha1.hpp>
//#include <boost/nondet_random.hpp> //forward declare boost::random::random_device
// can't use boost::generator_iterator since boost::random number seed(Iter&, Iter)
// functions need a last iterator
//#include <boost/generator_iterator.hpp>
# include <boost/iterator/iterator_facade.hpp>
#if defined(_MSC_VER)
# pragma warning(push) // Save warning settings.
# pragma warning(disable : 4996) // Disable deprecated std::fopen
#if defined(_WIN32_WCE)
# pragma comment(lib, "coredll.lib")
#else
# pragma comment(lib, "advapi32.lib")
#endif
#endif
#if defined(BOOST_WINDOWS)
# include <boost/detail/winapi/crypt.hpp> // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext
# include <boost/detail/winapi/timers.hpp>
# include <boost/detail/winapi/get_current_process_id.hpp>
# include <boost/detail/winapi/get_current_thread_id.hpp>
#else
# include <sys/time.h> // for gettimeofday
# include <sys/types.h> // for pid_t
# include <unistd.h> // for getpid()
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::memcpy;
using ::time_t;
using ::time;
using ::clock_t;
using ::clock;
using ::rand;
using ::FILE;
using ::fopen;
using ::fread;
using ::fclose;
} //namespace std
#endif
// forward declare random number generators
namespace boost { namespace random {
class random_device;
}} //namespace boost::random
namespace boost {
namespace uuids {
namespace detail {
// should this be part of Boost.Random?
class seed_rng: private boost::noncopyable
{
public:
typedef unsigned int result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
public:
// note: rd_ intentionally left uninitialized
seed_rng() BOOST_NOEXCEPT
: rd_index_(5)
, random_(NULL)
{
#if defined(BOOST_WINDOWS)
if (!boost::detail::winapi::CryptAcquireContextW(
&random_,
NULL,
NULL,
boost::detail::winapi::PROV_RSA_FULL_,
boost::detail::winapi::CRYPT_VERIFYCONTEXT_ | boost::detail::winapi::CRYPT_SILENT_))
{
random_ = NULL;
}
#else
random_ = std::fopen( "/dev/urandom", "rb" );
#endif
std::memset(rd_, 0, sizeof(rd_));
}
~seed_rng() BOOST_NOEXCEPT
{
if (random_) {
#if defined(BOOST_WINDOWS)
boost::detail::winapi::CryptReleaseContext(random_, 0);
#else
std::fclose(random_);
#endif
}
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
{
return (std::numeric_limits<result_type>::min)();
}
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
{
return (std::numeric_limits<result_type>::max)();
}
result_type operator()()
{
if (rd_index_ >= 5) {
//get new digest
sha1_random_digest_();
rd_index_ = 0;
}
return rd_[rd_index_++];
}
private:
BOOST_STATIC_CONSTANT(std::size_t, internal_state_size = 5);
inline void ignore_size(size_t) {}
static unsigned int * sha1_random_digest_state_()
{
static unsigned int state[ internal_state_size ];
return state;
}
void sha1_random_digest_()
{
boost::uuids::detail::sha1 sha;
if (random_)
{
// intentionally left uninitialized
unsigned char state[ 20 ];
#if defined(BOOST_WINDOWS)
boost::detail::winapi::CryptGenRandom(random_, sizeof(state), state);
#else
ignore_size(std::fread( state, 1, sizeof(state), random_ ));
#endif
sha.process_bytes( state, sizeof( state ) );
}
{
// Getting enropy from some system specific sources
#if defined(BOOST_WINDOWS)
boost::detail::winapi::DWORD_ procid = boost::detail::winapi::GetCurrentProcessId();
sha.process_bytes( (unsigned char const*)&procid, sizeof( procid ) );
boost::detail::winapi::DWORD_ threadid = boost::detail::winapi::GetCurrentThreadId();
sha.process_bytes( (unsigned char const*)&threadid, sizeof( threadid ) );
boost::detail::winapi::LARGE_INTEGER_ ts;
ts.QuadPart = 0;
boost::detail::winapi::QueryPerformanceCounter( &ts );
sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
std::time_t tm = std::time( 0 );
sha.process_bytes( (unsigned char const*)&tm, sizeof( tm ) );
#else
pid_t pid = getpid();
sha.process_bytes( (unsigned char const*)&pid, sizeof( pid ) );
timeval ts;
gettimeofday(&ts, NULL); // We do not use `clock_gettime` to avoid linkage with -lrt
sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
#endif
}
unsigned int * ps = sha1_random_digest_state_();
sha.process_bytes( ps, internal_state_size * sizeof( unsigned int ) );
sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) );
{
std::clock_t ck = std::clock();
sha.process_bytes( (unsigned char const*)&ck, sizeof( ck ) );
}
{
unsigned int rn[] =
{ static_cast<unsigned int>(std::rand())
, static_cast<unsigned int>(std::rand())
, static_cast<unsigned int>(std::rand())
};
sha.process_bytes( (unsigned char const*)rn, sizeof( rn ) );
}
{
unsigned int * p = new unsigned int;
sha.process_bytes( (unsigned char const*)&p, sizeof( p ) );
delete p;
const seed_rng* this_ptr = this;
sha.process_bytes( (unsigned char const*)&this_ptr, sizeof( this_ptr ) );
sha.process_bytes( (unsigned char const*)&std::rand, sizeof( void(*)() ) );
}
sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) );
unsigned int digest[ 5 ];
sha.get_digest( digest );
for( int i = 0; i < 5; ++i )
{
// harmless data race
ps[ i ] ^= digest[ i ];
rd_[ i ] ^= digest[ i ];
}
}
private:
unsigned int rd_[5];
int rd_index_;
#if defined(BOOST_WINDOWS)
boost::detail::winapi::HCRYPTPROV_ random_;
#else
std::FILE * random_;
#endif
};
// almost a copy of boost::generator_iterator
// but default constructor sets m_g to NULL
template <class Generator>
class generator_iterator
: public iterator_facade<
generator_iterator<Generator>
, typename Generator::result_type
, single_pass_traversal_tag
, typename Generator::result_type const&
>
{
typedef iterator_facade<
generator_iterator<Generator>
, typename Generator::result_type
, single_pass_traversal_tag
, typename Generator::result_type const&
> super_t;
public:
generator_iterator() : m_g(NULL), m_value(0) {}
generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {}
void increment()
{
m_value = (*m_g)();
}
const typename Generator::result_type&
dereference() const
{
return m_value;
}
bool equal(generator_iterator const& y) const
{
return this->m_g == y.m_g && this->m_value == y.m_value;
}
private:
Generator* m_g;
typename Generator::result_type m_value;
};
// seed() seeds a random number generator with good seed values
template <typename UniformRandomNumberGenerator>
inline void seed(UniformRandomNumberGenerator& rng)
{
seed_rng seed_gen;
generator_iterator<seed_rng> begin(&seed_gen);
generator_iterator<seed_rng> end;
rng.seed(begin, end);
}
// random_device does not / can not be seeded
template <>
inline void seed<boost::random::random_device>(boost::random::random_device&) {}
// random_device does not / can not be seeded
template <>
inline void seed<seed_rng>(seed_rng&) {}
}}} //namespace boost::uuids::detail
#if defined(_MSC_VER)
#pragma warning(pop) // Restore warnings to previous state.
#endif
#endif
@@ -0,0 +1,231 @@
// boost/uuid/sha1.hpp header file ----------------------------------------------//
// Copyright 2007 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History
// 29 May 2007 - Initial Revision
// 25 Feb 2008 - moved to namespace boost::uuids::detail
// 10 Jan 2012 - can now handle the full size of messages (2^64 - 1 bits)
// This is a byte oriented implementation
#ifndef BOOST_UUID_SHA1_H
#define BOOST_UUID_SHA1_H
#include <boost/static_assert.hpp>
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <cstddef>
#include <string>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::size_t;
} // namespace std
#endif
namespace boost {
namespace uuids {
namespace detail {
BOOST_STATIC_ASSERT(sizeof(unsigned char)*8 == 8);
BOOST_STATIC_ASSERT(sizeof(unsigned int)*8 == 32);
inline unsigned int left_rotate(unsigned int x, std::size_t n)
{
return (x<<n) ^ (x>> (32-n));
}
class sha1
{
public:
typedef unsigned int(&digest_type)[5];
public:
sha1();
void reset();
void process_byte(unsigned char byte);
void process_block(void const* bytes_begin, void const* bytes_end);
void process_bytes(void const* buffer, std::size_t byte_count);
void get_digest(digest_type digest);
private:
void process_block();
void process_byte_impl(unsigned char byte);
private:
unsigned int h_[5];
unsigned char block_[64];
std::size_t block_byte_index_;
std::size_t bit_count_low;
std::size_t bit_count_high;
};
inline sha1::sha1()
{
reset();
}
inline void sha1::reset()
{
h_[0] = 0x67452301;
h_[1] = 0xEFCDAB89;
h_[2] = 0x98BADCFE;
h_[3] = 0x10325476;
h_[4] = 0xC3D2E1F0;
block_byte_index_ = 0;
bit_count_low = 0;
bit_count_high = 0;
}
inline void sha1::process_byte(unsigned char byte)
{
process_byte_impl(byte);
// size_t max value = 0xFFFFFFFF
//if (bit_count_low + 8 >= 0x100000000) { // would overflow
//if (bit_count_low >= 0x100000000-8) {
if (bit_count_low < 0xFFFFFFF8) {
bit_count_low += 8;
} else {
bit_count_low = 0;
if (bit_count_high <= 0xFFFFFFFE) {
++bit_count_high;
} else {
BOOST_THROW_EXCEPTION(std::runtime_error("sha1 too many bytes"));
}
}
}
inline void sha1::process_byte_impl(unsigned char byte)
{
block_[block_byte_index_++] = byte;
if (block_byte_index_ == 64) {
block_byte_index_ = 0;
process_block();
}
}
inline void sha1::process_block(void const* bytes_begin, void const* bytes_end)
{
unsigned char const* begin = static_cast<unsigned char const*>(bytes_begin);
unsigned char const* end = static_cast<unsigned char const*>(bytes_end);
for(; begin != end; ++begin) {
process_byte(*begin);
}
}
inline void sha1::process_bytes(void const* buffer, std::size_t byte_count)
{
unsigned char const* b = static_cast<unsigned char const*>(buffer);
process_block(b, b+byte_count);
}
inline void sha1::process_block()
{
unsigned int w[80];
for (std::size_t i=0; i<16; ++i) {
w[i] = (block_[i*4 + 0] << 24);
w[i] |= (block_[i*4 + 1] << 16);
w[i] |= (block_[i*4 + 2] << 8);
w[i] |= (block_[i*4 + 3]);
}
for (std::size_t i=16; i<80; ++i) {
w[i] = left_rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
}
unsigned int a = h_[0];
unsigned int b = h_[1];
unsigned int c = h_[2];
unsigned int d = h_[3];
unsigned int e = h_[4];
for (std::size_t i=0; i<80; ++i) {
unsigned int f;
unsigned int k;
if (i<20) {
f = (b & c) | (~b & d);
k = 0x5A827999;
} else if (i<40) {
f = b ^ c ^ d;
k = 0x6ED9EBA1;
} else if (i<60) {
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
} else {
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
unsigned temp = left_rotate(a, 5) + f + e + k + w[i];
e = d;
d = c;
c = left_rotate(b, 30);
b = a;
a = temp;
}
h_[0] += a;
h_[1] += b;
h_[2] += c;
h_[3] += d;
h_[4] += e;
}
inline void sha1::get_digest(digest_type digest)
{
// append the bit '1' to the message
process_byte_impl(0x80);
// append k bits '0', where k is the minimum number >= 0
// such that the resulting message length is congruent to 56 (mod 64)
// check if there is enough space for padding and bit_count
if (block_byte_index_ > 56) {
// finish this block
while (block_byte_index_ != 0) {
process_byte_impl(0);
}
// one more block
while (block_byte_index_ < 56) {
process_byte_impl(0);
}
} else {
while (block_byte_index_ < 56) {
process_byte_impl(0);
}
}
// append length of message (before pre-processing)
// as a 64-bit big-endian integer
process_byte_impl( static_cast<unsigned char>((bit_count_high>>24) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_high>>16) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_high>>8 ) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_high) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low>>24) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low>>16) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low>>8 ) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low) & 0xFF) );
// get final digest
digest[0] = h_[0];
digest[1] = h_[1];
digest[2] = h_[2];
digest[3] = h_[3];
digest[4] = h_[4];
}
}}} // namespace boost::uuids::detail
#endif
@@ -0,0 +1,185 @@
// Boost string_generator.hpp header file ----------------------------------------------//
// Copyright 2010 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UUID_STRING_GENERATOR_HPP
#define BOOST_UUID_STRING_GENERATOR_HPP
#include <boost/uuid/uuid.hpp>
#include <string>
#include <cstring> // for strlen, wcslen
#include <iterator>
#include <algorithm> // for find
#include <stdexcept>
#include <boost/throw_exception.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::strlen;
using ::wcslen;
} //namespace std
#endif //BOOST_NO_STDC_NAMESPACE
namespace boost {
namespace uuids {
// generate a uuid from a string
// lexical_cast works fine using uuid_io.hpp
// but this generator should accept more forms
// and be more efficient
// would like to accept the following forms:
// 0123456789abcdef0123456789abcdef
// 01234567-89ab-cdef-0123456789abcdef
// {01234567-89ab-cdef-0123456789abcdef}
// {0123456789abcdef0123456789abcdef}
// others?
struct string_generator {
typedef uuid result_type;
template <typename ch, typename char_traits, typename alloc>
uuid operator()(std::basic_string<ch, char_traits, alloc> const& s) const {
return operator()(s.begin(), s.end());
}
uuid operator()(char const*const s) const {
return operator()(s, s+std::strlen(s));
}
uuid operator()(wchar_t const*const s) const {
return operator()(s, s+std::wcslen(s));
}
template <typename CharIterator>
uuid operator()(CharIterator begin, CharIterator end) const
{
typedef typename std::iterator_traits<CharIterator>::value_type char_type;
// check open brace
char_type c = get_next_char(begin, end);
bool has_open_brace = is_open_brace(c);
char_type open_brace_char = c;
if (has_open_brace) {
c = get_next_char(begin, end);
}
bool has_dashes = false;
uuid u;
int i=0;
for (uuid::iterator it_byte=u.begin(); it_byte!=u.end(); ++it_byte, ++i) {
if (it_byte != u.begin()) {
c = get_next_char(begin, end);
}
if (i == 4) {
has_dashes = is_dash(c);
if (has_dashes) {
c = get_next_char(begin, end);
}
}
if (has_dashes) {
if (i == 6 || i == 8 || i == 10) {
if (is_dash(c)) {
c = get_next_char(begin, end);
} else {
throw_invalid();
}
}
}
*it_byte = get_value(c);
c = get_next_char(begin, end);
*it_byte <<= 4;
*it_byte |= get_value(c);
}
// check close brace
if (has_open_brace) {
c = get_next_char(begin, end);
check_close_brace(c, open_brace_char);
}
return u;
}
private:
template <typename CharIterator>
typename std::iterator_traits<CharIterator>::value_type
get_next_char(CharIterator& begin, CharIterator end) const {
if (begin == end) {
throw_invalid();
}
return *begin++;
}
unsigned char get_value(char c) const {
static char const*const digits_begin = "0123456789abcdefABCDEF";
static char const*const digits_end = digits_begin + 22;
static unsigned char const values[] =
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15
, static_cast<unsigned char>(-1) };
char const* d = std::find(digits_begin, digits_end, c);
return values[d - digits_begin];
}
unsigned char get_value(wchar_t c) const {
static wchar_t const*const digits_begin = L"0123456789abcdefABCDEF";
static wchar_t const*const digits_end = digits_begin + 22;
static unsigned char const values[] =
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15
, static_cast<unsigned char>(-1) };
wchar_t const* d = std::find(digits_begin, digits_end, c);
return values[d - digits_begin];
}
bool is_dash(char c) const {
return c == '-';
}
bool is_dash(wchar_t c) const {
return c == L'-';
}
// return closing brace
bool is_open_brace(char c) const {
return (c == '{');
}
bool is_open_brace(wchar_t c) const {
return (c == L'{');
}
void check_close_brace(char c, char open_brace) const {
if (open_brace == '{' && c == '}') {
//great
} else {
throw_invalid();
}
}
void check_close_brace(wchar_t c, wchar_t open_brace) const {
if (open_brace == L'{' && c == L'}') {
// great
} else {
throw_invalid();
}
}
void throw_invalid() const {
BOOST_THROW_EXCEPTION(std::runtime_error("invalid uuid string"));
}
};
}} // namespace boost::uuids
#endif //BOOST_UUID_STRING_GENERATOR_HPP
@@ -0,0 +1,212 @@
// Boost uuid.hpp header file ----------------------------------------------//
// Copyright 2006 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History
// 06 Feb 2006 - Initial Revision
// 09 Nov 2006 - fixed variant and version bits for v4 guids
// 13 Nov 2006 - added serialization
// 17 Nov 2006 - added name-based guid creation
// 20 Nov 2006 - add fixes for gcc (from Tim Blechmann)
// 07 Mar 2007 - converted to header only
// 10 May 2007 - removed need for Boost.Thread
// - added better seed - thanks Peter Dimov
// - removed null()
// - replaced byte_count() and output_bytes() with size() and begin() and end()
// 11 May 2007 - fixed guid(ByteInputIterator first, ByteInputIterator last)
// - optimized operator>>
// 14 May 2007 - converted from guid to uuid
// 29 May 2007 - uses new implementation of sha1
// 01 Jun 2007 - removed using namespace directives
// 09 Nov 2007 - moved implementation to uuid.ipp file
// 12 Nov 2007 - moved serialize code to uuid_serialize.hpp file
// 25 Feb 2008 - moved to namespace boost::uuids
// 19 Mar 2009 - changed to a POD, reorganized files
// 28 Nov 2009 - disabled deprecated warnings for MSVC
// 30 Nov 2009 - used BOOST_STATIC_CONSTANT
// 02 Dec 2009 - removed BOOST_STATIC_CONSTANT - not all compilers like it
// 29 Apr 2013 - added support for noexcept and constexpr, added optimizations for SSE/AVX
#ifndef BOOST_UUID_HPP
#define BOOST_UUID_HPP
#include <cstddef>
#include <boost/cstdint.hpp>
#include <boost/uuid/detail/config.hpp>
#ifndef BOOST_UUID_NO_TYPE_TRAITS
#include <boost/type_traits/is_pod.hpp>
#include <boost/type_traits/integral_constant.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(_MSC_VER)
#pragma warning(push) // Save warning settings.
#pragma warning(disable : 4996) // Disable deprecated std::swap_ranges, std::equal
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::size_t;
using ::ptrdiff_t;
} //namespace std
#endif //BOOST_NO_STDC_NAMESPACE
namespace boost {
namespace uuids {
struct uuid
{
public:
typedef uint8_t value_type;
typedef uint8_t& reference;
typedef uint8_t const& const_reference;
typedef uint8_t* iterator;
typedef uint8_t const* const_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
// This does not work on some compilers
// They seem to want the variable definec in
// a cpp file
//BOOST_STATIC_CONSTANT(size_type, static_size = 16);
static BOOST_CONSTEXPR size_type static_size() BOOST_NOEXCEPT { return 16; }
public:
iterator begin() BOOST_NOEXCEPT { return data; }
const_iterator begin() const BOOST_NOEXCEPT { return data; }
iterator end() BOOST_NOEXCEPT { return data+size(); }
const_iterator end() const BOOST_NOEXCEPT { return data+size(); }
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return static_size(); }
bool is_nil() const BOOST_NOEXCEPT;
enum variant_type
{
variant_ncs, // NCS backward compatibility
variant_rfc_4122, // defined in RFC 4122 document
variant_microsoft, // Microsoft Corporation backward compatibility
variant_future // future definition
};
variant_type variant() const BOOST_NOEXCEPT
{
// variant is stored in octet 7
// which is index 8, since indexes count backwards
unsigned char octet7 = data[8]; // octet 7 is array index 8
if ( (octet7 & 0x80) == 0x00 ) { // 0b0xxxxxxx
return variant_ncs;
} else if ( (octet7 & 0xC0) == 0x80 ) { // 0b10xxxxxx
return variant_rfc_4122;
} else if ( (octet7 & 0xE0) == 0xC0 ) { // 0b110xxxxx
return variant_microsoft;
} else {
//assert( (octet7 & 0xE0) == 0xE0 ) // 0b111xxxx
return variant_future;
}
}
enum version_type
{
version_unknown = -1,
version_time_based = 1,
version_dce_security = 2,
version_name_based_md5 = 3,
version_random_number_based = 4,
version_name_based_sha1 = 5
};
version_type version() const BOOST_NOEXCEPT
{
// version is stored in octet 9
// which is index 6, since indexes count backwards
uint8_t octet9 = data[6];
if ( (octet9 & 0xF0) == 0x10 ) {
return version_time_based;
} else if ( (octet9 & 0xF0) == 0x20 ) {
return version_dce_security;
} else if ( (octet9 & 0xF0) == 0x30 ) {
return version_name_based_md5;
} else if ( (octet9 & 0xF0) == 0x40 ) {
return version_random_number_based;
} else if ( (octet9 & 0xF0) == 0x50 ) {
return version_name_based_sha1;
} else {
return version_unknown;
}
}
// note: linear complexity
void swap(uuid& rhs) BOOST_NOEXCEPT;
public:
// or should it be array<uint8_t, 16>
uint8_t data[16];
};
bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT;
bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT;
inline bool operator!=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return !(lhs == rhs);
}
inline bool operator>(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return rhs < lhs;
}
inline bool operator<=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return !(rhs < lhs);
}
inline bool operator>=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return !(lhs < rhs);
}
inline void swap(uuid& lhs, uuid& rhs) BOOST_NOEXCEPT
{
lhs.swap(rhs);
}
// This is equivalent to boost::hash_range(u.begin(), u.end());
inline std::size_t hash_value(uuid const& u) BOOST_NOEXCEPT
{
std::size_t seed = 0;
for(uuid::const_iterator i=u.begin(), e=u.end(); i != e; ++i)
{
seed ^= static_cast<std::size_t>(*i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
}} //namespace boost::uuids
#ifndef BOOST_UUID_NO_TYPE_TRAITS
// type traits specializations
namespace boost {
template <>
struct is_pod<uuids::uuid> : true_type {};
} // namespace boost
#endif
#if defined(BOOST_UUID_USE_SSE2)
#include <boost/uuid/detail/uuid_x86.hpp>
#else
#include <boost/uuid/detail/uuid_generic.hpp>
#endif
#if defined(_MSC_VER)
#pragma warning(pop) // Restore warnings to previous state.
#endif
#endif // BOOST_UUID_HPP
@@ -0,0 +1,19 @@
// Boost uuid_generators.hpp header file ----------------------------------------------//
// Copyright 2006 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History
// 06 Feb 2006 - Initial Revision
#ifndef BOOST_UUID_GENERATORS_HPP
#define BOOST_UUID_GENERATORS_HPP
#include <boost/uuid/nil_generator.hpp>
#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/name_generator.hpp>
#include <boost/uuid/random_generator.hpp>
#endif //BOOST_UUID_GENERATORS_HPP
@@ -0,0 +1,198 @@
// Boost uuid_io.hpp header file ----------------------------------------------//
// Copyright 2009 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History
// 20 Mar 2009 - Initial Revision
// 28 Nov 2009 - disabled deprecated warnings for MSVC
#ifndef BOOST_UUID_IO_HPP
#define BOOST_UUID_IO_HPP
#include <boost/uuid/uuid.hpp>
#include <ios>
#include <ostream>
#include <istream>
#include <boost/io/ios_state.hpp>
#include <locale>
#include <algorithm>
#if defined(_MSC_VER)
#pragma warning(push) // Save warning settings.
#pragma warning(disable : 4996) // Disable deprecated std::ctype<char>::widen, std::copy
#endif
namespace boost {
namespace uuids {
template <typename ch, typename char_traits>
std::basic_ostream<ch, char_traits>& operator<<(std::basic_ostream<ch, char_traits> &os, uuid const& u)
{
io::ios_flags_saver flags_saver(os);
io::basic_ios_fill_saver<ch, char_traits> fill_saver(os);
const typename std::basic_ostream<ch, char_traits>::sentry ok(os);
if (ok) {
const std::streamsize width = os.width(0);
const std::streamsize uuid_width = 36;
const std::ios_base::fmtflags flags = os.flags();
const typename std::basic_ios<ch, char_traits>::char_type fill = os.fill();
if (flags & (std::ios_base::right | std::ios_base::internal)) {
for (std::streamsize i=uuid_width; i<width; i++) {
os << fill;
}
}
os << std::hex << std::right;
os.fill(os.widen('0'));
std::size_t i=0;
for (uuid::const_iterator i_data = u.begin(); i_data!=u.end(); ++i_data, ++i) {
os.width(2);
os << static_cast<unsigned int>(*i_data);
if (i == 3 || i == 5 || i == 7 || i == 9) {
os << os.widen('-');
}
}
if (flags & std::ios_base::left) {
for (std::streamsize s=uuid_width; s<width; s++) {
os << fill;
}
}
os.width(0); //used the width so reset it
}
return os;
}
template <typename ch, typename char_traits>
std::basic_istream<ch, char_traits>& operator>>(std::basic_istream<ch, char_traits> &is, uuid &u)
{
const typename std::basic_istream<ch, char_traits>::sentry ok(is);
if (ok) {
unsigned char data[16];
typedef std::ctype<ch> ctype_t;
ctype_t const& ctype = std::use_facet<ctype_t>(is.getloc());
ch xdigits[16];
{
char szdigits[] = "0123456789ABCDEF";
ctype.widen(szdigits, szdigits+16, xdigits);
}
ch*const xdigits_end = xdigits+16;
ch c;
for (std::size_t i=0; i<u.size() && is; ++i) {
is >> c;
c = ctype.toupper(c);
ch* f = std::find(xdigits, xdigits_end, c);
if (f == xdigits_end) {
is.setstate(std::ios_base::failbit);
break;
}
unsigned char byte = static_cast<unsigned char>(std::distance(&xdigits[0], f));
is >> c;
c = ctype.toupper(c);
f = std::find(xdigits, xdigits_end, c);
if (f == xdigits_end) {
is.setstate(std::ios_base::failbit);
break;
}
byte <<= 4;
byte |= static_cast<unsigned char>(std::distance(&xdigits[0], f));
data[i] = byte;
if (is) {
if (i == 3 || i == 5 || i == 7 || i == 9) {
is >> c;
if (c != is.widen('-')) is.setstate(std::ios_base::failbit);
}
}
}
if (is) {
std::copy(data, data+16, u.begin());
}
}
return is;
}
namespace detail {
inline char to_char(size_t i) {
if (i <= 9) {
return static_cast<char>('0' + i);
} else {
return static_cast<char>('a' + (i-10));
}
}
inline wchar_t to_wchar(size_t i) {
if (i <= 9) {
return static_cast<wchar_t>(L'0' + i);
} else {
return static_cast<wchar_t>(L'a' + (i-10));
}
}
} // namespace detail
inline std::string to_string(uuid const& u)
{
std::string result;
result.reserve(36);
std::size_t i=0;
for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
const size_t hi = ((*it_data) >> 4) & 0x0F;
result += detail::to_char(hi);
const size_t lo = (*it_data) & 0x0F;
result += detail::to_char(lo);
if (i == 3 || i == 5 || i == 7 || i == 9) {
result += '-';
}
}
return result;
}
#ifndef BOOST_NO_STD_WSTRING
inline std::wstring to_wstring(uuid const& u)
{
std::wstring result;
result.reserve(36);
std::size_t i=0;
for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
const size_t hi = ((*it_data) >> 4) & 0x0F;
result += detail::to_wchar(hi);
const size_t lo = (*it_data) & 0x0F;
result += detail::to_wchar(lo);
if (i == 3 || i == 5 || i == 7 || i == 9) {
result += L'-';
}
}
return result;
}
#endif
}} //namespace boost::uuids
#if defined(_MSC_VER)
#pragma warning(pop) // Restore warnings to previous state.
#endif
#endif // BOOST_UUID_IO_HPP
@@ -0,0 +1,20 @@
// Boost uuid_serialize.hpp header file ----------------------------------------------//
// Copyright 2007 Andy Tompkins.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History
// 12 Nov 2007 - Initial Revision
// 25 Feb 2008 - moved to namespace boost::uuids::detail
#ifndef BOOST_UUID_SERIALIZE_HPP
#define BOOST_UUID_SERIALIZE_HPP
#include <boost/uuid/uuid.hpp>
#include <boost/serialization/level.hpp>
BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)
#endif // BOOST_UUID_SERIALIZE_HPP