Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/experimental/timer
1 // <experimental/timer> -*- C++ -*- 2 3 // Copyright (C) 2015-2025 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file experimental/timer 26 * This is a TS C++ Library header. 27 * @ingroup networking-ts 28 */ 29 30 #ifndef _GLIBCXX_EXPERIMENTAL_TIMER 31 #define _GLIBCXX_EXPERIMENTAL_TIMER 1 32 33 #ifdef _GLIBCXX_SYSHDR 34 #pragma GCC system_header 35 #endif 36 37 #include <bits/requires_hosted.h> // experimental is currently omitted 38 39 #if __cplusplus >= 201402L 40 41 #include <bits/chrono.h> 42 #include <system_error> 43 #include <thread> 44 #include <experimental/netfwd> 45 #include <experimental/io_context> 46 #include <experimental/bits/net.h> 47 48 namespace std _GLIBCXX_VISIBILITY(default) 49 { 50 _GLIBCXX_BEGIN_NAMESPACE_VERSION 51 namespace experimental 52 { 53 namespace net 54 { 55 inline namespace v1 56 { 57 58 /** @addtogroup networking-ts 59 * @{ 60 */ 61 62 template<typename _Clock> 63 struct wait_traits 64 { 65 static typename _Clock::duration 66 to_wait_duration(const typename _Clock::duration& __d) 67 { return __d; } 68 69 static typename _Clock::duration 70 to_wait_duration(const typename _Clock::time_point& __t) 71 { 72 auto __now = _Clock::now(); 73 auto __diff = __t - __now; 74 if (__diff > _Clock::duration::max()) 75 return _Clock::duration::max(); 76 if (__diff < _Clock::duration::min()) 77 return _Clock::duration::min(); 78 return __diff; 79 } 80 }; 81 82 template<typename _Clock, typename _WaitTraits> 83 class basic_waitable_timer 84 { 85 public: 86 // types: 87 88 using executor_type = io_context::executor_type; 89 using clock_type = _Clock; 90 using duration = typename clock_type::duration; 91 using time_point = typename clock_type::time_point; 92 using traits_type = _WaitTraits; 93 94 // construct / copy / destroy: 95 96 explicit 97 basic_waitable_timer(io_context& __ctx) 98 : _M_ex(__ctx.get_executor()), _M_expiry() 99 { } 100 101 basic_waitable_timer(io_context& __ctx, const time_point& __t) 102 : _M_ex(__ctx.get_executor()), _M_expiry(__t) 103 { } 104 105 basic_waitable_timer(io_context& __ctx, const duration& __d) 106 : _M_ex(__ctx.get_executor()), _M_expiry(_Clock::now() + __d) 107 { } 108 109 basic_waitable_timer(const basic_waitable_timer&) = delete; 110 111 basic_waitable_timer(basic_waitable_timer&& __rhs) 112 : _M_ex(std::move(__rhs._M_ex)), _M_expiry(__rhs._M_expiry) 113 { 114 _M_key.swap(__rhs._M_key); 115 __rhs._M_expiry = time_point{}; 116 } 117 118 ~basic_waitable_timer() { cancel(); } 119 120 basic_waitable_timer& operator=(const basic_waitable_timer&) = delete; 121 122 basic_waitable_timer& 123 operator=(basic_waitable_timer&& __rhs) 124 { 125 if (this == std::addressof(__rhs)) 126 return *this; 127 cancel(); 128 _M_ex = std::move(__rhs._M_ex); 129 _M_expiry = __rhs._M_expiry; 130 __rhs._M_expiry = time_point{}; 131 _M_key.swap(__rhs._M_key); 132 return *this; 133 } 134 135 // basic_waitable_timer operations: 136 137 executor_type get_executor() noexcept { return _M_ex; } 138 139 size_t cancel() { return _M_ex.context().cancel(*this); } 140 size_t cancel_one() { return _M_ex.context().cancel_one(*this); } 141 142 time_point expiry() const { return _M_expiry; } 143 144 size_t expires_at(const time_point& __t) 145 { 146 size_t __cancelled = cancel(); 147 _M_expiry = __t; 148 return __cancelled; 149 } 150 151 size_t expires_after(const duration& __d) 152 { return expires_at(_Clock::now() + __d); } 153 154 void wait(); 155 void wait(error_code& __ec); 156 157 template<typename _CompletionToken> 158 __deduced_t<_CompletionToken, void(error_code)> 159 async_wait(_CompletionToken&& __token) 160 { 161 async_completion<_CompletionToken, void(error_code)> __init(__token); 162 _M_ex.context().async_wait(*this, 163 std::move(__init.completion_handler)); 164 return __init.result.get(); 165 } 166 167 private: 168 executor_type _M_ex; 169 time_point _M_expiry; 170 171 struct _Key { }; // TODO move _M_expiry into here? 172 unique_ptr<_Key> _M_key{new _Key}; 173 174 friend class io_context; 175 }; 176 177 using system_timer = basic_waitable_timer<chrono::system_clock>; 178 using steady_timer = basic_waitable_timer<chrono::steady_clock>; 179 using high_resolution_timer 180 = basic_waitable_timer<chrono::high_resolution_clock>; 181 182 template<typename _Clock, typename _WaitTraits> 183 void 184 basic_waitable_timer<_Clock, _WaitTraits>::wait() 185 { 186 _M_ex.dispatch([this] { 187 while (clock_type::now() < _M_expiry) 188 this_thread::sleep_for(traits_type::to_wait_duration(_M_expiry)); 189 }, allocator<void>{}); 190 } 191 192 template<typename _Clock, typename _WaitTraits> 193 void 194 basic_waitable_timer<_Clock, _WaitTraits>::wait(error_code&) 195 { 196 _M_ex.dispatch([this] { 197 while (clock_type::now() < _M_expiry) 198 this_thread::sleep_for(traits_type::to_wait_duration(_M_expiry)); 199 }, allocator<void>{}); 200 } 201 202 /// @} 203 204 } // namespace v1 205 } // namespace net 206 } // namespace experimental 207 _GLIBCXX_END_NAMESPACE_VERSION 208 } // namespace std 209 210 #endif // C++14 211 212 #endif // _GLIBCXX_EXPERIMENTAL_TIMER