proxygen
Chrono.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <chrono>
20 #include <stdexcept>
21 #include <type_traits>
22 
23 #include <folly/Portability.h>
24 #include <folly/lang/Exception.h>
25 #include <folly/portability/Time.h>
26 
27 /***
28  * include or backport:
29  * * std::chrono::ceil
30  * * std::chrono::floor
31  * * std::chrono::round
32  */
33 
34 #if __cpp_lib_chrono >= 201510 || _MSC_VER
35 
36 namespace folly {
37 namespace chrono {
38 
39 /* using override */ using std::chrono::ceil;
40 /* using override */ using std::chrono::floor;
41 /* using override */ using std::chrono::round;
42 } // namespace chrono
43 } // namespace folly
44 
45 #else
46 
47 namespace folly {
48 namespace chrono {
49 
50 namespace detail {
51 
52 // from: http://en.cppreference.com/w/cpp/chrono/duration/ceil, CC-BY-SA
53 template <typename T>
55 template <typename Rep, typename Period>
56 struct is_duration<std::chrono::duration<Rep, Period>> : std::true_type {};
57 
58 template <typename To, typename Duration>
59 constexpr To ceil_impl(Duration const& d, To const& t) {
60  return t < d ? t + To{1} : t;
61 }
62 
63 template <typename To, typename Duration>
64 constexpr To floor_impl(Duration const& d, To const& t) {
65  return t > d ? t - To{1} : t;
66 }
67 
68 template <typename To, typename Diff>
69 constexpr To round_impl(To const& t0, To const& t1, Diff diff0, Diff diff1) {
70  return diff0 < diff1 ? t0 : diff1 < diff0 ? t1 : t0.count() & 1 ? t1 : t0;
71 }
72 
73 template <typename To, typename Duration>
74 constexpr To round_impl(Duration const& d, To const& t0, To const& t1) {
75  return round_impl(t0, t1, d - t0, t1 - d);
76 }
77 
78 template <typename To, typename Duration>
79 constexpr To round_impl(Duration const& d, To const& t0) {
80  return round_impl(d, t0, t0 + To{1});
81 }
82 } // namespace detail
83 
84 // mimic: std::chrono::ceil, C++17
85 // from: http://en.cppreference.com/w/cpp/chrono/duration/ceil, CC-BY-SA
86 template <
87  typename To,
88  typename Rep,
89  typename Period,
91 constexpr To ceil(std::chrono::duration<Rep, Period> const& d) {
92  return detail::ceil_impl(d, std::chrono::duration_cast<To>(d));
93 }
94 
95 // mimic: std::chrono::ceil, C++17
96 // from: http://en.cppreference.com/w/cpp/chrono/time_point/ceil, CC-BY-SA
97 template <
98  typename To,
99  typename Clock,
100  typename Duration,
102 constexpr std::chrono::time_point<Clock, To> ceil(
103  std::chrono::time_point<Clock, Duration> const& tp) {
104  return std::chrono::time_point<Clock, To>{ceil<To>(tp.time_since_epoch())};
105 }
106 
107 // mimic: std::chrono::floor, C++17
108 // from: http://en.cppreference.com/w/cpp/chrono/duration/floor, CC-BY-SA
109 template <
110  typename To,
111  typename Rep,
112  typename Period,
114 constexpr To floor(std::chrono::duration<Rep, Period> const& d) {
115  return detail::floor_impl(d, std::chrono::duration_cast<To>(d));
116 }
117 
118 // mimic: std::chrono::floor, C++17
119 // from: http://en.cppreference.com/w/cpp/chrono/time_point/floor, CC-BY-SA
120 template <
121  typename To,
122  typename Clock,
123  typename Duration,
125 constexpr std::chrono::time_point<Clock, To> floor(
126  std::chrono::time_point<Clock, Duration> const& tp) {
127  return std::chrono::time_point<Clock, To>{floor<To>(tp.time_since_epoch())};
128 }
129 
130 // mimic: std::chrono::round, C++17
131 // from: http://en.cppreference.com/w/cpp/chrono/duration/round, CC-BY-SA
132 template <
133  typename To,
134  typename Rep,
135  typename Period,
136  typename = typename std::enable_if<
139 constexpr To round(std::chrono::duration<Rep, Period> const& d) {
140  return detail::round_impl(d, floor<To>(d));
141 }
142 
143 // mimic: std::chrono::round, C++17
144 // from: http://en.cppreference.com/w/cpp/chrono/time_point/round, CC-BY-SA
145 template <
146  typename To,
147  typename Clock,
148  typename Duration,
149  typename = typename std::enable_if<
152 constexpr std::chrono::time_point<Clock, To> round(
153  std::chrono::time_point<Clock, Duration> const& tp) {
154  return std::chrono::time_point<Clock, To>{round<To>(tp.time_since_epoch())};
155 }
156 } // namespace chrono
157 } // namespace folly
158 
159 #endif
160 
161 namespace folly {
162 namespace chrono {
163 
165  using rep = std::chrono::milliseconds::rep;
166  using period = std::chrono::milliseconds::period;
167  using duration = std::chrono::duration<rep, period>;
168  using time_point = std::chrono::time_point<coarse_steady_clock, duration>;
169  constexpr static bool is_steady = true;
170 
172 #ifndef CLOCK_MONOTONIC_COARSE
173  return time_point(std::chrono::duration_cast<duration>(
174  std::chrono::steady_clock::now().time_since_epoch()));
175 #else
176  timespec ts;
177  auto ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
178  if (kIsDebug && (ret != 0)) {
179  throw_exception<std::runtime_error>(
180  "Error using CLOCK_MONOTONIC_COARSE.");
181  }
182 
183  return time_point(std::chrono::duration_cast<duration>(
184  std::chrono::seconds(ts.tv_sec) +
185  std::chrono::nanoseconds(ts.tv_nsec)));
186 #endif
187  }
188 };
189 
190 } // namespace chrono
191 } // namespace folly
chrono
Definition: CMakeCache.txt:563
constexpr To ceil(std::chrono::duration< Rep, Period > const &d)
Definition: Chrono.h:91
std::chrono::time_point< coarse_steady_clock, duration > time_point
Definition: Chrono.h:168
int(* clock_gettime)(clockid_t, timespec *ts)
constexpr auto kIsDebug
Definition: Portability.h:264
constexpr std::chrono::time_point< Clock, To > floor(std::chrono::time_point< Clock, Duration > const &tp)
Definition: Chrono.h:125
constexpr To round(std::chrono::duration< Rep, Period > const &d)
Definition: Chrono.h:139
PskType type
std::chrono::steady_clock::time_point now()
STL namespace.
constexpr To ceil_impl(Duration const &d, To const &t)
Definition: Chrono.h:59
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
constexpr To round_impl(Duration const &d, To const &t0)
Definition: Chrono.h:79
constexpr To floor_impl(Duration const &d, To const &t)
Definition: Chrono.h:64
bool_constant< true > true_type
Definition: gtest-port.h:2210
std::chrono::milliseconds Duration
Definition: Types.h:36
constexpr std::chrono::time_point< Clock, To > round(std::chrono::time_point< Clock, Duration > const &tp)
Definition: Chrono.h:152
static time_point now() noexcept
Definition: Chrono.h:171
static const char *const value
Definition: Conv.cpp:50
std::chrono::milliseconds::period period
Definition: Chrono.h:166
bool_constant< false > false_type
Definition: gtest-port.h:2209
constexpr To round_impl(To const &t0, To const &t1, Diff diff0, Diff diff1)
Definition: Chrono.h:69
constexpr std::chrono::time_point< Clock, To > ceil(std::chrono::time_point< Clock, Duration > const &tp)
Definition: Chrono.h:102
std::chrono::duration< rep, period > duration
Definition: Chrono.h:167
constexpr To floor(std::chrono::duration< Rep, Period > const &d)
Definition: Chrono.h:114
std::chrono::milliseconds::rep rep
Definition: Chrono.h:165