C ++ 17普遍的に一意の識別子のためのC ++ 17クロスプラットフォームシングルヘッダーライブラリの実装は、UUIDまたはGUID(主にWindows上)として単純に知られています。 UUIDは、データベーステーブルキー、COMインターフェイス、クラス、タイプライブラリなど、コンピューターシステムの情報を一意に識別するために使用される128ビット番号です。
UUID/GUIDの詳細については、以下を参照してください。
仕様はUUIDライブラリをstdネームスペースに配置しますが、この実装では、 stdネームスペースに課される制限に違反することなくライブラリを使用可能にするために、この目的のために名前空間uuidsを使用します。次のタイプとユーティリティが利用可能です。
基本タイプ:
| 名前 | 説明 |
|---|---|
uuid | UUIDを表すクラス。これは、デフォルト構築(nil uuid)を構築することができます。これは、範囲(ペアのイテレーターで定義)またはspanから構築されます。 |
uuid_variant | UUIDのタイプを表す強いタイプの列 |
uuid_version | UUIDのバージョンを表す強いタイプの列 |
ジェネレーター:
| 名前 | 説明 |
|---|---|
basic_uuid_random_generator | 擬似ランダム番号ジェネレーターエンジンを使用してバージョン4 UUIDを生成する関数オブジェクト。 |
uuid_random_generator | Mersenne Twister Engineを使用したbasic_uuid_random_generator ( basic_uuid_random_generator<std::mt19937> ) |
uuid_name_generator | SHA1ハッシュを使用して、名前ベースのUUIDを生成する関数オブジェクト。 |
uuid_system_generator | オペレーティングシステムリソースを使用して新しいUUIDを生成する関数オブジェクト(WindowsのCoCreateGuid 、linuxのuuid_generate 、macでCFUUIDCreate )注:これは標準的な提案の一部ではありません。 UUID_SYSTEM_GENERATORマクロが定義されている場合にのみ使用できます。 |
uuid_time_generator | 時間ベースのUUIDを生成する実験関数オブジェクト。 注:これは実験機能であり、生産コードでは使用しないでください。 UUID_TIME_GENERATORマクロが定義されている場合にのみ使用できます。 |
ユーティリティ:
| 名前 | 説明 |
|---|---|
std::swap<> | uuidのswapの専門化 |
std::hash<> | uuidのhashの専門化( std::unordered_setなどの順序付けられていない連想容器にUUIDを保存するために必要) |
定数:
| 名前 | 説明 |
|---|---|
uuid_namespace_dns | 名前ベースのuuidの名前空間IDという名前の文字列が完全に適格なドメイン名である場合。 |
uuid_namespace_url | 名前ベースのuuidの名前空間IDという名前の文字列がURLの場合。 |
uuid_namespace_oid | 名前ベースのuuidの名前空間ID mame stringがiso oidである場合(https://oidref.com/、https://en.wikipedia.org/wiki/object_identifierを参照)。 |
uuid_namespace_x500 | 名前ベースのUUIDの名前空間ID名文字列がx.500 dn、derまたはテキスト出力形式の場合(https://en.wikipedia.org/wiki/x.500、https://en.wikipedia.org/wiki/abstract_syntax_notation_notation_notation_notation_notationを参照してください。 |
他の:
| 名前 | 説明 |
|---|---|
operator==およびoperator!= | uuidsのための平等/不平等の比較 |
operator< | 1つのuuidが別のuuidよりも少ないかどうかを比較するため。この操作はそれほど論理的な意味ではありませんが、UUIDをSTD ::セットに保存するために必要です。 |
operator<< | 標準的なテキスト表現を使用して出力ストリームにUUIDを書き込む。 |
to_string() | UUIDの正規のテキスト表現を含む文字列を作成します。 |
このライブラリは、提案P0959の実装です。
提案が標準委員会とC ++コミュニティのフィードバックに基づいて進化するにつれて、このライブラリの実装はこれらの変更を反映します。
変更の歴史の提案の改訂履歴を参照してください。
以下は、ライブラリを使用するための例のリストです。
nil uuidを作成します
uuid empty;
assert (empty.is_nil());新しいUUIDを作成します
uuid const id = uuids::uuid_system_generator{}();
assert (!id.is_nil());
assert (id.version() == uuids::uuid_version::random_number_based);
assert (id.variant() == uuids::uuid_variant::rfc);デフォルトのランダムジェネレーターを使用して新しいUUIDを作成します
std::random_device rd;
auto seed_data = std::array< int , std::mt19937::state_size> {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::mt19937 generator (seq);
uuids::uuid_random_generator gen{generator};
uuid const id = gen();
assert (!id.is_nil());
assert (id.as_bytes().size() == 16);
assert (id.version() == uuids::uuid_version::random_number_based);
assert (id.variant() == uuids::uuid_variant::rfc);特定のランダムジェネレーターを使用して新しいUUIDを作成します
std::random_device rd;
auto seed_data = std::array< int , 6 > {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::ranlux48_base generator (seq);
uuids::basic_uuid_random_generator<std::ranlux48_base> gen (&generator);
uuid const id = gen();
assert (!id.is_nil());
assert (id.as_bytes().size() == 16);
assert (id.version() == uuids::uuid_version::random_number_based);
assert (id.variant() == uuids::uuid_variant::rfc);名前ジェネレーターを使用して新しいUUIDを作成します
uuids::uuid_name_generator gen (uuids::uuid::from_string( " 47183823-2574-4bfd-b411-99ed177d3e43 " ).value());
uuid const id = gen( " john " );
assert (!id.is_nil());
assert (id.version() == uuids::uuid_version::name_based_sha1);
assert (id.variant() == uuids::uuid_variant::rfc);文字列からuuidを作成します
auto str = " 47183823-2574-4bfd-b411-99ed177d3e43 " s;
auto id = uuids::uuid::from_string(str);
assert (id.has_value());
assert (uuids::to_string(id.value()) == str);
// or
auto str = L" 47183823-2574-4bfd-b411-99ed177d3e43 " s;
uuid id = uuids::uuid::from_string(str).value();
assert (uuids::to_string< wchar_t >(id) == str);16バイトのシーケンスからUUIDを作成します
std::array<uuids::uuid::value_type, 16 > arr{{
0x47 , 0x18 , 0x38 , 0x23 ,
0x25 , 0x74 ,
0x4b , 0xfd ,
0xb4 , 0x11 ,
0x99 , 0xed , 0x17 , 0x7d , 0x3e , 0x43 }};
uuid id (arr);
assert (uuids::to_string(id) == "47183823-2574-4bfd-b411-99ed177d3e43");
// or
uuids::uuid::value_type arr[ 16 ] = {
0x47 , 0x18 , 0x38 , 0x23 ,
0x25 , 0x74 ,
0x4b , 0xfd ,
0xb4 , 0x11 ,
0x99 , 0xed , 0x17 , 0x7d , 0x3e , 0x43 };
uuid id (std::begin(arr), std::end(arr));
assert (uuids::to_string(id) == "47183823-2574-4bfd-b411-99ed177d3e43");
// or
uuids::uuid id{{
0x47 , 0x18 , 0x38 , 0x23 ,
0x25 , 0x74 ,
0x4b , 0xfd ,
0xb4 , 0x11 ,
0x99 , 0xed , 0x17 , 0x7d , 0x3e , 0x43 }};
assert (uuids::to_string(id) == "47183823-2574-4bfd-b411-99ed177d3e43");UUIDの比較
uuid empty;
uuid id = uuids::uuid_system_generator{}();
assert (empty == empty);
assert (id == id);
assert (empty != id);UUIDを交換します
uuid empty;
uuid id = uuids::uuid_system_generator{}();
assert (empty.is_nil());
assert (!id.is_nil());
std::swap (empty, id);
assert (!empty.is_nil());
assert (id.is_nil());
empty.swap(id);
assert (empty.is_nil());
assert (!id.is_nil());文字列への変換
uuid empty;
assert (uuids::to_string(empty) == "00000000-0000-0000-0000-000000000000");
assert (uuids::to_string< wchar_t >(empty) == L"00000000-0000-0000-0000-000000000000");注文された連想容器で使用します
std::random_device rd;
auto seed_data = std::array< int , std::mt19937::state_size> {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::mt19937 engine (seq);
uuids::uuid_random_generator gen (&engine);
std::set<uuids::uuid> ids{uuid{}, gen (), gen (), gen (), gen ()};
assert (ids.size() == 5);
assert (ids.find(uuid{}) != ids.end());順序付けられていない連想容器で使用します
std::random_device rd;
auto seed_data = std::array< int , std::mt19937::state_size> {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::mt19937 engine (seq);
uuids::uuid_random_generator gen (&engine);
std::unordered_set<uuids::uuid> ids{uuid{}, gen (), gen (), gen (), gen ()};
assert (ids.size() == 5);
assert (ids.find(uuid{}) != ids.end());Hashing uuids
using namespace std ::string_literals ;
auto str = " 47183823-2574-4bfd-b411-99ed177d3e43 " s;
uuid id = uuids::uuid::from_string(str).value();
auto h1 = std::hash<std::string>{};
auto h2 = std::hash<uuid>{};
assert (h1(str) == h2(id)); basic_uuid_random_generatorおよびstd :: random_deviceを使用してuuidsを生成してジェネレーターをシードする場合、これは非決定的ではなく、実際に同じ数字のシーケンスを生成する可能性があることに留意してください。
STD :: RANDOM_DEVICEは、非決定的なソース(ハードウェアデバイスなど)が実装に利用できない場合、実装定義の擬似ランダム番号エンジンに関して実装できます。この場合、各std :: random_deviceオブジェクトは同じ数値シーケンスを生成する場合があります。
これはMingwの問題になる可能性があります。バグ85494を参照 - MINGWでのRANDOM_DEVICEの実装は役に立たない。これはGCC 9.2で修正されました。
ポータブルな代替品は、Boost.randomライブラリを使用することです。
ライブラリは、Windows、Linux、Mac OSのすべての主要なオペレーティングシステムでサポートされています。
C ++ 20で構築されたプロジェクトでライブラリを使用する場合は、 std::spanを使用できます。これは、ヘッダーがコンパイラによってサポートされている場合、デフォルトで使用されます。チェックは、__CPP_LIB_SPAN機能テストマクロで行われます。
それ以外の場合は、C ++ 17で構築する場合など、 std::spanは利用できません。ただし、Microsoftガイドラインサポートライブラリ(別名GSL)は、そのspan実装に使用できます(標準バージョンが定義されました)。 STDUUIDライブラリは、 std::spanが利用できない場合、この実装を使用するデフォルトです。
gsl::spanを使用できるようにするには、GSLライブラリが利用可能であることを確認し、GSLが含まれるディレクトリがプロジェクトのディレクトリを含むディレクトリにリストされています。
Cmakeを使用してテストプロジェクトを構築する場合、 UUID_USING_CXX20_SPANと呼ばれる変数が定義されていないか、値がOFFいることを確認してください(これはデフォルト値です)。これにより、 gslディレクトリがヘッダーディレクトリの検索リストに含まれるようになります。
テストプロジェクトは情報源で利用できます。テストを構築および実行するには、次のことを行います。
buildディレクトリを作成するcmake .. build Directoryから実行します。 cmakeを持っていない場合は、最初にインストールする必要があります。例
Visual Studio 2019のプロジェクトファイルを生成するには、次のコマンドを実行できます。
cd build
cmake -G "Visual Studio 17" -A x64 ..
オペレーティングシステムを有効にするには、 UUID_SYSTEM_GENERATOR変数をONに設定します。
cd build
cmake -G "Visual Studio 17" -A x64 -DUUID_SYSTEM_GENERATOR=ON ..
実験時間ベースのUUIDジェネレーターを有効にするには、 UUID_TIME_GENERATOR変数をONに設定します。
cd build
cmake -G "Visual Studio 17" -A x64 -DUUID_TIME_GENERATOR=ON ..
SHA1の実装は、Tinysha1ライブラリに基づいています。