Skip to content

Commit 85ae4ec

Browse files
authored
Implement a basic UUID v4 generator (#1799)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 9e6c60d commit 85ae4ec

File tree

11 files changed

+121
-1
lines changed

11 files changed

+121
-1
lines changed

.github/workflows/website-build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
- run: >
1717
cmake -S . -B ./build
1818
-DCMAKE_BUILD_TYPE:STRING=Release
19+
-DSOURCEMETA_CORE_UUID:BOOL=OFF
1920
-DSOURCEMETA_CORE_GZIP:BOOL=OFF
2021
-DSOURCEMETA_CORE_REGEX:BOOL=OFF
2122
-DSOURCEMETA_CORE_URI:BOOL=OFF

.github/workflows/website-deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
- run: >
2727
cmake -S . -B ./build
2828
-DCMAKE_BUILD_TYPE:STRING=Release
29+
-DSOURCEMETA_CORE_UUID:BOOL=OFF
2930
-DSOURCEMETA_CORE_GZIP:BOOL=OFF
3031
-DSOURCEMETA_CORE_REGEX:BOOL=OFF
3132
-DSOURCEMETA_CORE_URI:BOOL=OFF

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ project(core VERSION 0.0.0 LANGUAGES C CXX DESCRIPTION "Sourcemeta Core")
33
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
44

55
# Options
6+
option(SOURCEMETA_CORE_UUID "Build the Sourcemeta Core UUID library" ON)
67
option(SOURCEMETA_CORE_GZIP "Build the Sourcemeta Core GZIP library" ON)
78
option(SOURCEMETA_CORE_REGEX "Build the Sourcemeta Core Regex library" ON)
89
option(SOURCEMETA_CORE_URI "Build the Sourcemeta Core URI library" ON)
@@ -47,6 +48,10 @@ if(SOURCEMETA_CORE_INSTALL)
4748
COMPONENT sourcemeta_${PROJECT_NAME}_dev)
4849
endif()
4950

51+
if(SOURCEMETA_CORE_UUID)
52+
add_subdirectory(src/core/uuid)
53+
endif()
54+
5055
if(SOURCEMETA_CORE_GZIP OR SOURCEMETA_CORE_CONTRIB_ZLIB)
5156
find_package(ZLIB REQUIRED)
5257
add_subdirectory(src/core/gzip)
@@ -119,6 +124,10 @@ endif()
119124
if(SOURCEMETA_CORE_TESTS)
120125
enable_testing()
121126

127+
if(SOURCEMETA_CORE_UUID)
128+
add_subdirectory(test/uuid)
129+
endif()
130+
122131
if(SOURCEMETA_CORE_GZIP)
123132
add_subdirectory(test/gzip)
124133
endif()

config.cmake.in

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
list(APPEND SOURCEMETA_CORE_COMPONENTS ${Core_FIND_COMPONENTS})
55
list(APPEND SOURCEMETA_CORE_COMPONENTS ${core_FIND_COMPONENTS})
66
if(NOT SOURCEMETA_CORE_COMPONENTS)
7+
list(APPEND SOURCEMETA_CORE_COMPONENTS uuid)
78
list(APPEND SOURCEMETA_CORE_COMPONENTS gzip)
89
list(APPEND SOURCEMETA_CORE_COMPONENTS regex)
910
list(APPEND SOURCEMETA_CORE_COMPONENTS uri)
@@ -18,7 +19,9 @@ endif()
1819
include(CMakeFindDependencyMacro)
1920

2021
foreach(component ${SOURCEMETA_CORE_COMPONENTS})
21-
if(component STREQUAL "gzip")
22+
if(component STREQUAL "uuid")
23+
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uuid.cmake")
24+
elseif(component STREQUAL "gzip")
2225
find_dependency(ZLIB CONFIG)
2326
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_gzip.cmake")
2427
elseif(component STREQUAL "regex")

src/core/uuid/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME uuid SOURCES uuid.cc)
2+
3+
if(SOURCEMETA_CORE_INSTALL)
4+
sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME uuid)
5+
endif()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef SOURCEMETA_CORE_UUID_H_
2+
#define SOURCEMETA_CORE_UUID_H_
3+
4+
#ifndef SOURCEMETA_CORE_UUID_EXPORT
5+
#include <sourcemeta/core/uuid_export.h>
6+
#endif
7+
8+
#include <string> // std::string
9+
10+
/// @defgroup uuid UUID
11+
/// @brief An growing implementation of RFC 9562 UUID.
12+
///
13+
/// This functionality is included as follows:
14+
///
15+
/// ```cpp
16+
/// #include <sourcemeta/core/uuid.h>
17+
/// ```
18+
19+
namespace sourcemeta::core {
20+
21+
/// @ingroup uuid
22+
/// Generate a random UUID v4 string. For example:
23+
///
24+
/// ```cpp
25+
/// #include <sourcemeta/core/uuid.h>
26+
/// #include <iostream>
27+
///
28+
/// std::cout << sourcemeta::core::uuidv4() << "\n";
29+
/// ```
30+
///
31+
/// See https://www.rfc-editor.org/rfc/rfc9562#name-uuid-version-4
32+
SOURCEMETA_CORE_UUID_EXPORT auto uuidv4() -> std::string;
33+
34+
} // namespace sourcemeta::core
35+
36+
#endif

src/core/uuid/uuid.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <sourcemeta/core/uuid.h>
2+
3+
#include <cstdint> // std::uint8_t
4+
#include <random> // std::random_device, std::mt19937, std::uniform_int_distribution
5+
#include <string_view> // std::string_view
6+
7+
namespace sourcemeta::core {
8+
9+
// Adapted from https://stackoverflow.com/a/58467162/1641422
10+
auto uuidv4() -> std::string {
11+
static std::random_device device;
12+
static std::mt19937 generator{device()};
13+
static constexpr std::string_view digits = "0123456789abcdef";
14+
static constexpr bool dash[] = {0, 0, 0, 0, 1, 0, 1, 0,
15+
1, 0, 1, 0, 0, 0, 0, 0};
16+
std::uniform_int_distribution<decltype(digits)::size_type> distribution(0,
17+
15);
18+
std::string result;
19+
result.reserve(36);
20+
for (std::uint8_t index = 0; index < 16; index++) {
21+
if (dash[index]) {
22+
result += "-";
23+
}
24+
25+
result += digits[distribution(generator)];
26+
result += digits[distribution(generator)];
27+
}
28+
29+
return result;
30+
}
31+
32+
} // namespace sourcemeta::core

test/packaging/find_package/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
55
set(CMAKE_CXX_EXTENSIONS OFF)
66
find_package(Core REQUIRED)
77
add_executable(core_hello hello.cc)
8+
target_link_libraries(core_hello PRIVATE sourcemeta::core::uuid)
89
target_link_libraries(core_hello PRIVATE sourcemeta::core::gzip)
910
target_link_libraries(core_hello PRIVATE sourcemeta::core::uri)
1011
target_link_libraries(core_hello PRIVATE sourcemeta::core::json)

test/packaging/find_package/hello.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <sourcemeta/core/jsonpointer.h>
66
#include <sourcemeta/core/jsonschema.h>
77
#include <sourcemeta/core/uri.h>
8+
#include <sourcemeta/core/uuid.h>
89
#include <sourcemeta/core/yaml.h>
910

1011
#include <cstdlib> // EXIT_SUCCESS

test/uuid/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
sourcemeta_googletest(NAMESPACE sourcemeta PROJECT core NAME uuid
2+
SOURCES uuid_v4_test.cc)
3+
4+
target_link_libraries(sourcemeta_core_uuid_unit
5+
PRIVATE sourcemeta::core::uuid)

0 commit comments

Comments
 (0)