Boost C++ 库

……世界上最受推崇和设计精良的 C++ 库项目之一。 Herb SutterAndrei AlexandrescuC++ 编码规范

引言

UUID(通用唯一标识符)旨在唯一地识别分布式环境中的信息,而无需大量的集中协调。它可以用来标记生命周期很短的对象,或可靠地识别跨网络的持久对象。

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

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 中的更改

  • 恢复了在 1.86 中意外丢失的构造 `constexpr uuid` 的能力。

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_nil`、`operator==`、`operator<`、`swap` 和 `operator<=>` 的通用(非 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_md5` 和 `name_generator_sha1`),因此它成为一个私有实现细节,不再是公共接口的一部分。

  • 虽然仍然提供 `name_generator` 和 `name_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* last` 和 `Ch(&&)[N]` 的 `to_chars` 的重载。

  • `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 指令子集的 CPU 兼容(即等效于 Intel Skylake-X)。

默认情况下,库尝试在编译时检测目标 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 以来 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)有意义。

交换

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

此函数允许使用boost::hash来使用uuid实例。

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

此特化允许使用std::hash来使用uuid实例。

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(第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之一。

返回

从构造函数传递的命名空间和字符串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类使用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_

示例
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第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;
返回

对应于tpuuid_clock::time_point

to_sys

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

对应于tpstd::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纪元以来的100纳秒间隔的timestampuuid_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初始化为零。

备注

根据RFC 4122 第4.5节的建议,设置node_的多播位以表示本地节点标识符。

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_不为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序列

  • 系统时钟永不倒退;

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

  • 每微秒最多生成64个UUID(每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)