From dced1276db18b2fb1a001b2eeaf0f4424690891e Mon Sep 17 00:00:00 2001 From: mariusbancila Date: Tue, 19 Dec 2017 12:22:28 +0200 Subject: [PATCH] std:byte, constructors --- paper.md | 167 +++++++++++++++++++++++++++---------------------------- 1 file changed, 83 insertions(+), 84 deletions(-) diff --git a/paper.md b/paper.md index 7824468..e86c4be 100644 --- a/paper.md +++ b/paper.md @@ -6,7 +6,7 @@ Universally unique identifiers (*uuid*), also known as Globally Unique Identifie UUIDs are 128-bit numbers that are for most practical purposes unique, without depending on a central registration authority for ensuring their uniqueness. Although the probability of UUID duplication exists, it is negligible. According to Wikipedia, "*for there to be a one in a billion chance of duplication, 103 trillion version 4 UUIDs must be generated.*" UUID is an Internet Engineering Task Force standard described by RFC 4122. -The library proposed on this paper is a lite one: it enables developers to generate UUIDs based on the operation system facilities, serialize and deserialize UUIDs to and frmo strings, validate UUIDs and other common ensuing operations. +The library proposed on this paper is a light one: it enables developers to generate UUIDs based on the operation system facilities, serialize and deserialize UUIDs to and from strings, validate UUIDs and other common ensuing operations. ## II. Impact On the Standard @@ -14,7 +14,7 @@ This proposal is a pure library extension. It does not require changes to any st ## III. Design Decisions -The proposed library, that should be available in a new header called `` in the namespace `std::uuids`, provides: +The proposed library, that should be available in a new header called `` in the namespace `std`, provides: * a class called `uuid` that represents a universally unique identifier * strongly type enums `uuid_variant` and `uuid_version` to represent the possible variant and version types of a UUID * a `make_uuid` function to generate a new UUID @@ -31,9 +31,9 @@ uuid empty; auto empty = uuid{}; ``` -### String constructors +### string_view constructors -Conversion constructors from `std::string` and `std::wstring` allow to create `uuid` instances from a string. +Conversion constructors from `std::string_view` and `std::wstring_view` allow to create `uuid` instances from various strings. The input argument must have the form `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` where `x` is a hexadecimal digit. Should the argument be of a different format a nil UUID would be created. @@ -44,28 +44,27 @@ std::wstring str=L"47183823-2574-4bfd-b411-99ed177d3e43"; uuid id2(str); ``` -### Array constructors +### Iterators constructors -The conversion constructor from `std::array` enables the construction of a `uuid` from an array of bytes. +The conversion constructor that takes two forward iterators constructs an `uuid` with the content of the range \[first, last). It requires the range to have exactly 16 elements, otherwise the result is a nil `uuid`. This constructor follows the conventions of other containers in the standard library. ``` -std::array arr{{ - 0x47, 0x18, 0x38, 0x23, - 0x25, 0x74, - 0x4b, 0xfd, - 0xb4, 0x11, - 0x99, 0xed, 0x17, 0x7d, 0x3e, 0x43}}; +std::array arr{{ + std::byte{ 0x47 }, std::byte{ 0x18 }, std::byte{ 0x38 }, std::byte{ 0x23 }, + std::byte{ 0x25 }, std::byte{ 0x74 }, + std::byte{ 0x4b }, std::byte{ 0xfd }, + std::byte{ 0xb4 }, std::byte{ 0x11 }, + std::byte{ 0x99 }, std::byte{ 0xed }, std::byte{ 0x17 }, std::byte{ 0x7d }, std::byte{ 0x3e }, std::byte{ 0x43 } }}; uuid id(arr); ``` -A conversion constructor from `uint8_t*` also exists to construct `uuid`s from C-like arrays. This requires the input buffer to have at least 16 bytes. The behavior when the buffer does not have 16 bytes is undefined. ``` -uint8_t arr[16] = { - 0x47, 0x18, 0x38, 0x23, - 0x25, 0x74, - 0x4b, 0xfd, - 0xb4, 0x11, - 0x99, 0xed, 0x17, 0x7d, 0x3e, 0x43}; +std::byte arr[16] = { + std::byte{ 0x47 }, std::byte{ 0x18 }, std::byte{ 0x38 }, std::byte{ 0x23 }, + std::byte{ 0x25 }, std::byte{ 0x74 }, + std::byte{ 0x4b }, std::byte{ 0xfd }, + std::byte{ 0xb4 }, std::byte{ 0x11 }, + std::byte{ 0x99 }, std::byte{ 0xed }, std::byte{ 0x17 }, std::byte{ 0x7d }, std::byte{ 0x3e }, std::byte{ 0x43 }}; uuid id(arr); ``` @@ -96,12 +95,12 @@ assert(id.wstring() == L"47183823-2574-4bfd-b411-99ed177d3e43"); Constant and mutable iterators allow direct access to the underlaying `uuid` data. This enables both direct reading and writing of the `uuid` bits. ``` -std::array arr{{ - 0x47, 0x18, 0x38, 0x23, - 0x25, 0x74, - 0x4b, 0xfd, - 0xb4, 0x11, - 0x99, 0xed, 0x17, 0x7d, 0x3e, 0x43}}; +std::array arr{{ + std::byte{ 0x47 }, std::byte{ 0x18 }, std::byte{ 0x38 }, std::byte{ 0x23 }, + std::byte{ 0x25 }, std::byte{ 0x74 }, + std::byte{ 0x4b }, std::byte{ 0xfd }, + std::byte{ 0xb4 }, std::byte{ 0x11 }, + std::byte{ 0x99 }, std::byte{ 0xed }, std::byte{ 0x17 }, std::byte{ 0x7d }, std::byte{ 0x3e }, std::byte{ 0x43 } }}; uuid id; assert(id.nil()); @@ -121,8 +120,8 @@ Member functions `variant()` and `version()` allows to check the variant type of ``` uuid id("47183823-2574-4bfd-b411-99ed177d3e43"); -assert(id.version() == uuids::uuid_version::random_number_based); -assert(id.variant() == uuids::uuid_variant::rfc); +assert(id.version() == uuid_version::random_number_based); +assert(id.variant() == uuid_variant::rfc); ``` ### Swapping @@ -165,10 +164,10 @@ assert(empty != id); Although it does not make sense to check whether a uuid is less or less or equal then another uuid, the overloading of this operator for `uuid` is necessary in order to be able to store `uuid` values in some containers such as `std::set` that by default use the operator to compare keys. ``` -std::set ids{ +std::set ids{ uuid{}, - uuids::uuid("47183823-2574-4bfd-b411-99ed177d3e43"), - uuids::make_uuid() + uuid("47183823-2574-4bfd-b411-99ed177d3e43"), + make_uuid() }; assert(ids.size() == 3); @@ -180,10 +179,10 @@ assert(ids.find(uuid{}) != ids.end()); A `std::hash<>` specialization for `uuid` is provided in order to enable the use of `uuid`s in associative unordered containers such as `std::unordered_set`. ``` -std::unordered_set ids{ +std::unordered_set ids{ uuid{}, - uuids::uuid("47183823-2574-4bfd-b411-99ed177d3e43"), - uuids::make_uuid() + uuid("47183823-2574-4bfd-b411-99ed177d3e43"), + make_uuid() }; assert(ids.size() == 3); @@ -197,8 +196,8 @@ Non-member `make_uuid` function creates a new uuid by relying on the operating s ``` auto id = make_uuid(); assert(!id.nil()); -assert(id.version() == uuids::uuid_version::random_number_based); -assert(id.variant() == uuids::uuid_variant::rfc); +assert(id.version() == uuid_version::random_number_based); +assert(id.variant() == uuid_variant::rfc); ``` ## IV. Technical Specifications @@ -209,7 +208,7 @@ Add a new header called ``. ### `uuid_variant` enum ``` -namespace std::uuid { +namespace std { enum class uuid_variant { ncs, @@ -223,7 +222,7 @@ namespace std::uuid { ### `uuid_version` enum ``` -namespace std::uuid { +namespace std { enum class uuid_version { none = 0, @@ -239,59 +238,60 @@ namespace std::uuid { ### `uuid` class ``` -namespace std::uuid { +namespace std { struct uuid - { - public: - typedef uint8_t value_type; - typedef uint8_t& reference; - typedef uint8_t const& const_reference; - typedef uint8_t* iterator; - typedef uint8_t const* const_iterator; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; +{ +public: + typedef std::byte value_type; + typedef std::byte& reference; + typedef std::byte const& const_reference; + typedef std::byte* iterator; + typedef std::byte const* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; - public: - constexpr explicit uuid(); - constexpr explicit uuid(std::array const & bytes); - explicit uuid(uint8_t const * const bytes); - explicit uuid(std::string const & str); - explicit uuid(std::wstring const & str); +public: + constexpr uuid() noexcept; - constexpr uuid_variant variant() const noexcept; - constexpr uuid_version version() const noexcept; - constexpr std::size_t size() const noexcept; - constexpr bool nil() const noexcept; + template + explicit uuid(ForwardIterator first, ForwardIterator last); - void swap(uuid & other) noexcept; - friend void swap(uuid& lhs, uuid& rhs) noexcept; - - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + explicit uuid(std::string_view str); + explicit uuid(std::wstring_view str); - template, - class Alloc = std::allocator> - std::basic_string string(Alloc const & a = Alloc()) const; - std::string string() const; - std::wstring wstring() const; + constexpr uuid_variant variant() const noexcept; + constexpr uuid_version version() const noexcept; + constexpr std::size_t size() const noexcept; + constexpr bool nil() const noexcept; - private: - friend bool operator==(uuid const & lhs, uuid const & rhs) noexcept; - friend bool operator<(uuid const & lhs, uuid const & rhs) noexcept; - - template - friend std::basic_ostream & operator<<(std::basic_ostream &s, uuid const & id); - }; -} + void swap(uuid & other) noexcept; + friend void swap(uuid& lhs, uuid& rhs) noexcept; + + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + template, + class Alloc = std::allocator> + std::basic_string string(Alloc const & a = Alloc()) const; + std::string string() const; + std::wstring wstring() const; + +private: + friend bool operator==(uuid const & lhs, uuid const & rhs) noexcept; + friend bool operator<(uuid const & lhs, uuid const & rhs) noexcept; + + template + friend std::basic_ostream & operator<<(std::basic_ostream &s, uuid const & id); +}; ``` ### non-member functions ``` -namespace std::uuid { +namespace std { inline bool operator== (uuid const& lhs, uuid const& rhs) noexcept; inline bool operator!= (uuid const& lhs, uuid const& rhs) noexcept; inline bool operator< (uuid const& lhs, uuid const& rhs) noexcept; @@ -306,15 +306,14 @@ namespace std::uuid { ### Specialization ``` -namespace std -{ +namespace std { template <> - void swap(uuids::uuid & lhs, uuids::uuid & rhs); + void swap(uuid & lhs, uuid & rhs); template <> - struct hash + struct hash { - typedef uuids::uuid argument_type; + typedef uuid argument_type; typedef std::size_t result_type; result_type operator()(argument_type const &uuid) const;