2
0
mirror of https://github.com/boostorg/uuid.git synced 2026-01-19 04:42:16 +00:00

Update documentation

This commit is contained in:
Peter Dimov
2024-05-03 22:11:30 +03:00
parent c915af978a
commit b20a0ba4d2
7 changed files with 336 additions and 2 deletions

View File

@@ -16,7 +16,7 @@ uuid url() noexcept;
uuid oid() noexcept;
uuid x500dn() noexcept;
}}} //namespace boost::uuids::ns
}}} // namespace boost::uuids::ns
----
=== Namespaces

View File

@@ -3,6 +3,7 @@
include::uuid_all.adoc[]
include::uuid.adoc[]
include::uuid_io.adoc[]
include::uuid_generators.adoc[]
include::nil_generator.adoc[]
include::string_generator.adoc[]
@@ -12,4 +13,8 @@ include::name_generator_md5.adoc[]
include::name_generator.adoc[]
include::basic_random_generator.adoc[]
include::random_generator.adoc[]
include::uuid_io.adoc[]
include::uuid_clock.adoc[]
include::time_generator_v1.adoc[]
include::time_generator_v6.adoc[]
include::time_generator_v7.adoc[]
include::time_generator.adoc[]

View File

@@ -0,0 +1,15 @@
[#time_generator]
== <boost/uuid/time_generator.hpp>
:idprefix: time_generator_
=== Synopsis
[source,c++]
----
#include <boost/uuid/time_generator_v1.hpp>
#include <boost/uuid/time_generator_v6.hpp>
#include <boost/uuid/time_generator_v7.hpp>
----
This convenience header makes the three time-based generators `time_generator_v1`, `time_generator_v6`, and `time_generator_v7`, available.

View File

@@ -0,0 +1,96 @@
[#time_generator_v1]
== <boost/uuid/{zwsp}time_generator_v1.hpp>
:idprefix: time_generator_v1_
=== Synopsis
[source,c++]
----
namespace boost {
namespace uuids {
class time_generator_v1
{
public:
struct state_type
{
std::uint64_t timestamp;
std::uint16_t clock_seq;
};
private: // exposition only
uuid::node_type node_ = {};
std::atomic<state_type>* ps_ = nullptr;
state_type state_ = {};
public:
using result_type = uuid;
time_generator_v1();
time_generator_v1( uuid::node_type const& node, state_type const& state ) noexcept;
time_generator_v1( uuid::node_type const& node, std::atomic<state_type>& state ) noexcept;
result_type operator()() noexcept;
};
}} // namespace boost::uuids
----
The class `time_generator_v1` generates time-based version 1 UUIDs.
It supports three modes of operation.
The default and recommended one is by using its default constructor.
This instructs the generator to use a pseudorandom node identifier and initial clock sequence.
If more control over the node identifier (or the clock sequence) is desired,
for example,
if the generated UUIDs must use a specific node identifier that persists for the lifetime of the program or even across different program runs,
a constructor that takes a node identifier and a `state_type` is provided.
(The `timestamp` field of the provided `state_type` should generally be zero.)
Finally, if the program has several `time_generator_v1` instances (for example, one per thread) that need to use the same node identifier,
the third constructor takes a node identifier and a reference to `std::atomic<state_type>`.
The atomic state is used by the generators to ensure that no duplicate UUIDs are produced.
=== Constructors
```
time_generator_v1();
```
Effects: :: Using entropy from `std::random_device`, generates a pseudorandom 48 bit node identifier in `node_` and a pseudorandom 14 bit clock sequence in `state_.clock_seq`. Initalizes `state_.timestamp` to zero.
Remarks: :: The multicast bit of `node_` is set to denote a local node identifier, as recommended in https://www.rfc-editor.org/rfc/rfc4122.html#section-4.5[RFC 4122 Section 4.5].
```
time_generator_v1( uuid::node_type const& node, state_type const& state ) noexcept;
```
Effects: :: Initializes `node_` to `node` and `state_` to `state`.
```
time_generator_v1( uuid::node_type const& node, std::atomic<state_type>& state ) noexcept;
```
Effects: :: Initializes `node_` to `node` and `ps_` to `&state`.
=== operator()
```
result_type operator()() noexcept;
```
Effects: ::
+
Using the state in `state_`, if `ps_` is `nullptr`, or the state in `*ps_`, if `ps_` is not `nullptr`,
atomically computes and sets a new state by retrieving the system time as if by `uuid_clock::now()`,
converting it to a timestamp as if by `uuid_clock::to_timestamp`,
storing the result in `state.timestamp`,
and incrementing `state.clock_seq` modulo 0x4000 if the new timestamp is lower than or equal to the previous timestamp.
+
Creates a version 1 UUID using the node identifier from `node_` and the new timestamp and clock sequence and returns it.

View File

@@ -0,0 +1,46 @@
[#time_generator_v6]
== <boost/uuid/{zwsp}time_generator_v6.hpp>
:idprefix: time_generator_v6_
=== Synopsis
[source,c++]
----
namespace boost {
namespace uuids {
class time_generator_v6
{
public:
struct state_type
{
std::uint64_t timestamp;
std::uint16_t clock_seq;
};
private: // exposition only
uuid::node_type node_ = {};
std::atomic<state_type>* ps_ = nullptr;
state_type state_ = {};
public:
using result_type = uuid;
time_generator_v6();
time_generator_v6( uuid::node_type const& node, state_type const& state ) noexcept;
time_generator_v6( uuid::node_type const& node, std::atomic<state_type>& state ) noexcept;
result_type operator()() noexcept;
};
}} // namespace boost::uuids
----
The class `time_generator_v6` generates time-based version 6 UUIDs, as described in https://datatracker.ietf.org/doc/draft-ietf-uuidrev-rfc4122bis/[rfc4122bis] section 5.6.
It operates in the exact same manner as `time_generator_v1`, with the only difference being that it produces version 6 UUIDs rather than version 1 ones.

View File

@@ -0,0 +1,62 @@
[#time_generator_v7]
== <boost/uuid/{zwsp}time_generator_v7.hpp>
:idprefix: time_generator_v7_
=== Synopsis
[source,c++]
[subs=+quotes]
----
namespace boost {
namespace uuids {
class time_generator_v7
{
private:
// exposition only
_unspecified-csprng-type_ rng_;
public:
using result_type = uuid;
time_generator_v7();
result_type operator()() noexcept;
};
}} // namespace boost::uuids
----
The class `time_generator_v7` generates time-based version 7 UUIDs, as described in https://datatracker.ietf.org/doc/draft-ietf-uuidrev-rfc4122bis/[rfc4122bis] section 5.7.
=== Constructor
```
time_generator_v7();
```
Effects: :: Initializes the internal cryptographically strong pseudorandom number generator (CSPRNG) `rng_` using entropy from `std::random_device`.
=== operator()
```
result_type operator()() noexcept;
```
Effects: ::
+
. Obtains a new timestamp as if by getting the system time from `std::chrono::system_clock::now()` and converting it to a number of microseconds from the Unix epoch.
. Creates a new version 7 UUID and initializes its `unix_ts_ms` field with the number of milliseconds in the timestamp.
. Initializes the `rand_a` field with the residual number of microseconds from the timestamp.
. Initializes the 6 bits of the `rand_b` field following the variant to a conflict resolution counter, such that if more than one UUID is generated using the same timestamp, monotonicity is still ensured.
. Initializes the rest of the `rand_b` field to random values obtained from the internal CSPRNG `rng_`.
. Returns the UUID.
Remarks: :: `operator()` generates a monotonically increasing sequence of UUIDs, if the following requirements are met:
+
* The system clock never goes backwards;
* The system clock has at least millisecond resolution;
* No more than 64 UUIDs are generated per microsecond (no more than one every 16 nanoseconds.)

110
doc/uuid/uuid_clock.adoc Normal file
View File

@@ -0,0 +1,110 @@
[#uuid_clock]
== <boost/uuid/uuid_clock.hpp>
:idprefix: uuid_clock_
=== Synopsis
[source,c++]
----
namespace boost {
namespace uuids {
class uuid_clock
{
public:
using rep = std::int64_t;
using period = std::ratio<1, 10000000>; // 100ns
using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<uuid_clock, duration>;
static constexpr bool is_steady = false;
static time_point now() noexcept;
static time_point from_sys( std::chrono::system_clock::time_point const& tp ) noexcept;
static std::chrono::system_clock::time_point to_sys( time_point const& tp ) noexcept;
static time_point from_timestamp( std::uint64_t timestamp ) noexcept;
static std::uint64_t to_timestamp( time_point const& tp ) noexcept;
};
}} // namespace boost::uuids
----
The class `uuid_clock` is a `<chrono>`-compatible clock with an epoch of 00:00:00.00, 15 October 1582, and a resolution of 100 ns.
These values are specified in https://www.rfc-editor.org/rfc/rfc4122.html#section-4.1.4[RFC 4122 Section 4.1.4].
=== now
```
static time_point now() noexcept;
```
Returns: :: The current system time (`std::chrono::system_clock::now()`, converted to `uuid_clock::time_point`.)
=== from_sys
```
static time_point from_sys( std::chrono::system_clock::time_point const& tp ) noexcept;
```
Returns: :: The `uuid_clock::time_point` corresponding to `tp`.
=== to_sys
```
static std::chrono::system_clock::time_point to_sys( time_point const& tp ) noexcept;
```
Returns: :: The `std::chrono::system_clock::time_point` corresponding to `tp`.
Example: ::
+
```
#include <boost/uuid/time_generator_v1.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_clock.hpp>
#include <chrono>
using namespace boost::uuids;
int main()
{
time_generator_v1 gen;
uuid u = gen(); // generates a version 1 time-based UUID
// note that stream output of std::chrono::system_clock::time_point requires C++20
std::cout << uuid_clock::to_sys( u.time_point_v1() ) << std::endl;
}
```
=== from_timestamp
```
static time_point from_timestamp( std::uint64_t timestamp ) noexcept;
```
Returns: :: The `uuid_clock::time_point` corresponding to `timestamp` 100 nanosecond intervals since the `uuid_clock` epoch.
=== to_timestamp
```
static std::uint64_t to_timestamp( time_point const& tp ) noexcept;
```
Returns: :: The number of 100 nanosecond intervals since the `uuid_clock` epoch corresponding to `tp`.
Example: ::
+
```
using namespace boost::uuids;
uuid u = time_generator_v1()();
assert( u.timestamp_v1() == uuid_clock::to_timestamp( u.time_point_v1() ) );
```