独自の時計を作成するだけで十分かどうかは、作成した時間をどのように使用するかによって異なります。たとえば、半分の速度で実行したいが、どこかで次のように呼ばれる場合:
std::this_thread::sleep_for(std::chrono::minutes(2));
期間は調整されません。代わりに、sleep_until を使用して、「遅い」クロックを使用する時点を指定する必要があります。しかし、ゆっくり動く時計を作るのはとても簡単です:
template<typename Clock,int slowness>
struct slow_clock {
using rep = typename Clock::rep;
using period = typename Clock::period;
using duration = typename Clock::duration;
using time_point = std::chrono::time_point<slow_clock>;
constexpr static bool is_steady = Clock::is_steady;
static time_point now() {
return time_point(start_time.time_since_epoch() + ((Clock::now() - start_time)/slowness));
}
static const typename Clock::time_point start_time;
};
template<typename Clock,int slowness>
const typename Clock::time_point
slow_clock<Clock,slowness>::start_time = Clock::now();
now() から返される time_points は、指定したクロックに比べて遅い速度で進むように見えます。たとえば、次のプログラムを使用すると、ナノ秒単位でゆっくりとカチカチ音をたてることができます。
int main() {
using Clock = slow_clock<std::chrono::high_resolution_clock,500000000>;
for(int i=0;i<10;++i) {
std::this_thread::sleep_until(Clock::now()
+ std::chrono::nanoseconds(1));
std::cout << "tick\n";
}
}
など、実装するすべての関数は、MessageQueue::poll()
おそらくグローバル クロックの typedef に関して実装する必要があります。
もちろん、これはプログラムの実際の実行速度とは何の関係もありませんが、それらに基づいてプログラムの速度を落としている場合を除きます。タイムアウトする関数はより長くかかり、sleep_until はより長くかかりますが、将来のある時点を待たない操作は単に高速に見えるだけです。
// appears to run a million times faster than normal according to (finish-start)
auto start = slow_clock<steady_clock,1000000>::now();
do_slow_operation();
auto finish = slow_clock<steady_clock,1000000>::now();