stduuid

repository·master·Indexed 21 days ago

https://github.com/mariusbancila/stduuid

A C++17 cross-platform single-header library for generating and manipulating Universally Unique Identifiers (UUIDs) or GUIDs, implementing the P0959 proposal. It provides various generators including random (version 4), name-based (version 5), system-based, and experimental time-based generators. The library includes the uuids::uuid class, support for canonical string parsing and conversion, and integrations with C++ standard associative containers via std::hash and comparison operators.

Tokens
6.4K
Snippets
30
Records
38
Agent score
74%

What's inside stduuid

  1. Overview of stduuid library

    master

    stduuid is a C++17 cross-platform single-header library for generating and managing Universally Unique Identifiers (UUID) or GUIDs. It implements the P0959 proposal.

    To avoid conflicts with the standard library, all types and utilities are located in the uuids namespace rather than std.

  2. Design decisions for UUID construction and parsing

    master

    The library provides several ways to create and parse UUIDs, following the evolution of the P0959 proposal.

    String Parsing

    • from_string(): A constexpr function template used to parse a string into a uuid. In the latest version (P0959R3), it is declared noexcept. It returns a std::optional<std::uuid>, allowing for non-throwing error handling.
    • is_valid_uuid(): A constexpr function template that checks if a string contains a valid UUID format without returning a uuid object.
    • Supported Formats: The parser supports the standard format including braces, e.g., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".

    Construction Methods

    • Default Constructor: A defaulted constructor that creates a nil UUID.
    • Array Constructors: The uuid type can be constructed from arrays.
    • Byte Conversion: A conversion constructor exists from std::span<std::byte, 16>.
    • as_bytes(): A member function that converts the uuid into a view of its underlying 16 bytes.
  3. Use custom ordering functors for UUID containers

    master

    To use std::uuid as a key in associative containers like std::set or std::map, you can use provided non-member ordering functors. This avoids the debate over whether the uuid class should implement a default < operator and allows you to choose between lexicographical compatibility and performance.

    • uuid_lexicographical_order: Performs a lexicographic comparison, providing compatibility with other systems.
    • uuid_fast_order: Performs a memberwise comparison for higher efficiency.

    You can also provide your own custom implementation if required.

    // Using fast order for efficiency
    std::map<std::uuid, Value, std::uuid_fast_order> map;
    
    // Using lexicographical order for compatibility
    template<typename Value, typename Allocator = std::allocator<Value>>
    using uuid_map = std::map<std::uuid, Value, std::uuid_lexicographical_order, Allocator>;
  4. Understand UUID format and field layout (RFC 4122)

    master

    A UUID is a 128-bit (16 octet) object. The layout is determined by the variant field (the most significant bits of octet 8). The standard RFC 4122 variant uses the bit pattern 10x.

    Field Layout (Network Byte Order):

    • time_low (32 bits): Octets 0-3
    • time_mid (16 bits): Octets 4-5
    • time_hi_and_version (16 bits): Octets 6-7 (includes version in the 4 MSBs)
    • clock_seq_hi_and_reserved (8 bits): Octet 8 (includes variant in MSBs)
    • clock_seq_low (8 bits): Octet 9
    • node (48 bits): Octets 10-15

    Common Versions:

    • 1: Time-based
    • 2: DCE Security
    • 3: Name-based (MD5)
    • 4: Randomly generated
    • 5: Name-based (SHA-1)
  5. Core types in the uuids namespace

    master

    The library provides the following fundamental types:

    • uuids::uuid: The primary class representing a UUID. It can be default constructed (creating a nil UUID), constructed from a range of iterators, or from a span.
    • uuids::uuid_variant: A strongly typed enum representing the UUID variant.
    • uuids::uuid_version: A strongly typed enum representing the UUID version.
  6. Dependencies and C++ Standard requirements

    master

    C++20 and std::span

    If using C++20, the library will automatically use std::span if supported by your compiler (checked via __cpp_lib_span).

    C++17 and GSL

    If using C++17, std::span is not available. The library defaults to using the Microsoft Guidelines Support Library (GSL) implementation of span. To use this, ensure the GSL library is available and its include directory is in your project's include path.

  7. Build the library on Windows using CMake

    master

    To build the library on Windows, use CMake to generate Visual Studio project files. You must create a build directory and run the CMake command from within that directory.

    Depending on your target architecture, use the appropriate generator:

    • x86: "Visual Studio 15 2017"
    • x64: "Visual Studio 15 2017 Win64"
    • ARM: "Visual Studio 15 2017 ARM"

    Note: The examples provided assume Visual Studio 2017 is installed.

    mkdir build
    cd build
    cmake -G "Visual Studio 15 2017" ..
  8. Build and run the test suite

    master

    To build and execute the tests for stduuid, follow these steps:

    1. Clone or download the repository.
    2. Create a build directory in the root directory.
    3. Run cmake .. from within the build directory (ensure CMake is installed).
    4. Build the project using your preferred build system.
    5. Run the resulting executable.
    mkdir build
    cd build
    cmake ..
    # Follow your build system's instructions to compile and run
  9. Configure UUID generators via CMake

    master

    You can enable specific UUID generators during the CMake configuration step using the following flags:

    • OS-specific UUID generator: Set UUID_SYSTEM_GENERATOR to ON.
    • Experimental time-based UUID generator: Set UUID_TIME_GENERATOR to ON.
    # Enable OS-specific UUID generator
    cmake -G "Visual Studio 17" -A x64 -DUUID_SYSTEM_GENERATOR=ON ..
    
    # Enable experimental time-based UUID generator
    cmake -G "Visual Studio 17" -A x64 -DUUID_TIME_GENERATOR=ON ..
  10. Create a UUID from raw bytes

    master

    You can construct a uuid from a sequence of 16 bytes using an array, a pointer range, or an initializer list.

    // From an array
    std::array<uuids::uuid::value_type, 16> arr{{ 0x47, 0x18, 0x38, 0x23, 0x25, 0x74, 0x4b, 0xfd, 0xb4, 0x11, 0x99, 0xed, 0x17, 0x7d, 0x3e, 0x43 }};
    uuids::uuid id(arr);
    
    // From a pointer range
    uuids::uuid::value_type raw_arr[16] = { 0x47, 0x18, 0x38, 0x23, 0x25, 0x74, 0x4b, 0xfd, 0xb4, 0x11, 0x99, 0xed, 0x17, 0x7d, 0x3e, 0x43 };
    uuids::uuid id2(std::begin(raw_arr), std::end(raw_arr));