/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/Support/Chrono.h
Line | Count | Source |
1 | | //===- llvm/Support/Chrono.h - Utilities for Timing Manipulation-*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | |
10 | | #ifndef LLVM_SUPPORT_CHRONO_H |
11 | | #define LLVM_SUPPORT_CHRONO_H |
12 | | |
13 | | #include "llvm/Support/Compiler.h" |
14 | | #include "llvm/Support/FormatProviders.h" |
15 | | |
16 | | #include <chrono> |
17 | | #include <ctime> |
18 | | |
19 | | namespace llvm { |
20 | | |
21 | | class raw_ostream; |
22 | | |
23 | | namespace sys { |
24 | | |
25 | | /// A time point on the system clock. This is provided for two reasons: |
26 | | /// - to insulate us agains subtle differences in behavoir to differences in |
27 | | /// system clock precision (which is implementation-defined and differs between |
28 | | /// platforms). |
29 | | /// - to shorten the type name |
30 | | /// The default precision is nanoseconds. If need a specific precision specify |
31 | | /// it explicitly. If unsure, use the default. If you need a time point on a |
32 | | /// clock other than the system_clock, use std::chrono directly. |
33 | | template <typename D = std::chrono::nanoseconds> |
34 | | using TimePoint = std::chrono::time_point<std::chrono::system_clock, D>; |
35 | | |
36 | | /// Convert a TimePoint to std::time_t |
37 | 838k | LLVM_ATTRIBUTE_ALWAYS_INLINE inline std::time_t toTimeT(TimePoint<> TP) { |
38 | 838k | using namespace std::chrono; |
39 | 838k | return system_clock::to_time_t( |
40 | 838k | time_point_cast<system_clock::time_point::duration>(TP)); |
41 | 838k | } |
42 | | |
43 | | /// Convert a std::time_t to a TimePoint |
44 | | LLVM_ATTRIBUTE_ALWAYS_INLINE inline TimePoint<std::chrono::seconds> |
45 | 902k | toTimePoint(std::time_t T) { |
46 | 902k | using namespace std::chrono; |
47 | 902k | return time_point_cast<seconds>(system_clock::from_time_t(T)); |
48 | 902k | } |
49 | | |
50 | | } // namespace sys |
51 | | |
52 | | raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP); |
53 | | |
54 | | /// Implementation of format_provider<T> for duration types. |
55 | | /// |
56 | | /// The options string of a duration type has the grammar: |
57 | | /// |
58 | | /// duration_options ::= [unit][show_unit [number_options]] |
59 | | /// unit ::= `h`|`m`|`s`|`ms|`us`|`ns` |
60 | | /// show_unit ::= `+` | `-` |
61 | | /// number_options ::= options string for a integral or floating point type |
62 | | /// |
63 | | /// Examples |
64 | | /// ================================= |
65 | | /// | options | Input | Output | |
66 | | /// ================================= |
67 | | /// | "" | 1s | 1 s | |
68 | | /// | "ms" | 1s | 1000 ms | |
69 | | /// | "ms-" | 1s | 1000 | |
70 | | /// | "ms-n" | 1s | 1,000 | |
71 | | /// | "" | 1.0s | 1.00 s | |
72 | | /// ================================= |
73 | | /// |
74 | | /// If the unit of the duration type is not one of the units specified above, |
75 | | /// it is still possible to format it, provided you explicitly request a |
76 | | /// display unit or you request that the unit is not displayed. |
77 | | |
78 | | namespace detail { |
79 | | template <typename Period> struct unit { static const char value[]; }; |
80 | | template <typename Period> const char unit<Period>::value[] = ""; |
81 | | |
82 | | template <> struct unit<std::ratio<3600>> { static const char value[]; }; |
83 | | template <> struct unit<std::ratio<60>> { static const char value[]; }; |
84 | | template <> struct unit<std::ratio<1>> { static const char value[]; }; |
85 | | template <> struct unit<std::milli> { static const char value[]; }; |
86 | | template <> struct unit<std::micro> { static const char value[]; }; |
87 | | template <> struct unit<std::nano> { static const char value[]; }; |
88 | | } // namespace detail |
89 | | |
90 | | template <typename Rep, typename Period> |
91 | | struct format_provider<std::chrono::duration<Rep, Period>> { |
92 | | private: |
93 | | typedef std::chrono::duration<Rep, Period> Dur; |
94 | | typedef typename std::conditional< |
95 | | std::chrono::treat_as_floating_point<Rep>::value, double, intmax_t>::type |
96 | | InternalRep; |
97 | | |
98 | | template <typename AsPeriod> static InternalRep getAs(const Dur &D) { |
99 | | using namespace std::chrono; |
100 | | return duration_cast<duration<InternalRep, AsPeriod>>(D).count(); |
101 | | } |
102 | | |
103 | | static std::pair<InternalRep, StringRef> consumeUnit(StringRef &Style, |
104 | | const Dur &D) { |
105 | | using namespace std::chrono; |
106 | | if (Style.consume_front("ns")) |
107 | | return {getAs<std::nano>(D), "ns"}; |
108 | | if (Style.consume_front("us")) |
109 | | return {getAs<std::micro>(D), "us"}; |
110 | | if (Style.consume_front("ms")) |
111 | | return {getAs<std::milli>(D), "ms"}; |
112 | | if (Style.consume_front("s")) |
113 | | return {getAs<std::ratio<1>>(D), "s"}; |
114 | | if (Style.consume_front("m")) |
115 | | return {getAs<std::ratio<60>>(D), "m"}; |
116 | | if (Style.consume_front("h")) |
117 | | return {getAs<std::ratio<3600>>(D), "h"}; |
118 | | return {D.count(), detail::unit<Period>::value}; |
119 | | } |
120 | | |
121 | | static bool consumeShowUnit(StringRef &Style) { |
122 | | if (Style.empty()) |
123 | | return true; |
124 | | if (Style.consume_front("-")) |
125 | | return false; |
126 | | if (Style.consume_front("+")) |
127 | | return true; |
128 | | assert(0 && "Unrecognised duration format"); |
129 | | return true; |
130 | | } |
131 | | |
132 | | public: |
133 | | static void format(const Dur &D, llvm::raw_ostream &Stream, StringRef Style) { |
134 | | InternalRep count; |
135 | | StringRef unit; |
136 | | std::tie(count, unit) = consumeUnit(Style, D); |
137 | | bool show_unit = consumeShowUnit(Style); |
138 | | |
139 | | format_provider<InternalRep>::format(count, Stream, Style); |
140 | | |
141 | | if (show_unit) { |
142 | | assert(!unit.empty()); |
143 | | Stream << " " << unit; |
144 | | } |
145 | | } |
146 | | }; |
147 | | |
148 | | } // namespace llvm |
149 | | |
150 | | #endif // LLVM_SUPPORT_CHRONO_H |