// Three clocks, and only what the standard promises about each.
// Every line prints the same on libstdc++ (GCC) and libc++ (Clang). What the two
// libraries do differently is in the dated table on the page, not in here.
#include <chrono>
#include <iostream>
#include <type_traits>

namespace sc = std::chrono;

// Can a value of type T be written to a stream? A requires-expression asks the
// compiler, and gets true or false back instead of a failed build.
template <class T>
concept printable = requires(std::ostream& os, T value) { os << value; };

int main() {
    std::cout << std::boolalpha;

    // The flag every clock carries. The standard fixes it for two of the three.
    std::cout << "system_clock::is_steady = " << sc::system_clock::is_steady << '\n';  // false
    std::cout << "steady_clock::is_steady = " << sc::steady_clock::is_steady << '\n';  // true

    // The third may be either of the other two, and which one is the library's call.
    constexpr bool one_of_the_two =
        std::is_same_v<sc::high_resolution_clock, sc::system_clock> ||
        std::is_same_v<sc::high_resolution_clock, sc::steady_clock>;
    std::cout << "high_resolution_clock is one of them = " << one_of_the_two << '\n';  // true

    // system_clock counts from 1970-01-01 00:00:00 UTC, so its time points are dates...
    std::cout << "a system_clock time point prints as a date = "
              << printable<sc::system_clock::time_point> << '\n';                      // true
    std::cout << "system_clock's epoch = " << sc::sys_seconds{} << '\n';               // 1970-01-01 00:00:00

    // ...while steady_clock counts from an epoch nobody specifies, so its are not.
    std::cout << "a steady_clock time point prints as a date = "
              << printable<sc::steady_clock::time_point> << '\n';                      // false

    // steady_clock ticks in nanoseconds on every library this runs on.
    using P = sc::steady_clock::period;
    std::cout << "steady_clock tick = " << P::num << '/' << P::den << " s\n";          // 1/1000000000 s
}
