1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef PLATFORM_BASE_TRIVIAL_CLOCK_TRAITS_H_ 6 #define PLATFORM_BASE_TRIVIAL_CLOCK_TRAITS_H_ 7 8 #include <chrono> 9 #include <ostream> 10 11 namespace openscreen { 12 13 // The Open Screen monotonic clock traits description, providing all the C++14 14 // requirements of a TrivialClock, for use with STL <chrono>. 15 class TrivialClockTraits { 16 public: 17 // TrivialClock named requirements: std::chrono templates can/may use these. 18 // NOTE: unless you are specifically integrating with the clock, you probably 19 // don't want to use these types, and instead should reference the std::chrono 20 // types directly. 21 using duration = std::chrono::microseconds; 22 using rep = duration::rep; 23 using period = duration::period; 24 using time_point = std::chrono::time_point<TrivialClockTraits, duration>; 25 static constexpr bool is_steady = true; 26 27 // Helper method for named requirements. 28 template <typename D> to_duration(D d)29 static constexpr duration to_duration(D d) { 30 return std::chrono::duration_cast<duration>(d); 31 } 32 33 // Time point values from the clock use microsecond precision, as a reasonably 34 // high-resolution clock is required. The time source must tick forward at 35 // least 10000 times per second. 36 using kRequiredResolution = std::ratio<1, 10000>; 37 38 // In <chrono>, a clock type is just some type properties plus a static now() 39 // function. So, there's nothing to instantiate here. 40 TrivialClockTraits() = delete; 41 ~TrivialClockTraits() = delete; 42 43 // "Trivially copyable" is necessary for using the time types in 44 // std::atomic<>. 45 static_assert(std::is_trivially_copyable<duration>(), 46 "duration is not trivially copyable"); 47 static_assert(std::is_trivially_copyable<time_point>(), 48 "time_point is not trivially copyable"); 49 }; 50 51 // Convenience type definition, for injecting time sources into classes (e.g., 52 // &Clock::now versus something else for testing). 53 using ClockNowFunctionPtr = TrivialClockTraits::time_point (*)(); 54 55 // Logging convenience for durations. Outputs a string of the form "123µs". 56 std::ostream& operator<<(std::ostream& os, 57 const TrivialClockTraits::duration& d); 58 59 // Logging convenience for time points. Outputs a string of the form 60 // "123µs-ticks". 61 std::ostream& operator<<(std::ostream& os, 62 const TrivialClockTraits::time_point& tp); 63 64 // Logging (and gtest pretty-printing) for several commonly-used chrono types. 65 std::ostream& operator<<(std::ostream& out, const std::chrono::hours&); 66 std::ostream& operator<<(std::ostream& out, const std::chrono::minutes&); 67 std::ostream& operator<<(std::ostream& out, const std::chrono::seconds&); 68 std::ostream& operator<<(std::ostream& out, const std::chrono::milliseconds&); 69 // Note: The ostream output operator for std::chrono::microseconds is handled by 70 // the one for TrivialClockTraits::duration above since they are the same type. 71 72 } // namespace openscreen 73 74 #endif // PLATFORM_BASE_TRIVIAL_CLOCK_TRAITS_H_ 75