Boost C++ 库

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei 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.90.0 中的更改

  • string_generator 在 C++14 及更高版本中现在是 constexpr

  • 添加了头文件 boost/uuid/constants.hpp

  • boost/uuid/uuid_generators.hpp 重命名为 boost/uuid/generators.hpp。为了兼容性,保留了旧名称。

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` 类型可用时使用 `__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() 字符串。

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

  • 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 扩展的可用性,并在成功时自动定义相应的宏。如果自动检测失败且已知目标 CPU 将具有该扩展,则用户可以定义 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/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/generators.hpp>
#include <boost/uuid/constants.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

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 起的 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

免费交换

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 必须是字符类型(char, wchar_t, char8_t, char16_t, char32_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 必须是字符类型(char, wchar_t, char8_t, char16_t, char32_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/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

效果

解析字符串 suuid 并返回结果。

示例
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;
效果

解析字符串 suuid 并返回结果。

示例
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 类使用 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,由构造函数传递的命名空间及其 byte_count 个字节(从 buffer 开始)的摘要生成。

<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_(如果 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;
返回

uuid_clock 纪元起的 100 纳秒间隔数,对应于 tp

示例
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 section 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 section 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

<boost/uuid/constants.hpp>

提要

#include <boost/uuid/namespaces.hpp>

namespace boost {
namespace uuids {

uuid nil_uuid() noexcept;

}} // namespace boost::uuids

常量

此头文件提供了几个著名 UUID 常量的定义。

uuid nil_uuid() noexcept;
返回

nil UUID,{00000000-0000-0000-0000-000000000000}

设计说明

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

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

致谢

boost.org 邮件列表上的一些人提供了有用的评论,并极大地帮助塑造了这个库。

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

Copyright 2006 Andy Tompkins

Copyright 2017 James E. King III

Copyright 2024 Christian Mazakas

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