Boost C++ 库

...世界上最受推崇和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

简介

UUID,或通用唯一标识符,旨在在分布式环境中唯一标识信息,而无需重要的中央协调。它可用于标记生命周期非常短的对象,或可靠地跨网络识别非常持久的对象。

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

UUID 有许多应用。以下是一些示例:数据库可以使用 UUID 来标识行或记录,以确保它们在不同的数据库中是唯一的,或者用于发布/订阅服务。网络消息可以使用 UUID 进行标识,以确保消息的不同部分可以重新组合在一起。分布式计算可以使用 UUID 来标识远程过程调用。事务和序列化中涉及的类可以通过 UUID 标识。微软的组件对象模型 (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(),其中 u 的类型为 uuid,现在返回指向表示形式的第一个 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 指令子集(即相当于 Intel Skylake-X)的 CPU 兼容。

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

对齐

描述

BOOST_UUID_DISABLE_ALIGNMENT

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

默认情况下,uuid 具有与 std::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 {00000000-0000-0000-0000-000000000000} 时为 true,否则为 false

变体

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 以来的 100 纳秒间隔数)。该值仅对版本 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 以来的 100 纳秒间隔数)。该值仅对版本 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

自由 Swap

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;

序列化

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 个字符,不以 null 结尾)写入以 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 个字符,包括 null 终止符)写入 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,并且不写入 null 终止符。此用法仅为了向后兼容性而支持,并且已弃用。请改用 37 个字符的缓冲区,以便容纳 null 终止符。

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 (p. 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,附录 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 使用 SHA1 作为哈希算法,生成基于名称的版本 5 UUID。

explicit name_generator_sha1( uuid const& namespace_uuid );
效果

构造一个使用 namespace_uuid 作为命名空间的 name_generator_sha1

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

Ch 必须是 charwchar_tchar8_tchar16_tchar32_t 之一。

返回值

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

备注

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;
返回值

基于名称的版本 5 UUID,由传递给构造函数的命名空间以及从 buffer 开始的 byte_count 八位字节的摘要生成。

<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 使用 MD5 作为哈希算法,生成基于名称的版本 3 UUID。

其接口和操作与 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_ != nullptr,则使用从 *p_ 获取的随机数生成并返回版本 4 UUID;否则,使用从 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 纳秒。这些值在 RFC 4122 第 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;
返回值

与自 uuid_clock 纪元以来的 timestamp 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 第 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;
效果

如果 ps_nullptr,则使用 state_ 中的状态;如果 ps_ 不为 nullptr,则使用 *ps_ 中的状态;通过像 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. rand_b 字段的其余部分初始化为从内部 CSPRNG rng_ 获取的随机值。

  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)