Compare commits

...

18 Commits

Author SHA1 Message Date
Marius Bancila
3afe7193fa
Merge pull request #67 from chaorunrun/compile-for-c++17
Fix errors on compilation with c++17
2022-06-16 12:21:45 +03:00
Adam Jiang
e5da05d8de
Use <gsl/span> 2022-05-25 09:47:48 +08:00
Adam Jiang
30b95f9c8f
Merge branch 'master' into compile-for-c++17 2022-05-19 16:30:40 +08:00
Marius Bancila
3dca9d816c
Merge pull request #64 from OlivierLDff/optional-install
Optional install
2022-05-19 09:32:09 +03:00
Marius Bancila
d1f0f7f0ba
Merge pull request #69 from sid-dahiya/sid-dahiya/FixMsvcHiddenFriendError
Fix hidden friend issue for MSVC
2022-05-19 09:05:40 +03:00
Marius Bancila
cd9ca5e7d7
build with VS 2019 & 2022 2022-05-19 09:04:50 +03:00
Sid Dahiya
dfe3d39c10
Fix hidden friend issue for MSVC
This change is adding the `/Zc:hiddenFriend` option to address strict validation in MSVC 19.32.31328.0
2022-05-18 15:24:41 -07:00
Adam Jiang
979ba59e41 Fix errors on compilation with c++17 2022-05-18 22:17:02 +08:00
Marius Bancila
db4963048d merged 2022-05-10 09:09:42 +03:00
Olivier Le Doeuff
44160cca3f Deactivate unit test by default when stduuid is not the main CMake project 2022-05-06 17:22:56 +02:00
Olivier Le Doeuff
2ff6222e9f Make install optional (expected behavior in CMake FetchContent) 2022-05-06 17:22:11 +02:00
Marius Bancila
c1e1c144af
Merge pull request #62 from NovaSmoof/fixing-static-analysis
I believe this fixes an alignment issue.
2022-04-11 10:27:34 +03:00
Marius Bancila
9341e579f7
Merge pull request #61 from NovaSmoof/master
Added Appropriate nodiscards
2022-04-11 10:25:28 +03:00
Arthur.e
39b505ee95 I believe this fixes an alignment issue.
Casting the uint8_t array to a uint32_t pointer may cause it to become misaligned. So making it alignas a uint32 array should remove the undefined behavior.
2022-04-04 10:58:40 -07:00
Arthur.e
11a678d7fe Merge branch 'same-thing' 2022-04-04 10:00:21 -07:00
Arthur.e
02e2989771 Made all the things nodiscard
They should be.
2022-04-04 10:00:02 -07:00
Marius Bancila
1d3720fbcd whitespaces 2022-02-23 18:28:39 +02:00
Marius Bancila
cdebc5b78d pragma once replaced
added constexpr
2022-02-23 18:24:00 +02:00
5 changed files with 131 additions and 113 deletions

View File

@ -1,11 +1,18 @@
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" ON)
option(UUID_BUILD_TESTS "Build the unit tests" ${UUID_MAIN_PROJECT})
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)
@ -38,36 +45,38 @@ endif()
# Using span from std
if (NOT UUID_USING_CXX20_SPAN)
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/gsl>
$<INSTALL_INTERFACE:include/gsl>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
install(DIRECTORY gsl DESTINATION include)
endif ()
# 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})
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})
# 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")
# 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()
# Tests
if (UUID_BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif ()
endif ()

View File

@ -105,6 +105,7 @@ 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.
@ -506,21 +507,11 @@ namespace std {
constexpr std::strong_ordering operator<=>(uuid const&) const noexcept = default;
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;
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;
private:
template <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
@ -598,13 +589,8 @@ namespace std {
public:
explicit uuid_name_generator(uuid const& namespace_uuid) noexcept;
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);
template<typename StringType>
uuid operator()(StringType const & name);
};
}
```
@ -714,21 +700,11 @@ namespace std {
constexpr std::span<std::byte const, 16> as_bytes() const;
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;
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;
private:
template <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
@ -841,6 +817,12 @@ 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,12 +2,21 @@ version: '{build}'
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_GENERATOR_PLATFORM: Win32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
- 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
CMAKE_GENERATOR_PLATFORM: x64
CMAKE_CLI_FLAGS: -DUUID_SYSTEM_GENERATOR=ON -DUUID_TIME_GENERATOR=ON

View File

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