231 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: std-at-least-c++2010 11// <chrono>12//13// template<class T> struct is_clock;14// template<class T> constexpr bool is_clock_v = is_clock<T>::value;15 16#include <chrono>17#include <ratio>18 19#include "test_macros.h"20 21struct EmptyStruct {};22 23// Test structs missing required members24struct MissingRep {25 using period = std::ratio<1>;26 using duration = std::chrono::seconds;27 using time_point = std::chrono::time_point<MissingRep>;28 static constexpr bool is_steady = false;29 static time_point now();30};31 32struct MissingPeriod {33 using rep = long;34 using duration = std::chrono::seconds;35 using time_point = std::chrono::time_point<MissingPeriod>;36 static constexpr bool is_steady = false;37 static time_point now();38};39 40struct MissingDuration {41 using rep = long;42 using time_point = long;43 static constexpr bool is_steady = false;44 static time_point now();45};46 47struct MissingTimePoint {48 using rep = long;49 using period = std::ratio<1>;50 using duration = std::chrono::seconds;51 static constexpr bool is_steady = false;52 static std::chrono::time_point<MissingTimePoint> now();53};54 55struct MissingIsSteady {56 using rep = long;57 using period = std::ratio<1>;58 using duration = std::chrono::seconds;59 using time_point = std::chrono::time_point<MissingIsSteady>;60 static time_point now();61};62 63struct MissingNow {64 using rep = long;65 using period = std::ratio<1>;66 using duration = std::chrono::seconds;67 using time_point = std::chrono::time_point<MissingNow>;68 static constexpr bool is_steady = false;69};70 71// Valid clock types72struct ValidSteadyClock {73 using rep = long long;74 using period = std::nano;75 using duration = std::chrono::nanoseconds;76 using time_point = std::chrono::time_point<ValidSteadyClock>;77 static constexpr bool is_steady = true;78 static time_point now();79};80 81struct ValidSystemClock {82 using rep = long long;83 using period = std::micro;84 using duration = std::chrono::microseconds;85 using time_point = std::chrono::time_point<ValidSystemClock>;86 static constexpr bool is_steady = false;87 static time_point now();88};89 90// Test clocks with invalid is_steady type91struct WrongIsSteadyType {92 using rep = long;93 using period = std::ratio<1>;94 using duration = std::chrono::seconds;95 using time_point = std::chrono::time_point<WrongIsSteadyType>;96 static bool is_steady; // Not const bool97 static time_point now();98};99 100struct WrongIsSteadyNonBool {101 using rep = long;102 using period = std::ratio<1>;103 using duration = std::chrono::seconds;104 using time_point = std::chrono::time_point<WrongIsSteadyNonBool>;105 static constexpr int is_steady = 1; // Not bool106 static time_point now();107};108 109// Test clocks with invalid now() return type110struct WrongNowReturnType {111 using rep = long;112 using period = std::ratio<1>;113 using duration = std::chrono::seconds;114 using time_point = std::chrono::time_point<WrongNowReturnType>;115 static constexpr bool is_steady = false;116 static int now(); // Wrong return type117};118 119// Test clocks with invalid period type120struct WrongPeriodType {121 using rep = long;122 using period = int; // Not a ratio123 using duration = std::chrono::seconds;124 using time_point = std::chrono::time_point<WrongPeriodType>;125 static constexpr bool is_steady = false;126 static time_point now();127};128 129// Test clocks with wrong duration type130struct WrongDurationType {131 using rep = long;132 using period = std::ratio<1>;133 using duration = std::chrono::milliseconds; // Should be duration<long, ratio<1>>134 using time_point = std::chrono::time_point<WrongDurationType>;135 static constexpr bool is_steady = false;136 static time_point now();137};138 139// Test clocks with wrong time_point type140struct WrongTimePointType {141 using rep = long;142 using period = std::ratio<1>;143 using duration = std::chrono::duration<long, std::ratio<1>>;144 using time_point = int; // Not a time_point145 static constexpr bool is_steady = false;146 static time_point now();147};148 149struct WrongTimePointClock {150 using rep = long;151 using period = std::ratio<1>;152 using duration = std::chrono::duration<long, std::ratio<1>>;153 using time_point = std::chrono::time_point<ValidSystemClock>; // Wrong clock type154 static constexpr bool is_steady = false;155 static time_point now();156};157 158// Valid clock with time_point that has matching duration instead of matching clock159struct ValidClockWithDurationMatch {160 using rep = int;161 using period = std::milli;162 using duration = std::chrono::duration<int, std::milli>;163 using time_point = std::chrono::time_point<ValidSystemClock, duration>; // Valid: matches duration164 static constexpr bool is_steady = false;165 static time_point now();166};167 168// Test both is_clock and is_clock_v169static_assert(std::chrono::is_clock<std::chrono::system_clock>::value);170static_assert(std::chrono::is_clock_v<std::chrono::system_clock>);171 172// Test standard clock types173static_assert(std::chrono::is_clock_v<std::chrono::system_clock>);174static_assert(std::chrono::is_clock_v<std::chrono::high_resolution_clock>);175 176// Test non-clock types177static_assert(!std::chrono::is_clock_v<EmptyStruct>);178static_assert(!std::chrono::is_clock_v<int>);179static_assert(!std::chrono::is_clock_v<void>);180static_assert(!std::chrono::is_clock_v<std::chrono::system_clock::time_point>);181static_assert(!std::chrono::is_clock_v<std::chrono::seconds>);182static_assert(!std::chrono::is_clock_v<std::chrono::milliseconds>);183 184// Test structs missing required members185static_assert(!std::chrono::is_clock_v<MissingRep>);186static_assert(!std::chrono::is_clock_v<MissingPeriod>);187static_assert(!std::chrono::is_clock_v<MissingDuration>);188static_assert(!std::chrono::is_clock_v<MissingTimePoint>);189static_assert(!std::chrono::is_clock_v<MissingIsSteady>);190static_assert(!std::chrono::is_clock_v<MissingNow>);191 192// Test valid custom clocks193static_assert(std::chrono::is_clock_v<ValidSteadyClock>);194static_assert(std::chrono::is_clock_v<ValidSystemClock>);195static_assert(std::chrono::is_clock_v<ValidClockWithDurationMatch>);196 197// cv-qualified and reference types198static_assert(std::chrono::is_clock_v<const std::chrono::system_clock>);199static_assert(std::chrono::is_clock_v<volatile std::chrono::system_clock>);200static_assert(std::chrono::is_clock_v<const volatile std::chrono::system_clock>);201static_assert(!std::chrono::is_clock_v<std::chrono::system_clock&>);202static_assert(!std::chrono::is_clock_v<std::chrono::system_clock&&>);203static_assert(!std::chrono::is_clock_v<const std::chrono::system_clock&>);204 205// array and pointer types206static_assert(!std::chrono::is_clock_v<std::chrono::system_clock[]>);207static_assert(!std::chrono::is_clock_v<std::chrono::system_clock[10]>);208static_assert(!std::chrono::is_clock_v<std::chrono::system_clock*>);209static_assert(!std::chrono::is_clock_v<std::chrono::system_clock* const>);210 211// The Standard defined a minimum set of checks and allowed implementation to perform stricter checks. The following212// static asserts are implementation specific and a conforming standard library implementation doesn't have to produce213// the same outcome.214 215// Test clocks with invalid is_steady type216LIBCPP_STATIC_ASSERT(!std::chrono::is_clock_v<WrongIsSteadyType>); // is_steady not const bool217LIBCPP_STATIC_ASSERT(!std::chrono::is_clock_v<WrongIsSteadyNonBool>); // is_steady not bool type218 219// Test clocks with invalid now() return type220LIBCPP_STATIC_ASSERT(!std::chrono::is_clock_v<WrongNowReturnType>); // now() doesn't return time_point221 222// Test clocks with invalid period type223LIBCPP_STATIC_ASSERT(!std::chrono::is_clock_v<WrongPeriodType>); // period is not a ratio224 225// Test clocks with wrong duration type226LIBCPP_STATIC_ASSERT(!std::chrono::is_clock_v<WrongDurationType>); // duration doesn't match duration<rep, period>227 228// Test clocks with wrong time_point type229LIBCPP_STATIC_ASSERT(!std::chrono::is_clock_v<WrongTimePointType>); // time_point is not a time_point230LIBCPP_STATIC_ASSERT(!std::chrono::is_clock_v<WrongTimePointClock>); // time_point has wrong clock and wrong duration231