Boost C++ 库

这是世界上最受推崇、设计最精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ Coding Standards

Boost.Uuid - Boost C++ 函数库

介绍

UUID,即通用唯一标识符,旨在在没有显著中心协调的分布式环境中唯一标识信息。它可用于标记具有非常短生命周期的对象,或在网络中可靠地标识非常持久的对象。

UUID 的正式定义可在 RFC 4122RFC 9562 中找到。

UUID 有许多应用。以下是一些示例:数据库可以使用 UUID 来标识行或记录,以确保它们在不同数据库之间是唯一的,或用于发布/订阅服务。网络消息可以使用 UUID 来标识,以确保消息的不同部分能够重新组合在一起。分布式计算可以使用 UUID 来标识远程过程调用。参与序列化的事务和类可以通过 UUID 来标识。Microsoft 的组件对象模型 (COM) 使用 UUID 来区分不同的软件组件接口。UUID 被插入到 Microsoft Office 程序生成的文档中。UUID 在高级系统格式 (ASF) 中标识音频或视频流。UUID 也是 OID(对象标识符)和 URN(统一资源名称)的基础。

与替代方案相比,UUID 的一个吸引人的特性是它相对较小的尺寸,为 128 位,即 16 字节。另一个特性是创建 UUID 不需要中心化机构。

当 UUID 由其中一种定义的机制生成时,它们要么保证是唯一的,与所有其他生成的 UUID 不同(即,它以前从未生成过,将来也永远不会生成),要么(取决于机制)极有可能唯一。

修订历史

Boost 1.87.0 中的更改

  • 恢复了构造 constexpr uuid 的能力,该能力在 1.86 版本中被意外丢失。

Boost 1.86.0 中的更改 (重大更新)

  • 不再支持 C++03,需要 C++11 编译器。这包括 GCC 4.8 或更高版本、MSVC 14.0 或更高版本以及 MinGW-w64。

  • 移除了对 Core、Io、Move、NumericConversion、StaticAssert、TTI、Random、ContainerHash 的直接依赖。该库现在总共只有五个 Boost 依赖项(而 Boost 1.85 中有 39 个)。

  • std::hash 支持从 uuid_hash.hpp 移至 uuid.hpp

  • 将序列化支持从 uuid_serialize.hpp 移至 uuid.hpp

  • 提高了 hash_value 的质量和速度。

  • 添加了 operator<=>

  • is_niloperator==operator<swapoperator<=> 的通用(非 SIMD)实现现在在 __uint128_t 类型可用时使用它,否则使用 uint64_t 操作。

  • 添加了便捷头文件 <boost/uuid.hpp>

  • 移除了特定于平台的熵提供程序;现在该实现使用 std::random_device 作为熵源。

  • basic_random_generator 已移至其自己的头文件 boost/uuid/basic_random_generator.hpp

  • basic_random_generator 已更改为按值存储底层生成器,以避免动态分配并恢复可复制性。

  • random_generator_pure 现在是 basic_random_generator<std::random_device> 的别名,并且不鼓励使用它。

  • random_generator_mt19937 现在是 basic_random_generator<std::mt19937> 的别名,并且不鼓励使用它。

  • random_generator 现在使用密码学上强的伪随机数生成器 (ChaCha20/12),该生成器以来自 std::random_device 的熵进行播种。这是生成版本 4 UUID 的推荐方法。

  • 由于 basic_name_generator 只有两个有效的实例化,而且这两个实例化都已经提供(name_generator_md5name_generator_sha1),因此它已成为私有实现细节,不再是公共接口的一部分。

  • 虽然仍提供 name_generatorname_generator_latest 以兼容,但不再鼓励使用它们。

  • 名称生成器现在接受 Unicode 字符串;这些字符串在哈希之前会转换为 UTF-8。

  • RFC 4122 中定义的知名命名空间的定义已移至其自己的头文件 boost/uuid/namespaces.hpp

  • 添加了 time_generator_v1,这是一个生成基于时间的版本 1 UUID 的生成器。

  • 添加了 time_generator_v6,这是一个生成基于时间的版本 6 UUID 的生成器。

  • 添加了 time_generator_v7,这是一个生成基于时间的版本 7 UUID 的生成器。

  • 添加了 uuid_clock,这是一个与 <chrono> 兼容的时钟,其纪元和分辨率如 RFC 4122 所指定。

  • 已将时间戳、时间点、时钟序列和节点标识符的访问器添加到 uuid 中。

  • 改进了 string_generator 抛出的 std::runtime_error 异常的 what() 字符串。

  • 添加了 to_chars 的重载,接受 Ch* first, Ch* lastCh(&)[N]

  • uuid 的默认构造函数现在产生一个 nil UUID 而不是未初始化的 UUID。

  • u.data()(其中 uuuid 类型)现在返回一个指向表示形式第一个 uint8_t 的指针(与 u.begin() 相同)。为了向后兼容,data 是一个具有 operator() 的函数对象,而不是成员函数,这使得大多数将 data 用作公共成员的现有用法保持有效,尽管不再推荐。

  • uuid 现在具有与 std::uint64_t 相同的对齐方式。它以前是未对齐的(对齐方式为 1,与 std::uint8_t 相同)。要恢复 1.85 的行为,请定义宏 BOOST_UUID_DISABLE_ALIGNMENT

配置

该库不需要构建或任何特殊配置即可使用。但是,可以通过在包含库头文件之前定义宏来启用一些选项。

指令集

描述

BOOST_UUID_NO_SIMD

如果定义,将禁用对 SIMD 启用处理器的任何优化。将使用算法的通用版本。这可能会导致性能不佳。默认情况下,当库在编译时能够检测到 SIMD 扩展的可用性时,会使用优化算法。

BOOST_UUID_USE_SSE2

如果定义,将启用对 x86 处理器中可用的 SSE2 扩展的优化。

BOOST_UUID_USE_SSE3

如果定义,将启用对 x86 处理器中可用的 SSE3 扩展的优化。

BOOST_UUID_USE_SSE41

如果定义,将启用对 x86 处理器中可用的 SSE4.1 扩展的优化。

BOOST_UUID_USE_AVX

如果定义,将启用对现代 x86 处理器中可用的 AVX 扩展的优化。

BOOST_UUID_USE_AVX10_1

如果定义,将启用对现代 x86 处理器中可用的 AVX-512AVX10.1 扩展的优化。该库不需要 512 位向量,并且与实现 AVX-512F、CD、VL、BW 和 DQ 指令集的 CPU(即相当于 Intel Skylake-X)兼容。

默认情况下,该库会尝试在编译时检测目标 CPU 中 SIMD 扩展的可用性,并在成功时自动定义相应的宏。用户可以定义 BOOST_UUID_USE_SSE*BOOST_UUID_USE_AVX* 宏,如果自动检测失败且已知目标 CPU 将具有该扩展。只有当您确定这些扩展在运行您程序的任何机器上始终可用时,才启用这些扩展。该库不执行运行时检查,因此如果缺少某个扩展,程序很可能会崩溃。请注意,启用更高级的扩展意味着也包含了更基础的扩展。

对齐

描述

BOOST_UUID_DISABLE_ALIGNMENT

如果定义,将保持 uuid 未对齐(对齐方式为 1,与 std::uint8_t 相同)。这是 1.86 版本之前的行为。

默认情况下,uuidstd::uint64_t 具有相同的对齐方式。定义 BOOST_UUID_DISABLE_ALIGNMENT 以保持其未对齐。

示例

标记

// example of tagging an object with a uuid
// see boost/libs/uuid/test/test_tagging.cpp

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>

class object
{
public:
    object()
        : tag(boost::uuids::random_generator()())
        , state(0)
    {}

    explicit object(int state)
        : tag(boost::uuids::random_generator()())
        , state(state)
    {}

    object(object const& rhs)
        : tag(rhs.tag)
        , state(rhs.state)
    {}

    bool operator==(object const& rhs) const {
        return tag == rhs.tag;
    }

    object& operator=(object const& rhs) {
        tag = rhs.tag;
        state = rhs.state;
    }

    int get_state() const { return state; }
    void set_state(int new_state) { state = new_state; }

private:
    boost::uuids::uuid tag;

    int state;
};

object o1(1);
object o2 = o1;
o2.set_state(2);
assert(o1 == o2);

object o3(3);
assert(o1 != o3);
assert(o2 != o3);

字节提取

有时直接访问 uuid 的 16 字节很有用。典型用法如下:

boost::uuids::uuid u;
std::vector<std::uint8_t> v(u.size());
std::copy(u.begin(), u.end(), v.begin());

注意:boost::uuids::uuid::size() 始终返回 16。

参考

<boost/uuid.hpp>

这个便捷头文件使整个库都可用。

提要

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>

<boost/uuid/uuid.hpp>

提要

namespace boost {
namespace uuids {

class uuid
{
private:

    std::uint8_t data_[ 16 ] = {}; // exposition only

public:

    // constructors

    uuid() = default;
    uuid( std::uint8_t const (&r)[ 16 ] );

    // iteration

    using value_type = std::uint8_t;

    using reference = std::uint8_t&;
    using const_reference = std::uint8_t const&;

    using iterator = std::uint8_t*;
    using const_iterator = std::uint8_t const*;

    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    iterator begin() noexcept;
    iterator end() noexcept;

    const_iterator begin() const noexcept;
    const_iterator end() const noexcept;

    // data

    std::uint8_t* data() noexcept;
    std::uint8_t const* data() const noexcept;

    // size

    constexpr size_type size() const noexcept;
    static constexpr size_type static_size() noexcept;

    // is_nil

    bool is_nil() const noexcept;

    // variant

    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 noexcept;

    // version

    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_time_based_v6 = 6,
        version_time_based_v7 = 7,
        version_custom_v8 = 8
    };

    version_type version() const noexcept;

    // time-based fields

    using timestamp_type = std::uint64_t;
    using clock_seq_type = std::uint16_t;
    using node_type = std::array<std::uint8_t, 6>;

    timestamp_type timestamp_v1() const noexcept;
    uuid_clock::time_point time_point_v1() const noexcept;

    timestamp_type timestamp_v6() const noexcept;
    uuid_clock::time_point time_point_v6() const noexcept;

    timestamp_type timestamp_v7() const noexcept;

    std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
      time_point_v7() const noexcept;

    clock_seq_type clock_seq() const noexcept;
    node_type node_identifier() const noexcept;

    // swap

    void swap( uuid& rhs ) noexcept;
};

// operators

bool operator==( uuid const& lhs, uuid const& rhs ) noexcept;
bool operator!=( uuid const& lhs, uuid const& rhs ) noexcept;

bool operator<( uuid const& lhs, uuid const& rhs ) noexcept;
bool operator>( uuid const& lhs, uuid const& rhs ) noexcept;
bool operator<=( uuid const& lhs, uuid const& rhs ) noexcept;
bool operator>=( uuid const& lhs, uuid const& rhs ) noexcept;

std::strong_ordering operator<=>( uuid const& lhs, uuid const& rhs ) noexcept;

// free swap

void swap( uuid& lhs, uuid& rhs ) noexcept;

// hash_value

std::size_t hash_value( uuid const& u ) noexcept;

}} // namespace boost::uuids

// Boost.Serialization support

BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)

// std::hash support

template<> struct std::hash<boost::uuids::uuid>;

构造函数

uuid() = default;
效果

零初始化 data_

后置条件

is_nil().

uuid( std::uint8_t const (&r)[ 16 ] );
效果

r 的相应元素初始化 data_ 的元素。

示例
uuid dns = {{ 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};

迭代

提供了常量和可变迭代器。

iterator begin() noexcept;
const_iterator begin() const noexcept;
返回

data().

iterator end() noexcept;
const_iterator end() const noexcept;
返回

data() + size().

示例
using namespace boost::uuids;

uuid u;

for( uuid::const_iterator it = u.begin(); it != u.end(); ++it )
{
    uuid::value_type v = *it;
    // do something with the octet v
}

for( uuid::iterator it = u.begin(); it != u.end(); ++it )
{
    *it = 0;
}

数据

std::uint8_t* data() noexcept;
std::uint8_t const* data() const noexcept;
返回

data_.

大小

uuid 的大小(以字节为单位)固定为 16。

constexpr size_type size() const noexcept;
static constexpr size_type static_size() noexcept;
返回

16.

示例
using namespace boost::uuids;

uuid u;

assert( u.size() == 16 );
static_assert( uuid::static_size() == 16 );

is_nil

bool is_nil() const noexcept;
返回

uuid 等于 nil UUID 时为 true,即 {00000000-0000-0000-0000-000000000000},否则为 false

Variant

uuid 的三位决定了变体。

variant_type variant() const noexcept;
返回

UUID 变体;对于非 nil UUID,通常是 variant_rfc_4122

版本

uuid 的四位决定了版本,即用于生成 uuid 的机制。

version_type version() const noexcept;
返回

UUID 版本。

基于时间的字段

timestamp_type timestamp_v1() const noexcept;
返回

UUIDv1 时间戳(自 1582 年 10 月 15 日 00:00:00.00 以来的 100ns 间隔数)。该值仅对版本 1 UUID 有意义。

uuid_clock::time_point time_point_v1() const noexcept;
返回

版本 1 UUID 的时间戳,表示为 <chrono> time_point

timestamp_type timestamp_v6() const noexcept;
返回

UUIDv6 时间戳(自 1582 年 10 月 15 日 00:00:00.00 以来的 100ns 间隔数)。该值仅对版本 6 UUID 有意义。

uuid_clock::time_point time_point_v6() const noexcept;
返回

版本 6 UUID 的时间戳,表示为 <chrono> time_point

timestamp_type timestamp_v7() const noexcept;
返回

UUIDv7 时间戳(自 Unix 纪元 - 1970 年 1 月 1 日 UTC 午夜以来的毫秒数)。该值仅对版本 7 UUID 有意义。

std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
  time_point_v7() const noexcept;
返回

版本 7 UUID 的时间戳,表示为 <chrono> time_point

clock_seq_type clock_seq() const noexcept;
返回

基于时间的 UUID 的时钟序列。该值仅对基于时间的 UUID(版本 1 和版本 6)有意义。

node_type node_identifier() const noexcept;
返回

基于时间的 UUID 的节点标识符。该值仅对基于时间的 UUID(版本 1 和版本 6)有意义。

Swap

void swap( uuid& rhs ) noexcept;
效果

交换 *thisrhs 的值。

运算符

bool operator==( uuid const& lhs, uuid const& rhs ) noexcept;
返回

如同 std::memcmp( lhs.data(), rhs.data(), 16 ) == 0

bool operator!=( uuid const& lhs, uuid const& rhs ) noexcept;
返回

!(lhs == rhs).

bool operator<( uuid const& lhs, uuid const& rhs ) noexcept;
返回

如同 std::memcmp( lhs.data(), rhs.data(), 16 ) < 0

bool operator>( uuid const& lhs, uuid const& rhs ) noexcept;
返回

rhs < lhs.

bool operator<=( uuid const& lhs, uuid const& rhs ) noexcept;
返回

!(rhs < lhs).

bool operator>=( uuid const& lhs, uuid const& rhs ) noexcept;
返回

!(lhs < rhs).

std::strong_ordering operator<=>( uuid const& lhs, uuid const& rhs ) noexcept;
返回

如同 std::memcmp( lhs.data(), rhs.data(), 16 ) <=> 0

自由交换

void swap( uuid& lhs, uuid& rhs ) noexcept;
效果

lhs.swap( rhs );

hash_value

此函数允许 uuid 实例与 boost::hash 一起使用。

std::size_t hash_value( uuid const& u ) noexcept;
返回

uuid 的哈希值。

示例
boost::unordered_flat_map<boost::uuids::uuid, int> hash_map;

Serialization

BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)

uuid 作为原始类型序列化,即通过其字符串表示。

std::hash

此特化允许 uuid 实例与 std::hash 一起使用。

template<> struct std::hash<boost::uuids::uuid>
{
    std::size_t operator()( boost::uuids::uuid const& v ) const noexcept;
}
std::size_t operator()( boost::uuids::uuid const& v ) const noexcept;
返回

boost::uuids::hash_value( v ).

示例
std::unordered_map<boost::uuids::uuid, int> hash_map;

<boost/uuid/uuid_io.hpp>

提要

namespace boost {
namespace uuids {

// stream insertion

template<class Ch, class Traits>
  std::basic_ostream<Ch, Traits>&
    operator<<( std::basic_ostream<Ch, Traits>& os, uuid const& u );

// stream extraction

template<class Ch, class Traits>
  std::basic_istream<Ch, Traits>&
    operator>>( std::basic_istream<Ch, Traits>& is, uuid& u );

// to_chars

template<class OutputIterator>
  OutputIterator to_chars( uuid const& u, OutputIterator out );

template<class Ch>
  bool to_chars( uuid const& u, Ch* first, Ch* last ) noexcept;

template<class Ch, std::size_t N>
  Ch* to_chars( uuid const& u, Ch (&buffer)[ N ] ) noexcept;

// to_string

std::string to_string( uuid const& u );
std::wstring to_wstring( uuid const& u );

}} // namespace boost::uuids

流插入

template<class Ch, class Traits>
  std::basic_ostream<Ch, Traits>&
    operator<<( std::basic_ostream<Ch, Traits>& os, uuid const& u );
要求

Ch 必须是 charwchar_t

效果

u 的字符串表示插入输出流 os

uuid 的字符串表示为 hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,其中 h 是小写十六进制数字。

注意
此运算符还支持使用 boost::lexical_castuuid 转换为字符串。
示例
using namespace boost::uuids;

uuid u1 = random_generator()();

std::cout << u1 << std::endl;

std::string s1 = boost::lexical_cast<std::string>( u1 );

std::cout << s1 << std::endl;

流提取

template<class Ch, class Traits>
  std::basic_istream<Ch, Traits>&
    operator>>( std::basic_istream<Ch, Traits>& is, uuid& u );
要求

Ch 必须是 charwchar_t

效果

is 解析 uuid 字符串表示,并将结果存储到 u 中。

注意
此运算符还支持使用 boost::lexical_cast 将字符串转换为 uuid
示例
using namespace boost::uuids;

uuid u1 = random_generator()();

std::stringstream ss;
ss << u1;

uuid u2 = boost::lexical_cast<uuid>( ss.str() );

assert( u1 == u2 );

uuid u3;
ss >> u3;

assert( u1 == u3 );

to_chars

template<class OutputIterator>
  OutputIterator to_chars( uuid const& u, OutputIterator out );
效果

u 的字符串表示(恰好 36 个 char 类型字符)输出到输出迭代器 out

示例
using namespace boost::uuids;

uuid u = random_generator()();

std::vector<char> v;

to_chars( u, std::back_inserter( v ) );
template<class Ch>
  bool to_chars( uuid const& u, Ch* first, Ch* last ) noexcept;
要求

Ch 必须是字符类型(charwchar_tchar8_tchar16_tchar32_t 之一)。

效果

如果 last - first >= 36,则将 u 的字符串表示(恰好 36 个字符,不含空终止符)写入 first 指向的缓冲区,并返回 true。否则,返回 false

示例
using namespace boost::uuids;

uuid u = random_generator()();

char buf[ 36 ];

bool ret = to_chars( u, std::begin( buf ), std::end( buf ) );
assert( ret );

std::cout << std::string( buf, 36 ) << std::endl;
template<class Ch, std::size_t N>
  Ch* to_chars( uuid const& u, Ch (&buffer)[ N ] ) noexcept;
要求

Ch 必须是字符类型(charwchar_tchar8_tchar16_tchar32_t 之一);N 必须至少为 37。

效果

u 的字符串表示(恰好 37 个字符,包括空终止符)写入 buffer

返回

buffer + 36.

示例
using namespace boost::uuids;

uuid u = random_generator()();

char buf[ 37 ];

to_chars( u, buf );

std::cout << buf << std::endl;
注意
作为特殊例外,允许 N 为 36。在这种情况下,函数将恰好 36 个字符写入 buffer 并且不写入空终止符。此用法仅为向后兼容而支持,并且已弃用。请使用 37 个字符的缓冲区,以便容纳空终止符。

to_string

提供了 to_stringto_wstring 函数,以便方便地将 uuid 转换为字符串。它们可能比 boost::lexical_cast 更高效。

std::string to_string( uuid const& u );
std::wstring to_wstring( uuid const& u );
返回

一个包含 u 字符串表示的字符串。

示例
using namespace boost::uuids;

uuid u = random_generator()();

std::string s1 = to_string( u );

std::wstring s2 = to_wstring( u );

<boost/uuid/uuid_generators.hpp>

提要

这个便捷头文件提供了所有 UUID 生成器。

#include <boost/uuid/nil_generator.hpp>
#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/name_generator.hpp>
#include <boost/uuid/random_generator.hpp>

<boost/uuid/nil_generator.hpp>

提要

namespace boost {
namespace uuids {

struct nil_generator
{
    using result_type = uuid;
    uuid operator()() const noexcept;
};

uuid nil_uuid() noexcept;

}} // namespace boost::uuids

nil_generator

nil_generator 类始终生成一个 nil uuid

uuid operator()() const noexcept;
返回

一个 nil UUID。

示例
using namespace boost::uuid;

nil_generator gen;
uuid u = gen();

assert( u.is_nil() );

nil_uuid

uuid nil_uuid() noexcept;
返回

一个 nil UUID。

示例
using namespace boost::uuid;

uuid u = nil_uuid();

assert( u.is_nil() );

<boost/uuid/string_generator.hpp>

提要

namespace boost {
namespace uuids {

struct string_generator
{
    using result_type = uuid;

    template<class Ch, class Traits, class Alloc>
      uuid operator()( std::basic_string<Ch, Traits, Alloc> const& s ) const;

    uuid operator()( char const* s ) const;
    uuid operator()( wchar_t const* s ) const;

    template<class CharIterator>
      uuid operator()( CharIterator begin, CharIterator end ) const;
};

}} // namespace boost::uuids

string_generator

string_generator 类从字符串生成 uuid

支持 RFC 4122(第 3 页)中的标准定义的字符串格式,以及一些变体。

有效的字符串匹配以下 PCRE 正则表达式

^({)?([0-9a-fA-F]{8})(?-)?([0-9a-fA-F]{4})(?(DASH)-)([0-9a-fA-F]{4})(?(DASH)-)([0-9a-fA-F]{4})(?(DASH)-)([0-9a-fA-F]{12})(?(1)})$

或者更通用地说,以下格式被接受为有效的字符串格式,其中 h 是十六进制,不区分大小写,并且没有前导或尾随空格

hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh
{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
{hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh}

无效输入将生成 std::runtime_error 异常。

template<class Ch, class Traits, class Alloc>
  uuid operator()( std::basic_string<Ch, Traits, Alloc> const& s ) const;
要求

s 的字符类型 Ch 必须是 charwchar_t

效果

解析字符串 s 并将其转换为 uuid,然后返回结果。

示例
using namespace boost::uuids;

string_generator gen;

uuid u1 = gen( std::string( "0123456789abcdef0123456789abcdef" ) );
uuid u2 = gen( std::wstring( L"01234567-89AB-CDEF-0123-456789ABCDEF" ) );
uuid operator()( char const* s ) const;
uuid operator()( wchar_t const* s ) const;
效果

解析字符串 s 并将其转换为 uuid,然后返回结果。

示例
using namespace boost::uuids;

string_generator gen;

uuid u1 = gen( "{01234567-89ab-cdef-0123-456789abcdef}" );
uuid u2 = gen( L"01234567-89ab-cdef-0123-456789abcdef" );
template<class CharIterator>
  uuid operator()( CharIterator begin, CharIterator end ) const;
要求

CharIterator 必须是值类型为 charwchar_t 的输入迭代器。

效果

解析字符序列 [begin, end) 并将其转换为 uuid,然后返回结果。

示例
using namespace boost::uuids;

string_generator gen;

std::string s1( "0123456789abcdef0123456789abcdef" );
uuid u1 = gen( s1.begin(), s1.end() );

std::wstring s2( L"01234567-89AB-CDEF-0123-456789ABCDEF" );
uuid u2 = gen( s2.begin(), s2.end() );

<boost/uuid/namespaces.hpp>

提要

namespace boost {
namespace uuids {
namespace ns {

uuid dns() noexcept;
uuid url() noexcept;
uuid oid() noexcept;
uuid x500dn() noexcept;

}}} // namespace boost::uuids::ns

命名空间

此头文件提供了 RFC 4122, Appendix C 中定义的四个命名空间的定义。

uuid dns() noexcept;
返回

RFC 4122 中的 DNS 命名空间 UUID,{6ba7b810-9dad-11d1-80b4-00c04fd430c8}

uuid url() noexcept;
返回

RFC 4122 中的 URL 命名空间 UUID,{6ba7b811-9dad-11d1-80b4-00c04fd430c8}

uuid oid() noexcept;
返回

RFC 4122 中的 OID 命名空间 UUID,{6ba7b812-9dad-11d1-80b4-00c04fd430c8}

uuid x500dn() noexcept;
返回

RFC 4122 中的 X.500 DN 命名空间 UUID,{6ba7b814-9dad-11d1-80b4-00c04fd430c8}

<boost/uuid/​name_generator_sha1.hpp>

提要

#include <boost/uuid/namespaces.hpp>

namespace boost {
namespace uuids {

class name_generator_sha1
{
public:

    using result_type = uuid;

    explicit name_generator_sha1( uuid const& namespace_uuid ) noexcept;

    template<class Ch> uuid operator()( Ch const* name ) const noexcept;

    template<class Ch, class Traits, class Alloc>
      uuid operator()( std::basic_string<Ch, Traits, Alloc> const& name ) const noexcept;

    uuid operator()( void const* buffer, std::size_t byte_count ) const noexcept;
};

}} // namespace boost::uuids

name_generator_sha1

name_generator_sha1 类生成基于名称的版本 5 UUID,使用 SHA1 作为哈希算法。

explicit name_generator_sha1( uuid const& namespace_uuid );
效果

构造一个 name_generator_sha1,它使用 namespace_uuid 作为命名空间。

template<class Ch> uuid operator()( Ch const* name ) const noexcept;
要求

Ch 必须是 charwchar_tchar8_tchar16_tchar32_t 之一。

返回

从构造函数传入的命名空间的摘要以及字符串 name 的字符(转换为字节)生成的基于名称的版本 5 UUID。

备注

name 的字符按照以下方式转换为字节序列:

  • 如果 Chcharchar8_t,则字符被直接处理为字节;

  • 如果 Chwchar_t,则字符被转换为 uint32_t,然后使用小端表示法将它们序列化为四个字节;

  • 否则,字符序列被转换为 UTF-8,然后结果被处理为字节。

示例
using namespace boost::uuids;

name_generator_sha1 gen( ns::dns() );

uuid u1 = gen( "boost.org" );

std::cout << "\"boost.org\" UUID in DNS namespace, SHA1 version: " << u1 << std::endl;

// Output:
//   "boost.org" UUID in DNS namespace, SHA1 version: 0043f363-bbb4-5369-840a-322df6ec1926

uuid u2 = gen( L"boost.org" );

std::cout << "L\"boost.org\" UUID in DNS namespace, SHA1 version: " << u2 << std::endl;

// Output:
//   L"boost.org" UUID in DNS namespace, SHA1 version: c31c5016-3493-5dc2-8484-5813d495cc18

uuid u3 = gen( u"boost.org" );

std::cout << "u\"boost.org\" UUID in DNS namespace, SHA1 version: " << u3 << std::endl;

// Output:
//   u"boost.org" UUID in DNS namespace, SHA1 version: 0043f363-bbb4-5369-840a-322df6ec1926
template<class Ch, class Traits, class Alloc>
  uuid operator()( std::basic_string<Ch, Traits, Alloc> const& name ) const;
要求

Ch 必须是 charwchar_tchar8_tchar16_tchar32_t 之一。

返回

如同 operator()( name.c_str() )

uuid operator()( void const* buffer, std::size_t byte_count ) const;
返回

从构造函数传入的命名空间的摘要以及从 buffer 开始的 byte_count 个字节生成的基于名称的版本 5 UUID。

<boost/uuid/​name_generator_md5.hpp>

提要

#include <boost/uuid/namespaces.hpp>

namespace boost {
namespace uuids {

class name_generator_md5
{
public:

    using result_type = uuid;

    explicit name_generator_md5( uuid const& namespace_uuid ) noexcept;

    template<class Ch> uuid operator()( Ch const* name ) const noexcept;

    template<class Ch, class Traits, class Alloc>
      uuid operator()( std::basic_string<Ch, Traits, Alloc> const& name ) const noexcept;

    uuid operator()( void const* buffer, std::size_t byte_count ) const noexcept;
};

}} // namespace boost::uuids

name_generator_md5

name_generator_md5 类生成基于名称的版本 3 UUID,使用 MD5 作为哈希算法。

它的接口和操作与 name_generator_sha1 相同,唯一的区别是它使用 MD5 而不是 SHA1。

除了兼容性之外,没有理由使用 name_generator_md5。在几乎所有情况下都应优先使用 name_generator_sha1

示例
using namespace boost::uuids;

name_generator_md5 gen( ns::dns() );

uuid u1 = gen( "boost.org" );

std::cout << "\"boost.org\" UUID in DNS namespace, MD5 version: " << u1 << std::endl;

// Output:
//   "boost.org" UUID in DNS namespace, MD5 version: 888eca9c-e655-31a2-a46b-a2a821f6b150

uuid u2 = gen( L"boost.org" );

std::cout << "L\"boost.org\" UUID in DNS namespace, MD5 version: " << u2 << std::endl;

// Output:
//   L"boost.org" UUID in DNS namespace, MD5 version: 48149232-8cda-361b-b355-0bdb71d2cab3

uuid u3 = gen( u"boost.org" );

std::cout << "u\"boost.org\" UUID in DNS namespace, MD5 version: " << u3 << std::endl;

// Output:
//   u"boost.org" UUID in DNS namespace, MD5 version: 888eca9c-e655-31a2-a46b-a2a821f6b150

<boost/uuid/name_generator.hpp>

提要

#include <boost/uuid/name_generator_sha1.hpp>
#include <boost/uuid/name_generator_md5.hpp>

namespace boost {
namespace uuids {

// only provided for backward compatibility

using name_generator = name_generator_sha1;
using name_generator_latest = name_generator_sha1;

}} // namespace boost::uuids

此头文件使 name_generator_sha1name_generator_md5 可用,并声明兼容性别名 name_generatorname_generator_latest

<boost/uuid/​basic_random_generator.hpp>

提要

namespace boost {
namespace uuids {

template<class UniformRandomNumberGenerator>
class basic_random_generator
{
private:

    // exposition only
    UniformRandomNumberGenerator* p_;
    UniformRandomNumberGenerator g_;

public:

    using result_type = uuid;

    basic_random_generator();

    explicit basic_random_generator( UniformRandomNumberGenerator& gen );
    explicit basic_random_generator( UniformRandomNumberGenerator* pGen );

    result_type operator()();
};

}} // namespace boost::uuids

basic_random_generator

类模板 basic_random_generator 从随机数生成器(符合标准概念 UniformRandomBitGenerator 或 Boost.Random 概念 UniformRandomNumberGenerator)生成基于随机数的版本 4 UUID。

默认构造函数将使用从 std::random_device 获取的熵来播种随机数生成器。

其他构造函数允许您提供自己的 UniformRandomNumberGenerator,并且您负责在必要时对其进行正确播种。

basic_random_generator();
效果

值初始化 g_ 并将 p_ 初始化为 nullptr。如果 g_.seed() 是有效表达式,则调用 g_.seed( seed_seq ); 来播种 g_,其中 seed_seq 是一个提供 generate( first, last ) 成员函数以使用从 std::random_device 获取的熵填充范围 [first, last) 的对象。

注意
符合标准概念 RandomNumberEngine 或 Boost.Random 概念 PseudoRandomNumberGenerator 的随机数生成器提供此类 seed 成员函数。
explicit basic_random_generator( UniformRandomNumberGenerator& gen );
效果

值初始化 g_ 并将 p_ 初始化为 &gen

explicit basic_random_generator( UniformRandomNumberGenerator* pGen );
效果

值初始化 g_ 并将 p_ 初始化为 pGen

result_type operator()();
效果

使用来自 *p_(如果 p_ != nullptr)或来自 g_(否则)的随机数生成并返回一个版本 4 UUID。

示例
using namespace boost::uuids;

basic_random_generator<boost::mt19937> bulkgen;

for( int i = 0; i < 1000; ++i )
{
    uuid u = bulkgen();
    // do something with u
}

<boost/uuid/​random_generator.hpp>

提要

#include <boost/uuid/basic_random_generator.hpp>

namespace boost {
namespace uuids {

// recommended for all uses

class random_generator
{
private:

    // exposition only
    unspecified-csprng-type g_;

public:

    using result_type = uuid;

    random_generator();

    result_type operator()();
};

// only provided for backward compatibility

using random_generator_mt19937 = basic_random_generator<std::mt19937>;
using random_generator_pure = basic_random_generator<std::random_device>;

}} // namespace boost::uuids

random_generator

random_generator 类使用密码学上强的随机数生成器生成 UUID,该生成器以来自 std::random_device 的熵进行播种。这是生成版本 4 基于随机数的 UUID 的推荐方法。

random_generator();
效果

使用从 std::random_device 获取的熵初始化 g_(一个密码学上强的随机数生成器的实例)。

result_type operator()();
效果

使用来自 g_ 的随机数生成并返回一个版本 4 UUID。

示例
using namespace boost::uuids;

random_generator gen;

uuid u1 = gen();
std::cout << u1 << std::endl;

uuid u2 = gen();
std::cout << u2 << std::endl;

assert( u1 != u2 );

random_generator_mt19937

random_generator_mt19937basic_random_generator<std::mt19937> 的别名,仅为向后兼容而提供。

random_generator_pure

random_generator_purebasic_random_generator<std::random_device> 的别名,仅为向后兼容而提供。

<boost/uuid/uuid_clock.hpp>

提要

namespace boost {
namespace uuids {

class uuid_clock
{
public:

    using rep = std::int64_t;
    using period = std::ratio<1, 10000000>; // 100ns
    using duration = std::chrono::duration<rep, period>;
    using time_point = std::chrono::time_point<uuid_clock, duration>;

    static constexpr bool is_steady = false;

    static time_point now() noexcept;

    template<class Duration>
      static time_point from_sys(
        std::chrono::time_point<std::chrono::system_clock, Duration> const& tp ) noexcept;

    static std::chrono::time_point<std::chrono::system_clock, duration>
      to_sys( time_point const& tp ) noexcept;

    static time_point from_timestamp( std::uint64_t timestamp ) noexcept;
    static std::uint64_t to_timestamp( time_point const& tp ) noexcept;
};


}} // namespace boost::uuids

uuid_clock 类是一个与 <chrono> 兼容的时钟,其纪元为 1582 年 10 月 15 日 00:00:00.00,分辨率为 100 ns。这些值在 RFC 4122 Section 4.1.4 中指定。

now

static time_point now() noexcept;
返回

当前系统时间(std::chrono::system_clock::now(),转换为 uuid_clock::time_point。)

from_sys

template<class Duration>
  static time_point from_sys(
    std::chrono::time_point<std::chrono::system_clock, Duration> const& tp ) noexcept;
返回

tp 对应的 uuid_clock::time_point

to_sys

static std::chrono::time_point<std::chrono::system_clock, duration>
  to_sys( time_point const& tp ) noexcept;
返回

tp 对应的 std::chrono::system_clock::time_point

示例
#include <boost/uuid/time_generator_v1.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_clock.hpp>
#include <chrono>

using namespace boost::uuids;

int main()
{
    time_generator_v1 gen;

    uuid u = gen(); // generates a version 1 time-based UUID

    // note that stream output of std::chrono::system_clock::time_point requires C++20

    std::cout << uuid_clock::to_sys( u.time_point_v1() ) << std::endl;
}

from_timestamp

static time_point from_timestamp( std::uint64_t timestamp ) noexcept;
返回

timestamp(自 uuid_clock 纪元以来的 100 纳秒间隔数)对应的 uuid_clock::time_point

to_timestamp

static std::uint64_t to_timestamp( time_point const& tp ) noexcept;
返回

tp 对应的 uuid_clock 纪元以来的 100 纳秒间隔数。

示例
using namespace boost::uuids;

uuid u = time_generator_v1()();

assert( u.timestamp_v1() == uuid_clock::to_timestamp( u.time_point_v1() ) );

<boost/uuid/​time_generator_v1.hpp>

提要

namespace boost {
namespace uuids {

class time_generator_v1
{
public:

    struct state_type
    {
        std::uint64_t timestamp;
        std::uint16_t clock_seq;
    };

private: // exposition only

    uuid::node_type node_ = {};

    std::atomic<state_type>* ps_ = nullptr;
    state_type state_ = {};

public:

    using result_type = uuid;

    time_generator_v1();
    time_generator_v1( uuid::node_type const& node, state_type const& state ) noexcept;
    time_generator_v1( uuid::node_type const& node, std::atomic<state_type>& state ) noexcept;

    result_type operator()() noexcept;
};

}} // namespace boost::uuids

time_generator_v1 类生成基于时间的版本 1 UUID。它支持三种操作模式。

默认且推荐的模式是使用其默认构造函数。这指示生成器使用伪随机节点标识符和初始时钟序列。

如果需要更多地控制节点标识符(或时钟序列),例如,如果生成的 UUID 必须使用在程序生命周期内甚至跨程序运行都持久存在的特定节点标识符,则提供了一个接受节点标识符和 state_type 的构造函数。(提供的 state_typetimestamp 字段通常应为零。)

最后,如果程序中有多个 time_generator_v1 实例(例如,每个线程一个)需要使用相同的节点标识符,则第三个构造函数接受节点标识符和 std::atomic<state_type> 的引用。原子状态由生成器使用,以确保不会产生重复的 UUID。

构造函数

time_generator_v1();
效果

使用来自 std::random_device 的熵,在 node_ 中生成伪随机 48 位节点标识符,并在 state_.clock_seq 中生成伪随机 14 位时钟序列。将 state_.timestamp 初始化为零。

备注

node_ 的多播位被设置以表示本地节点标识符,如 RFC 4122 Section 4.5 中建议的那样。

time_generator_v1( uuid::node_type const& node, state_type const& state ) noexcept;
效果

初始化 node_node,并将 state_ 初始化为 state

time_generator_v1( uuid::node_type const& node, std::atomic<state_type>& state ) noexcept;
效果

初始化 node_node,并将 ps_ 初始化为 &state

operator()

result_type operator()() noexcept;
效果

使用 state_ 中的状态(如果 ps_nullptr),或使用 *ps_ 中的状态(如果 ps_ 不为 nullptr),原子地计算并设置新状态,通过获取系统时间(如同使用 uuid_clock::now()),将其转换为时间戳(如同使用 uuid_clock::to_timestamp),将结果存储在 state.timestamp 中,并在新时间戳低于或等于前一时间戳时将 state.clock_seq 模 0x4000 递增。

使用 node_ 的节点标识符以及新的时间戳和时钟序列创建一个版本 1 UUID 并返回它。

<boost/uuid/​time_generator_v6.hpp>

提要

namespace boost {
namespace uuids {

class time_generator_v6
{
public:

    struct state_type
    {
        std::uint64_t timestamp;
        std::uint16_t clock_seq;
    };

private: // exposition only

    uuid::node_type node_ = {};

    std::atomic<state_type>* ps_ = nullptr;
    state_type state_ = {};

public:

    using result_type = uuid;

    time_generator_v6();
    time_generator_v6( uuid::node_type const& node, state_type const& state ) noexcept;
    time_generator_v6( uuid::node_type const& node, std::atomic<state_type>& state ) noexcept;

    result_type operator()() noexcept;
};

}} // namespace boost::uuids

time_generator_v6 类生成基于时间的版本 6 UUID,如 RFC 9562 第 5.6 节所述。

它的操作方式与 time_generator_v1 完全相同,唯一的区别是它生成版本 6 UUID 而不是版本 1 UUID。

<boost/uuid/​time_generator_v7.hpp>

提要

namespace boost {
namespace uuids {

class time_generator_v7
{
private:

    // exposition only
    unspecified-csprng-type rng_;

public:

    using result_type = uuid;

    time_generator_v7();

    time_generator_v7( time_generator_v7 const& rhs );
    time_generator_v7( time_generator_v7&& rhs ) noexcept;

    time_generator_v7& operator=( time_generator_v7 const& rhs ) noexcept;
    time_generator_v7& operator=( time_generator_v7&& rhs ) noexcept;

    result_type operator()() noexcept;
};

}} // namespace boost::uuids

time_generator_v7 类生成基于时间的版本 7 UUID,如 RFC 9562 第 5.7 节所述。

构造函数

time_generator_v7();
效果

使用来自 std::random_device 的熵初始化内部密码学上强的伪随机数生成器 (CSPRNG) rng_

time_generator_v7( time_generator_v7 const& rhs );
效果

rhs 的状态复制到 *this,然后使用来自 std::random_device 的熵重新播种 this->rng_

备注

重新播种确保两个生成器在复制后不会产生相同的随机数序列。

time_generator_v7( time_generator_v7&& rhs ) noexcept;
效果

rhs 的状态复制到 *this,然后扰乱 rhs.rng_ 的状态,使其不再产生相同的随机数序列。

赋值

time_generator_v7& operator=( time_generator_v7 const& rhs ) noexcept;
效果

rhs 的状态复制到 *this,但 this->rng_ 保持不变。

返回

*this.

备注

不修改 this->rng_ 可确保两个生成器继续产生不同的随机数。

time_generator_v7& operator=( time_generator_v7&& rhs ) noexcept;
效果

rhs 的状态复制到 *this,然后扰乱 rhs.rng_ 的状态,使其不再产生相同的随机数序列。

返回

*this.

operator()

result_type operator()() noexcept;
效果
  1. 获取新的时间戳,如同通过 std::chrono::system_clock::now() 获取系统时间并将其转换为自 Unix 纪元以来的微秒数。

  2. 创建一个新的版本 7 UUID,并使用时间戳中的毫秒数初始化其 unix_ts_ms 字段。

  3. 使用时间戳中的剩余微秒数初始化 rand_a 字段。

  4. 初始化 rand_b 字段的 6 位(紧随变体之后)为冲突解决计数器,这样即使使用相同时间戳生成多个 UUID,也仍然可以保证单调性。

  5. 使用内部 CSPRNG rng_ 获取的随机值初始化 rand_b 字段的其余部分。

  6. 返回 UUID。

备注

如果满足以下条件,operator() 会生成单调递增的 UUID 序列:

  • 系统时钟永不回溯;

  • 系统时钟至少具有毫秒级分辨率;

  • 每微秒生成的 UUID 不超过 64 个(每 16 纳秒不超过一个)。

<boost/uuid/time_generator.hpp>

提要

#include <boost/uuid/time_generator_v1.hpp>
#include <boost/uuid/time_generator_v6.hpp>
#include <boost/uuid/time_generator_v7.hpp>

这个便捷头文件提供了三个基于时间的生成器:time_generator_v1time_generator_v6time_generator_v7

设计说明

文档 http://www.itu.int/ITU-T/studygroups/com17/oid/X.667-E.pdf 被用于设计和实现 uuid 结构。

所有函数都是可重入的。类与 int 的线程安全性相同。也就是说,不能在没有适当同步的情况下在线程之间共享实例。

致谢

boost.org 邮件列表中的许多人都提供了有用的评论,并极大地帮助塑造了该库。

文档由 Christian Mazakas 转换为 Asciidoc 格式。

版权所有 2006 Andy Tompkins

版权所有 2017 James E. King III

版权所有 2024 Christian Mazakas

版权所有 2024 Peter Dimov

旧修订历史

本节包含旧的修订历史,以前作为注释保存在库头文件中。

boost/uuid/uuid.hpp

// 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

boost/uuid/uuid_io.hpp

// Revision History
//  20 Mar 2009 - Initial Revision
//  28 Nov 2009 - disabled deprecated warnings for MSVC

boost/uuid/detail/sha1.hpp

// 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)