[#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.
