Boost C++ 函式庫

...世界上最受推崇且設計精良的 C++ 函式庫專案之一。 Herb SutterAndrei Alexandrescu,《C++ Coding Standards

簡介

UUID,或稱通用唯一識別碼,旨在於分散式環境中無需大量中央協調即可唯一識別資訊。它可用於標記生命週期非常短的物件,或用於在網路上可靠地識別非常持久的物件。

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

UUID 有許多應用。以下是一些範例:資料庫可以使用 UUID 來識別資料列或記錄,以確保它們在不同資料庫之間是唯一的,或者用於發佈/訂閱服務。網路訊息可以用 UUID 進行識別,以確保訊息的不同部分可以重新組合在一起。分散式運算可以使用 UUID 來識別遠端程序呼叫。序列化中涉及的交易和類別可以用 UUID 進行識別。Microsoft 的元件物件模型 (COM) 使用 UUID 來區分不同的軟體元件介面。UUID 會插入到 Microsoft Office 程式中的文件中。UUID 可識別進階系統格式 (ASF) 中的音訊或視訊串流。UUID 也是 OID(物件識別碼)和 URN(統一資源名稱)的基礎。

與其他方案相比,UUID 的一個吸引人的特性是它們相對較小的尺寸,只有 128 位元或 16 位元組。另一個特性是 UUID 的建立不需要中央授權機構。

當 UUID 是透過定義的機制之一產生時,它們要麼保證是唯一的,與所有其他產生的 UUID 不同(也就是說,它以前從未產生過,以後也不會再產生),要麼極有可能 是唯一的(取決於機制)。

修訂紀錄

Boost 1.87.0 的變更

  • 恢復了在 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_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 現在使用以 std::random_device 的熵作為種子的加密強度偽隨機數產生器 (ChaCha20/12)。這是產生版本 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> 相容的時鐘,其 epoch 和解析度如 RFC 4122 中所述。

  • 已將時間戳記、時間點、時鐘序列和節點識別碼的存取器新增至 uuid

  • 改進了 string_generator 拋出的 std::runtime_error 例外的 what() 字串。

  • 新增了採用 Ch* first, Ch* lastCh(&)[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 以來的 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)有意義。

交換

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。(譯註:<=> 為 C++20 的三向比較運算子)

自由交換

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_(如果 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 類別使用以 std::random_device 的熵值作為種子的密碼學強度隨機數產生器來產生 UUID。這是產生基於隨機的版本 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;
返回

對應於 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 紀元以來 timestamp 個 100 奈秒間隔的 uuid_clock::time_point

to_timestamp

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

uuid_clock 紀元以來對應於 tp 的 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_ 中的狀態(如果 ps_ 不為 nullptr),以原子方式計算並設定新狀態,方法是像 uuid_clock::now() 那樣擷取系統時間,像 uuid_clock::to_timestamp 那樣將其轉換為時間戳記,將結果儲存在 state.timestamp 中,如果新的時間戳記小於或等於先前的時間戳記,則將 state.clock_seq 以 0x4000 為模遞增。

使用 node_ 中的節點識別碼以及新的時間戳記和時鐘序列建立一個版本 1 的 UUID 並返回它。

<boost/uuid/time_generator_v6.hpp>

概要

namespace boost {
namespace uuids {

class time_generator_v6
{
public:

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

private: // exposition only

    uuid::node_type node_ = {};

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

public:

    using result_type = uuid;

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

    result_type operator()() noexcept;
};

}} // namespace boost::uuids

time_generator_v6 類別會產生基於時間的版本 6 UUID,如 RFC 9562 第 5.6 節所述。

它的操作方式與 time_generator_v1 完全相同,唯一的區別是它產生版本 6 的 UUID 而不是版本 1 的 UUID。

<boost/uuid/time_generator_v7.hpp>

概要

namespace boost {
namespace uuids {

class time_generator_v7
{
private:

    // exposition only
    unspecified-csprng-type rng_;

public:

    using result_type = uuid;

    time_generator_v7();

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

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

    result_type operator()() noexcept;
};

}} // namespace boost::uuids

time_generator_v7 類別會產生基於時間的版本 7 UUID,如 RFC 9562 第 5.7 節所述。

建構函式

time_generator_v7();
效果

使用 std::random_device 的熵值初始化內部的密碼學安全偽亂數產生器 (CSPRNG) rng_

time_generator_v7( time_generator_v7 const& rhs );
效果

rhs 的狀態複製到 *this,然後使用 std::random_device 的熵值重新設定 this->rng_ 的種子。

備註

重新設定種子可確保兩個產生器在複製後不會產生相同的亂數序列。

time_generator_v7( time_generator_v7&& rhs ) noexcept;
效果

rhs 的狀態複製到 *this,然後擾動 rhs.rng_ 的狀態,使其不再產生相同的亂數序列。

賦值

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

rhs 的狀態複製到 *this,但 this->rng_ 除外,它保持不變。

返回

*this.

備註

不修改 this->rng_ 可確保兩個產生器繼續產生不同的亂數。

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

rhs 的狀態複製到 *this,然後擾動 rhs.rng_ 的狀態,使其不再產生相同的亂數序列。

返回

*this.

operator()

result_type operator()() noexcept;
效果
  1. 取得新的時間戳記,如同從 std::chrono::system_clock::now() 取得系統時間並將其轉換為自 Unix 紀元以來的微秒數。

  2. 建立新的版本 7 UUID,並使用時間戳記中的毫秒數初始化其 unix_ts_ms 欄位。

  3. 使用時間戳記中剩餘的微秒數初始化 rand_a 欄位。

  4. 將變體後 rand_b 欄位的 6 個位元初始化為衝突解決計數器,以便在使用相同時間戳記產生多個 UUID 時,仍然可以確保單調性。

  5. 使用從內部 CSPRNG rng_ 取得的亂數值初始化 rand_b 欄位的其餘部分。

  6. 返回 UUID。

備註

如果滿足以下要求,operator() 會產生單調遞增的 UUID 序列:

  • 系統時鐘永不回溯;

  • 系統時鐘至少具有毫秒解析度;

  • 每微秒產生不超過 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)