Compare commits

..

No commits in common. "master" and "v1.2.2" have entirely different histories.

5 changed files with 113 additions and 131 deletions

View File

@ -1,18 +1,11 @@
cmake_minimum_required(VERSION 3.7.0)
set(UUID_MAIN_PROJECT OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(UUID_MAIN_PROJECT ON)
endif()
project(stduuid CXX)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
option(UUID_BUILD_TESTS "Build the unit tests" ${UUID_MAIN_PROJECT})
option(UUID_BUILD_TESTS "Build the unit tests" ON)
option(UUID_SYSTEM_GENERATOR "Enable operating system uuid generator" OFF)
option(UUID_TIME_GENERATOR "Enable experimental time-based uuid generator" OFF)
option(UUID_USING_CXX20_SPAN "Using span from std instead of gsl" OFF)
option(UUID_ENABLE_INSTALL "Create an install target" ${UUID_MAIN_PROJECT})
# Library target
add_library(${PROJECT_NAME} INTERFACE)
@ -45,38 +38,36 @@ endif()
# Using span from std
if (NOT UUID_USING_CXX20_SPAN)
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/gsl>
$<INSTALL_INTERFACE:include/gsl>)
install(DIRECTORY gsl DESTINATION include)
endif ()
if(UUID_ENABLE_INSTALL)
# Install step and imported target
install(FILES include/uuid.h DESTINATION include)
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets)
install(EXPORT ${PROJECT_NAME}-targets
DESTINATION lib/cmake/${PROJECT_NAME})
# Install step and imported target
install(FILES include/uuid.h DESTINATION include)
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets)
install(EXPORT ${PROJECT_NAME}-targets
DESTINATION lib/cmake/${PROJECT_NAME})
# Config files for find_package()
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION lib/cmake/${PROJECT_NAME})
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-version.cmake"
VERSION "1.0"
COMPATIBILITY AnyNewerVersion)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-version.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLibuuid.cmake"
DESTINATION lib/cmake/${PROJECT_NAME})
export(EXPORT ${PROJECT_NAME}-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}-targets.cmake")
endif()
# Config files for find_package()
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION lib/cmake/${PROJECT_NAME})
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-version.cmake"
VERSION "1.0"
COMPATIBILITY AnyNewerVersion)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-version.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLibuuid.cmake"
DESTINATION lib/cmake/${PROJECT_NAME})
export(EXPORT ${PROJECT_NAME}-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}-targets.cmake")
# Tests
if (UUID_BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif ()
endif ()

View File

@ -105,7 +105,6 @@ P0959R2 was discussed by LEWGI in Kona with the following feedback:
Based on this feedback and further considerations, the following changes have been done in this version:
* Added detailed explanation of the algorithms for generating uuids.
* `from_string()` and non-member `swap()` declared with `noexcept`.
* `from_string()` and `is_valid_uuid()` declared with `constexpr`.
* The `uuid` type is now defined as a class.
* Added an exposition-only member to hint and the possible internal representation of the uuid data.
* Added `uuid` constructors from arrays.
@ -507,11 +506,21 @@ namespace std {
constexpr std::strong_ordering operator<=>(uuid const&) const noexcept = default;
template<typename StringType>
constexpr static bool is_valid_uuid(StringType const & str) noexcept;
template<typename StringType>
constexpr static uuid from_string(StringType const & str) noexcept;
template<class CharT = char>
static bool is_valid_uuid(CharT const * str) noexcept;
template<class CharT = char,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
static bool is_valid_uuid(std::basic_string<CharT, Traits, Allocator> const & str) noexcept;
template<class CharT = char>
static uuid from_string(CharT const * str) noexcept;
template<class CharT = char,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
static uuid from_string(std::basic_string<CharT, Traits, Allocator> const & str) noexcept;
private:
template <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
@ -589,8 +598,13 @@ namespace std {
public:
explicit uuid_name_generator(uuid const& namespace_uuid) noexcept;
template<typename StringType>
uuid operator()(StringType const & name);
template<class CharT = char>
uuid operator()(CharT const * name);
template<class CharT = char,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
uuid operator()(std::basic_string<CharT, Traits, Allocator> const & name);
};
}
```
@ -700,11 +714,21 @@ namespace std {
constexpr std::span<std::byte const, 16> as_bytes() const;
template<typename StringType>
constexpr static bool is_valid_uuid(StringType const & str) noexcept;
template<typename StringType>
constexpr static uuid from_string(StringType const & str) noexcept;
template<class CharT = char>
static bool is_valid_uuid(CharT const * str) noexcept;
template<class CharT = char,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
static bool is_valid_uuid(std::basic_string<CharT, Traits, Allocator> const & str) noexcept;
template<class CharT = char>
static uuid from_string(CharT const * str) noexcept;
template<class CharT = char,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
static uuid from_string(std::basic_string<CharT, Traits, Allocator> const & str) noexcept;
private:
template <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
@ -817,12 +841,6 @@ auto id1 = uuid::from_string<char, std::char_traits<char>>(
std::string str{ "47183823-2574-4bfd-b411-99ed177d3e43" };
auto id2 = uuid::from_string<char, std::char_traits<char>>(str); // [2]
```
However, to simplify the definition, these two overloads have been replaced with a single one:
```
template <typename StringType>
constexpr static std::optional<uuid> from_string(StringType const & str);
```
The `is_valid_uuid()` function and the `uuid_name_generator`'s call operator are now defined in the same manner.
#### Need more explanations about the choices of ordering and how the RFC works in that regard.

View File

@ -2,21 +2,12 @@ version: '{build}'
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMAKE_GENERATOR: Visual Studio 16 2019
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_GENERATOR_PLATFORM: Win32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_GENERATOR_PLATFORM: x64
CMAKE_CLI_FLAGS: -DUUID_SYSTEM_GENERATOR=ON -DUUID_TIME_GENERATOR=ON
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
CMAKE_GENERATOR: Visual Studio 17 2022
CMAKE_GENERATOR_PLATFORM: Win32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
CMAKE_GENERATOR: Visual Studio 17 2022
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_GENERATOR_PLATFORM: x64
CMAKE_CLI_FLAGS: -DUUID_SYSTEM_GENERATOR=ON -DUUID_TIME_GENERATOR=ON

View File

@ -1,5 +1,4 @@
#ifndef STDUUID_H
#define STDUUID_H
#pragma once
#include <cstring>
#include <string>
@ -16,21 +15,7 @@
#include <chrono>
#include <numeric>
#include <atomic>
#ifdef __cplusplus
# if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
# define LIBUUID_CPP20_OR_GREATER
# endif
#endif
#ifdef LIBUUID_CPP20_OR_GREATER
#include <span>
#else
#include <gsl/span>
#endif
#ifdef _WIN32
@ -77,7 +62,7 @@ namespace uuids
namespace detail
{
template <typename TChar>
[[nodiscard]] constexpr inline unsigned char hex2char(TChar const ch) noexcept
constexpr inline unsigned char hex2char(TChar const ch)
{
if (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9'))
return static_cast<unsigned char>(ch - static_cast<TChar>('0'));
@ -89,7 +74,7 @@ namespace uuids
}
template <typename TChar>
[[nodiscard]] constexpr inline bool is_hex(TChar const ch) noexcept
constexpr inline bool is_hex(TChar const ch)
{
return
(ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9')) ||
@ -98,18 +83,17 @@ namespace uuids
}
template <typename TChar>
[[nodiscard]] constexpr std::basic_string_view<TChar> to_string_view(TChar const * str) noexcept
constexpr std::basic_string_view<TChar> to_string_view(TChar const * str)
{
if (str) return str;
return {};
}
template <typename StringType>
[[nodiscard]]
constexpr std::basic_string_view<
typename StringType::value_type,
typename StringType::traits_type>
to_string_view(StringType const & str) noexcept
to_string_view(StringType const & str)
{
return str;
}
@ -122,14 +106,14 @@ namespace uuids
static constexpr unsigned int block_bytes = 64;
[[nodiscard]] inline static uint32_t left_rotate(uint32_t value, size_t const count) noexcept
inline static uint32_t left_rotate(uint32_t value, size_t const count)
{
return (value << count) ^ (value >> (32 - count));
}
sha1() { reset(); }
void reset() noexcept
void reset()
{
m_digest[0] = 0x67452301;
m_digest[1] = 0xEFCDAB89;
@ -411,7 +395,7 @@ namespace uuids
std::copy(first, last, std::begin(data));
}
[[nodiscard]] constexpr uuid_variant variant() const noexcept
constexpr uuid_variant variant() const noexcept
{
if ((data[8] & 0x80) == 0x00)
return uuid_variant::ncs;
@ -423,7 +407,7 @@ namespace uuids
return uuid_variant::reserved;
}
[[nodiscard]] constexpr uuid_version version() const noexcept
constexpr uuid_version version() const noexcept
{
if ((data[6] & 0xF0) == 0x10)
return uuid_version::time_based;
@ -439,7 +423,7 @@ namespace uuids
return uuid_version::none;
}
[[nodiscard]] constexpr bool is_nil() const noexcept
constexpr bool is_nil() const noexcept
{
for (size_t i = 0; i < data.size(); ++i) if (data[i] != 0) return false;
return true;
@ -450,13 +434,13 @@ namespace uuids
data.swap(other.data);
}
[[nodiscard]] inline span<std::byte const, 16> as_bytes() const
inline span<std::byte const, 16> as_bytes() const
{
return span<std::byte const, 16>(reinterpret_cast<std::byte const*>(data.data()), 16);
}
template <typename StringType>
[[nodiscard]] constexpr static bool is_valid_uuid(StringType const & in_str) noexcept
constexpr static bool is_valid_uuid(StringType const & in_str) noexcept
{
auto str = detail::to_string_view(in_str);
bool firstDigit = true;
@ -500,7 +484,7 @@ namespace uuids
}
template <typename StringType>
[[nodiscard]] constexpr static std::optional<uuid> from_string(StringType const & in_str) noexcept
constexpr static std::optional<uuid> from_string(StringType const & in_str) noexcept
{
auto str = detail::to_string_view(in_str);
bool firstDigit = true;
@ -533,7 +517,7 @@ namespace uuids
else
{
data[index] = static_cast<uint8_t>(data[index] | detail::hex2char(str[i]));
index++;
index++;
firstDigit = true;
}
}
@ -553,7 +537,7 @@ namespace uuids
friend bool operator<(uuid const & lhs, uuid const & rhs) noexcept;
template <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
template<class CharT, class Traits, class Allocator>
friend std::basic_string<CharT, Traits, Allocator> to_string(uuid const& id);
@ -565,17 +549,17 @@ namespace uuids
// operators and non-member functions
// --------------------------------------------------------------------------------------------------------------------------
[[nodiscard]] inline bool operator== (uuid const& lhs, uuid const& rhs) noexcept
inline bool operator== (uuid const& lhs, uuid const& rhs) noexcept
{
return lhs.data == rhs.data;
}
[[nodiscard]] inline bool operator!= (uuid const& lhs, uuid const& rhs) noexcept
inline bool operator!= (uuid const& lhs, uuid const& rhs) noexcept
{
return !(lhs == rhs);
}
[[nodiscard]] inline bool operator< (uuid const& lhs, uuid const& rhs) noexcept
inline bool operator< (uuid const& lhs, uuid const& rhs) noexcept
{
return lhs.data < rhs.data;
}
@ -583,7 +567,7 @@ namespace uuids
template <class CharT,
class Traits,
class Allocator>
[[nodiscard]] inline std::basic_string<CharT, Traits, Allocator> to_string(uuid const & id)
inline std::basic_string<CharT, Traits, Allocator> to_string(uuid const & id)
{
std::basic_string<CharT, Traits, Allocator> uustr{detail::empty_guid<CharT>};
@ -736,7 +720,7 @@ namespace uuids
#endif
template <typename UniformRandomNumberGenerator>
class basic_uuid_random_generator
class basic_uuid_random_generator
{
public:
using engine_type = UniformRandomNumberGenerator;
@ -746,9 +730,9 @@ namespace uuids
explicit basic_uuid_random_generator(engine_type* gen) :
generator(gen, [](auto) {}) {}
[[nodiscard]] uuid operator()()
uuid operator()()
{
alignas(uint32_t) uint8_t bytes[16];
uint8_t bytes[16];
for (int i = 0; i < 16; i += 4)
*reinterpret_cast<uint32_t*>(bytes + i) = distribution(*generator);
@ -778,7 +762,7 @@ namespace uuids
{}
template <typename StringType>
[[nodiscard]] uuid operator()(StringType const & name)
uuid operator()(StringType const & name)
{
reset();
process_characters(detail::to_string_view(name));
@ -810,7 +794,7 @@ namespace uuids
}
}
[[nodiscard]] uuid make_uuid()
uuid make_uuid()
{
detail::sha1::digest8_t digest;
hasher.get_digest_bytes(digest);
@ -840,7 +824,7 @@ namespace uuids
std::optional<mac_address> device_address;
[[nodiscard]] bool get_mac_address()
bool get_mac_address()
{
if (device_address.has_value())
{
@ -863,7 +847,7 @@ namespace uuids
return device_address.has_value();
}
[[nodiscard]] long long get_time_intervals()
long long get_time_intervals()
{
auto start = std::chrono::system_clock::from_time_t(time_t(-12219292800));
auto diff = std::chrono::system_clock::now() - start;
@ -871,7 +855,7 @@ namespace uuids
return ns / 100;
}
[[nodiscard]] static unsigned short get_clock_sequence()
static unsigned short get_clock_sequence()
{
static std::mt19937 clock_gen(std::random_device{}());
static std::uniform_int_distribution<unsigned short> clock_dis;
@ -880,7 +864,7 @@ namespace uuids
}
public:
[[nodiscard]] uuid operator()()
uuid operator()()
{
if (get_mac_address())
{
@ -925,29 +909,29 @@ namespace std
using argument_type = uuids::uuid;
using result_type = std::size_t;
[[nodiscard]] result_type operator()(argument_type const &uuid) const
result_type operator()(argument_type const &uuid) const
{
#ifdef UUID_HASH_STRING_BASED
std::hash<std::string> hasher;
return static_cast<result_type>(hasher(uuids::to_string(uuid)));
#else
uint64_t l =
static_cast<uint64_t>(uuid.data[0]) << 56 |
static_cast<uint64_t>(uuid.data[1]) << 48 |
static_cast<uint64_t>(uuid.data[2]) << 40 |
static_cast<uint64_t>(uuid.data[3]) << 32 |
static_cast<uint64_t>(uuid.data[4]) << 24 |
static_cast<uint64_t>(uuid.data[5]) << 16 |
static_cast<uint64_t>(uuid.data[6]) << 8 |
uint64_t l =
static_cast<uint64_t>(uuid.data[0]) << 56 |
static_cast<uint64_t>(uuid.data[1]) << 48 |
static_cast<uint64_t>(uuid.data[2]) << 40 |
static_cast<uint64_t>(uuid.data[3]) << 32 |
static_cast<uint64_t>(uuid.data[4]) << 24 |
static_cast<uint64_t>(uuid.data[5]) << 16 |
static_cast<uint64_t>(uuid.data[6]) << 8 |
static_cast<uint64_t>(uuid.data[7]);
uint64_t h =
static_cast<uint64_t>(uuid.data[8]) << 56 |
static_cast<uint64_t>(uuid.data[9]) << 48 |
static_cast<uint64_t>(uuid.data[10]) << 40 |
static_cast<uint64_t>(uuid.data[11]) << 32 |
static_cast<uint64_t>(uuid.data[12]) << 24 |
static_cast<uint64_t>(uuid.data[13]) << 16 |
static_cast<uint64_t>(uuid.data[14]) << 8 |
uint64_t h =
static_cast<uint64_t>(uuid.data[8]) << 56 |
static_cast<uint64_t>(uuid.data[9]) << 48 |
static_cast<uint64_t>(uuid.data[10]) << 40 |
static_cast<uint64_t>(uuid.data[11]) << 32 |
static_cast<uint64_t>(uuid.data[12]) << 24 |
static_cast<uint64_t>(uuid.data[13]) << 16 |
static_cast<uint64_t>(uuid.data[14]) << 8 |
static_cast<uint64_t>(uuid.data[15]);
if constexpr (sizeof(result_type) > 4)
@ -963,5 +947,3 @@ namespace std
}
};
}
#endif /* STDUUID_H */

View File

@ -8,7 +8,7 @@ else ()
set_target_properties(test_${PROJECT_NAME} PROPERTIES CXX_STANDARD 17)
endif ()
if (WIN32)
target_compile_options(test_${PROJECT_NAME} PRIVATE /EHc /Zc:hiddenFriend)
target_compile_options(test_${PROJECT_NAME} PRIVATE /EHc)
target_compile_definitions(test_${PROJECT_NAME} PRIVATE _SCL_SECURE_NO_WARNINGS)
elseif (APPLE)
target_compile_options(test_${PROJECT_NAME} PRIVATE -fexceptions -g -Wall)
@ -28,4 +28,4 @@ set_tests_properties("test_${PROJECT_NAME}"
FAIL_REGULAR_EXPRESSION "Failed \\d+ test cases")
set_tests_properties("test_${PROJECT_NAME}"
PROPERTIES
TIMEOUT 120)
TIMEOUT 120)