technical specifications

This commit is contained in:
mariusbancila 2017-12-18 17:31:25 +02:00 committed by GitHub
parent 5fc6da8db3
commit d7f0988f8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

229
paper.md
View File

@ -91,8 +91,237 @@ assert(id.string() == "47183823-2574-4bfd-b411-99ed177d3e43");
assert(id.wstring() == L"47183823-2574-4bfd-b411-99ed177d3e43");
```
### Iterators
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<uint8_t, 16> arr{
0x47, 0x18, 0x38, 0x23,
0x25, 0x74,
0x4b, 0xfd,
0xb4, 0x11,
0x99, 0xed, 0x17, 0x7d, 0x3e, 0x43};
uuid id;
assert(id.nil());
std::copy(std::cbegin(arr), std::cend(arr), std::begin(id));
assert(!id.nil());
assert(id.string() == "47183823-2574-4bfd-b411-99ed177d3e43");
size_t i = 0;
for (auto const & b : id)
assert(arr[i++] == b);
```
### `variant` and `version`
Member functions `variant()` and `version()` allows to check the variant type of the uuid and respetively the version type. These are defined by two strongly typed enums called `uuid_variant` and `uuid_version`.
```
uuid id("47183823-2574-4bfd-b411-99ed177d3e43");
assert(id.version() == uuids::uuid_version::random_number_based);
assert(id.variant() == uuids::uuid_variant::rfc);
```
### Swapping
Both member and non-member swap functions including a `std::swap<>` specialization that enable the swapping of `uuid` values.
```
uuid empty;
uuid id("47183823-2574-4bfd-b411-99ed177d3e43");
assert(empty.nil());
assert(!id.nil());
std::swap(empty, id);
assert(!empty.nil());
assert(id.nil());
empty.swap(id);
assert(empty.nil());
assert(!id.nil());
```
### `operator==` and `operator!=`
Non-member operators == and != are provided in order to test the equality/inequality of two `uuid` values.
```
uuid empty;
uuid id("47183823-2574-4bfd-b411-99ed177d3e43");
assert(empty == empty);
assert(id == id);
assert(empty != id);
```
### `operator<`
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<uuids::uuid> ids{
uuid{},
uuids::uuid("47183823-2574-4bfd-b411-99ed177d3e43"),
uuids::make_uuid()
};
assert(ids.size() == 3);
assert(ids.find(uuid{}) != ids.end());
```
### Hashing
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<uuids::uuid> ids{
uuid{},
uuids::uuid("47183823-2574-4bfd-b411-99ed177d3e43"),
uuids::make_uuid()
};
assert(ids.size() == 3);
assert(ids.find(uuid{}) != ids.end());
```
### Generating new uuids
Non-member `make_uuid` function creates a new uuid by relying on the operating system APIs for this purpose. In practice, all the major operating system APIs (`CoCreateGuid` on Windows, `uuid_generate` on Linux, `CFUUIDCreate` on Max OS) produce version 4 UUIDs of the RFC variant.
```
auto id = make_uuid();
assert(!id.nil());
assert(id.version() == uuids::uuid_version::random_number_based);
assert(id.variant() == uuids::uuid_variant::rfc);
```
## IV. Technical Specifications
### Header
Add a new header called `<uuid>`.
### `uuid_variant` enum
```
namespace std::uuid {
enum class uuid_variant
{
ncs,
rfc,
microsoft,
future
};
}
```
### `uuid_version` enum
```
namespace std::uuid {
enum class uuid_version
{
none = 0,
time_based = 1,
dce_security = 2,
name_based_md5 = 3,
random_number_based = 4,
name_based_sha1 = 5
};
}
```
### `uuid` class
```
namespace std::uuid {
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:
constexpr explicit uuid();
constexpr explicit uuid(std::array<uint8_t, 16> const & bytes);
explicit uuid(uint8_t const * const bytes);
explicit uuid(std::string const & str);
explicit uuid(std::wstring const & str);
constexpr uuid_variant variant() const noexcept;
constexpr uuid_version version() const noexcept;
constexpr std::size_t size() const noexcept;
constexpr bool nil() const noexcept;
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 CharT,
class Traits = std::char_traits<CharT>,
class Alloc = std::allocator<CharT>>
std::basic_string<CharT, Traits, Alloc> 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 <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
};
}
```
### non-member functions
```
namespace std::uuid {
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;
template <class Elem, class Traits>
std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
uuid make_uuid();
}
```
### Specialization
```
namespace std
{
template <>
void swap(uuids::uuid & lhs, uuids::uuid & rhs);
template <>
struct hash<uuids::uuid>
{
typedef uuids::uuid argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const &uuid) const;
};
}
```
## V. Limitations
## VI. References