time2_demo.html 164 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html><head>
  3. <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  4. <title>time2_demo</title>
  5. </head><body>
  6. <pre><font color="#c80000">/*
  7. Copyright (c) 2008 Howard Hinnant
  8. Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. A prototype of a proposal for a time/duration/clock library for the C++ standard.
  11. It is intended that this be a solid foundation upon which higher level libraries
  12. can be based. Examples of such libraries include a date/time library and a
  13. physical quantities library.
  14. Two general purpose facilities are proposed:
  15. common_type
  16. ratio
  17. And 5 time/duration/clock facilities are proposed
  18. duration
  19. time_point
  20. system_clock
  21. monotonic_clock <font color="#c80000">// optional</font>
  22. high_resolution_clock <font color="#c80000">// optional</font>
  23. Much thanks to Andrei Alexandrescu,
  24. Walter Brown,
  25. Peter Dimov,
  26. Jeff Garland,
  27. Terry Golubiewski,
  28. Daniel Krügler,
  29. Anthony Williams.
  30. Synopsis
  31. namespace std
  32. {
  33. <font color="#c80000">// &lt;type_traits&gt;</font>
  34. <font color="#c80000">// common_type</font>
  35. <font color="#c80000">// common_type is ageneral purpose trait that can be specialized for user-defined types.</font>
  36. <font color="#c80000">// The semantics are intended to be identical to finding the resulting type of a</font>
  37. <font color="#c80000">// the conditional operator.</font>
  38. <font color="#c80000">// The client may need to specialize common_type if he wishes to convert to or from</font>
  39. <font color="#c80000">// another type only explicitly. It is used to determine the result type</font>
  40. <font color="#c80000">// in "mixed-mode" duration and time_point arithmetic. It will also find use in</font>
  41. <font color="#c80000">// similar "mixed-mode" arithmetic applications.</font>
  42. template &lt;class T, class U&gt;
  43. struct common_type
  44. {
  45. private:
  46. static T t();
  47. static U u();
  48. public:
  49. typedef decltype(true ? t() : u()) type;
  50. };
  51. <font color="#c80000">// or...</font>
  52. template &lt;class ...T&gt; struct common_type;
  53. template &lt;class T&gt;
  54. struct common_type&lt;T&gt;
  55. {
  56. typedef T type;
  57. };
  58. template &lt;class T, class U&gt;
  59. struct common_type&lt;T, U&gt;
  60. {
  61. private:
  62. static T t();
  63. static U u();
  64. public:
  65. typedef decltype(true ? t() : u()) type;
  66. };
  67. template &lt;class T, class U, class ...V&gt;
  68. struct common_type&lt;T, U, V...&gt;
  69. {
  70. typedef typename common_type&lt;typename common_type&lt;T, U&gt;::type, V...&gt;::type type;
  71. };
  72. <font color="#c80000">// This alternative variadic formulation of common_type has some advantages:</font>
  73. <font color="#c80000">//</font>
  74. <font color="#c80000">// 1. The obvious advantage is that it can handle 3 or more arguments seamlessly.</font>
  75. <font color="#c80000">// This can come in handy when writing template functions that take more than</font>
  76. <font color="#c80000">// two arguments, such as fma(x, y, z).</font>
  77. <font color="#c80000">//</font>
  78. <font color="#c80000">// 2. We could just get rid of identity (avoiding the legacy conflict) and use</font>
  79. <font color="#c80000">// common_type&lt;T&gt;::type in the one place we use identity&lt;T&gt;::type today.</font>
  80. <font color="#c80000">//</font>
  81. <font color="#c80000">// 3. For clients that need to specialize common_type (such as duration and time_point),</font>
  82. <font color="#c80000">// the client still needs to specialize only the two-argument version. The default</font>
  83. <font color="#c80000">// definition of the higher-order common_type will automatically use the client's</font>
  84. <font color="#c80000">// specialized two-argument version.</font>
  85. <font color="#c80000">// For example:</font>
  86. <font color="#c80000">// common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type is duration&lt;double, micro&gt;</font>
  87. <font color="#c80000">// ... end or</font>
  88. <font color="#c80000">// The cost of not including either version of common_type is that it is very likely that</font>
  89. <font color="#c80000">// the implementation would include it anyway, but spell it __common_type instead. This</font>
  90. <font color="#c80000">// would prevent authors of arithmetic emulators from using their classes as representations</font>
  91. <font color="#c80000">// with durations unless the emulator had exactly one implicit conversion to or from an</font>
  92. <font color="#c80000">// arithmetic type. This would be a large loss of functionality from the client's point</font>
  93. <font color="#c80000">// of view, possibly mandating a less safe interface for the client's arithmetic emulator.</font>
  94. <font color="#c80000">// ratio</font>
  95. <font color="#c80000">// ratio is a general purpose type allowing one to easily and safely compute integral</font>
  96. <font color="#c80000">// ratio values at compile time. The ratio class catches all errors (such as divide by</font>
  97. <font color="#c80000">// zero and overflow) at compile time. It is used in the duration and time_point libraries</font>
  98. <font color="#c80000">// to efficiently create units of time. It can also be used in other "quantity"</font>
  99. <font color="#c80000">// libraries (both std-defined and user-defined), or anywhere there is an integral</font>
  100. <font color="#c80000">// ratio which is known at compile time. The use of this utility can greatly reduce</font>
  101. <font color="#c80000">// the chances of run time overflow because the ratio (and any ratios resulting from</font>
  102. <font color="#c80000">// ratio arithmetic) are always reduced to lowest terms.</font>
  103. <font color="#c80000">// The cost of not including ratio would mean that the implementor would likely have this</font>
  104. <font color="#c80000">// functionality anyway, but spell it __ratio instead. This would prevent the client from</font>
  105. <font color="#c80000">// using ratio in his own code as demonstrated in the "User1" example. Furthermore duration</font>
  106. <font color="#c80000">// would have to be templated on two long long's instead of on ratio like so:</font>
  107. <font color="#c80000">//</font>
  108. <font color="#c80000">// template &lt;class Rep, long long N, long long D&gt; duration.</font>
  109. <font color="#c80000">//</font>
  110. <font color="#c80000">// This would mean that clients wanting to build a custom duration type (say a nanosecond</font>
  111. <font color="#c80000">// represented by a double) would have to write:</font>
  112. <font color="#c80000">//</font>
  113. <font color="#c80000">// duration&lt;double, 1, 1000000000LL&gt;</font>
  114. <font color="#c80000">//</font>
  115. <font color="#c80000">// instead of:</font>
  116. <font color="#c80000">//</font>
  117. <font color="#c80000">// duration&lt;double, nano&gt;</font>
  118. <font color="#c80000">//</font>
  119. <font color="#c80000">// This lack of syntatic niceness, along with the loss of functionality in the reuse of</font>
  120. <font color="#c80000">// ratio in user-written code seems to indicate that the loss of ratio would be a sizeable</font>
  121. <font color="#c80000">// loss to client code.</font>
  122. template &lt;intmax_t N, intmax_t D = 1&gt;
  123. class ratio
  124. {
  125. <font color="#c80000">// For every possible value of N and D, abs(N) &gt;= 0 and abs(D) &gt; 0</font>
  126. static_assert(__static_abs&lt;N&gt;::value &gt;= 0, "ratio numerator is out of range");
  127. static_assert(__static_abs&lt;D&gt;::value &gt; 0, "ratio denominator is out of range");
  128. public:
  129. static const intmax_t num; <font color="#c80000">// Reduced by greatest common divisor of N and D, has sign of sign(N) * sign(D)</font>
  130. static const intmax_t den; <font color="#c80000">// Reduced by greatest common divisor of N and D, always positive</font>
  131. <font color="#c80000">// When num == 0, den == 1</font>
  132. };
  133. <font color="#c80000">// The static_asserts in ratio are there to catch any values which have a negative absolute value.</font>
  134. <font color="#c80000">// In a typical 2's complement representation this is only LLONG_MIN. The reason for prohibiting</font>
  135. <font color="#c80000">// this value is because ratio must take the absolute values of its arguments and generally depends</font>
  136. <font color="#c80000">// on that number being non-negative in order to maintain invariants such as den &gt; 0.</font>
  137. <font color="#c80000">// convenience typedefs</font>
  138. typedef ratio&lt;1, 1000000000000000000000000&gt; yocto; <font color="#c80000">// conditionally supported</font>
  139. typedef ratio&lt;1, 1000000000000000000000&gt; zepto; <font color="#c80000">// conditionally supported</font>
  140. typedef ratio&lt;1, 1000000000000000000&gt; atto;
  141. typedef ratio&lt;1, 1000000000000000&gt; femto;
  142. typedef ratio&lt;1, 1000000000000&gt; pico;
  143. typedef ratio&lt;1, 1000000000&gt; nano;
  144. typedef ratio&lt;1, 1000000&gt; micro;
  145. typedef ratio&lt;1, 1000&gt; milli;
  146. typedef ratio&lt;1, 100&gt; centi;
  147. typedef ratio&lt;1, 10&gt; deci;
  148. typedef ratio&lt; 10, 1&gt; deca;
  149. typedef ratio&lt; 100, 1&gt; hecto;
  150. typedef ratio&lt; 1000, 1&gt; kilo;
  151. typedef ratio&lt; 1000000, 1&gt; mega;
  152. typedef ratio&lt; 1000000000, 1&gt; giga;
  153. typedef ratio&lt; 1000000000000, 1&gt; tera;
  154. typedef ratio&lt; 1000000000000000, 1&gt; peta;
  155. typedef ratio&lt; 1000000000000000000, 1&gt; exa;
  156. typedef ratio&lt; 1000000000000000000000, 1&gt; zetta; <font color="#c80000">// conditionally supported</font>
  157. typedef ratio&lt;1000000000000000000000000, 1&gt; yotta; <font color="#c80000">// conditionally supported</font>
  158. <font color="#c80000">// Compile time arithmetic and comparisons should either avoid overflow or not compile</font>
  159. template &lt;class R1, class R2&gt;
  160. requires R1 and R2 are instantiations of ratio
  161. struct ratio_add
  162. {
  163. typedef ratio&lt;pseudo code: R1 + R2&gt; type;
  164. };
  165. template &lt;class R1, class R2&gt;
  166. requires R1 and R2 are instantiations of ratio
  167. struct ratio_subtract
  168. {
  169. typedef ratio&lt;pseudo code: R1 - R2&gt; type;
  170. };
  171. template &lt;class R1, class R2&gt;
  172. requires R1 and R2 are instantiations of ratio
  173. struct ratio_multiply
  174. {
  175. typedef ratio&lt;pseudo code: R1 * R2&gt; type;
  176. };
  177. template &lt;class R1, class R2&gt;
  178. requires R1 and R2 are instantiations of ratio
  179. struct ratio_divide
  180. {
  181. typedef ratio&lt;pseudo code: R1 / R2&gt; type;
  182. };
  183. template &lt;class R1, class R2&gt;
  184. requires R1 and R2 are instantiations of ratio
  185. struct ratio_equal
  186. : public integral_constant&lt;bool, pseudo code: R1 == R2&gt; {};
  187. template &lt;class R1, class R2&gt;
  188. requires R1 and R2 are instantiations of ratio
  189. struct ratio_not_equal
  190. : public integral_constant&lt;bool, !ratio_equal&lt;R1, R2&gt;::value&gt; {};
  191. template &lt;class R1, class R2&gt;
  192. requires R1 and R2 are instantiations of ratio
  193. struct ratio_less
  194. : public integral_constant&lt;bool, pseudo code: R1 &lt; R2&gt; {};
  195. template &lt;class R1, class R2&gt;
  196. requires R1 and R2 are instantiations of ratio
  197. struct ratio_less_equal
  198. : public integral_constant&lt;bool, !ratio_less&lt;R2, R1&gt;::value&gt; {};
  199. template &lt;class R1, class R2&gt;
  200. requires R1 and R2 are instantiations of ratio
  201. struct ratio_greater
  202. : public integral_constant&lt;bool, ratio_less&lt;R2, R1&gt;::value&gt; {};
  203. template &lt;class R1, class R2&gt;
  204. requires R1 and R2 are instantiations of ratio
  205. struct ratio_greater_equal
  206. : public integral_constant&lt;bool, !ratio_less&lt;R1, R2&gt;::value&gt; {};
  207. namespace datetime
  208. {
  209. <font color="#c80000">// duration customization traits</font>
  210. <font color="#c80000">// Authors of arithmetic emulation types should specialize treat_as_floating_point</font>
  211. <font color="#c80000">// if their class emulates floating point and they want to use it as a duration's</font>
  212. <font color="#c80000">// representation.</font>
  213. template &lt;class Rep&gt; struct treat_as_floating_point
  214. : is_floating_point&lt;Rep&gt; {};
  215. <font color="#c80000">// Authors of arithmetic emulation types should specialize duration_values</font>
  216. <font color="#c80000">// if they want to use it as a duration's representation, and the default</font>
  217. <font color="#c80000">// definition of duration_values does not have the correct behavior.</font>
  218. template &lt;class Rep&gt;
  219. struct duration_values
  220. {
  221. public:
  222. static constexpr Rep zero() {return Rep(0);}
  223. static constexpr Rep max() {return numeric_limits&lt;Rep&gt;::max();}
  224. static constexpr Rep min() {return -max();}
  225. };
  226. <font color="#c80000">// Note: Rep(0) instead of Rep() is used for zero() because the author of Rep may</font>
  227. <font color="#c80000">// chose to have Rep() refer to an inderminant or unitialized value.</font>
  228. <font color="#c80000">// duration</font>
  229. <font color="#c80000">// A duration has a representation and a period.</font>
  230. <font color="#c80000">// </font>
  231. <font color="#c80000">// The representation is an arithmetic type, or a class emulating an arithmetic type.</font>
  232. <font color="#c80000">//</font>
  233. <font color="#c80000">// The period is the rational number of seconds between "ticks" of the duration. The</font>
  234. <font color="#c80000">// duration simply holds a count of the elapsed number of ticks (using the</font>
  235. <font color="#c80000">// representation), and that is related to seconds by multiplying by the period.</font>
  236. <font color="#c80000">// Note, this multiplication is only required when one needs to convert between</font>
  237. <font color="#c80000">// durations with different tick periods (e.g. milliseconds to microseconds).</font>
  238. <font color="#c80000">// </font>
  239. <font color="#c80000">// A duration has defalt construction and default copy semantics. One can also explicitly</font>
  240. <font color="#c80000">// construct a duration from its representation or something implicitly convertible to</font>
  241. <font color="#c80000">// its representation. If the representation is integral (or emulated integral) the</font>
  242. <font color="#c80000">// duration may not be constructed from a floating point (or emulated floating point)</font>
  243. <font color="#c80000">// type, even if that type is impilcitly convertible to the representation (the client</font>
  244. <font color="#c80000">// must explicitly convert such an argument as they pass it to the constructor if such</font>
  245. <font color="#c80000">// a conversion is desired).</font>
  246. <font color="#c80000">// </font>
  247. <font color="#c80000">// A duration may be implicitly constructible from another duration if the representations</font>
  248. <font color="#c80000">// of the two durations meet certain requirements. Let the representation of this duration</font>
  249. <font color="#c80000">// be Rep1 and the representation of the other duration be Rep2. Example representations</font>
  250. <font color="#c80000">// include int, long long, double, or a user-defined class which emulates one of these</font>
  251. <font color="#c80000">// arithmetic types. To qualify for implicit constructability Rep1 must be explicitly</font>
  252. <font color="#c80000">// constructible from Rep2. Note that implicit constructibility of Rep1 from Rep2 is not</font>
  253. <font color="#c80000">// required for this implicit construction between durations. Additionally the trait</font>
  254. <font color="#c80000">// common_type&lt;Rep1, Rep2&gt;::type must be well defined. If a conditional expression involving</font>
  255. <font color="#c80000">// these two types isn't valid, there must exist a common_type specialization which makes</font>
  256. <font color="#c80000">// the trait valid.</font>
  257. <font color="#c80000">// </font>
  258. <font color="#c80000">// The requirements put on the relationship between Rep1 and Rep2 are intended to be minimal,</font>
  259. <font color="#c80000">// and not require implicit conversions (which could be considered error prone by the author</font>
  260. <font color="#c80000">// of either of these representations).</font>
  261. <font color="#c80000">// </font>
  262. <font color="#c80000">// In addition to the above relationship between the representations, implicit constructability</font>
  263. <font color="#c80000">// also depends on whether the representation is considered floating point (or emulated floating</font>
  264. <font color="#c80000">// point) or integral (or emulated integral).</font>
  265. <font color="#c80000">// </font>
  266. <font color="#c80000">// If a duration has a floating point (or emulated floating point) representation it</font>
  267. <font color="#c80000">// is implicitly constructible from all other durations of any period (as long as</font>
  268. <font color="#c80000">// the representations are compatible as described above).</font>
  269. <font color="#c80000">// </font>
  270. <font color="#c80000">// If a duration has an integral (or emulated integral) representation it is implicitly</font>
  271. <font color="#c80000">// constructible from other integral-based durations which have a period which will exactly convert</font>
  272. <font color="#c80000">// to the period of this duration with no truncation error. More specifically, if the</font>
  273. <font color="#c80000">// period of this duration is P1, and the period of the other duration is P2, this</font>
  274. <font color="#c80000">// duration is implicitly constructible from the other duration if P2/P1 is a whole number</font>
  275. <font color="#c80000">// (as long as the representations are compatible as described above). Example:</font>
  276. <font color="#c80000">// microseconds has a period p1 = 1/1000000 seconds. milliseconds has a period</font>
  277. <font color="#c80000">// P2 = 1/1000 seconds. P2/P1 is (1/1000)/(1/1000000) = 1000000/1000 = 1000.</font>
  278. <font color="#c80000">// Therefore microseconds will implicitly construct from milliseconds (but not vice-versa).</font>
  279. <font color="#c80000">//</font>
  280. <font color="#c80000">// These rules involving integral representations are meant to prevent accidental truncatation</font>
  281. <font color="#c80000">// error. If truncation error is desired, a duration_cast facility is available to force it.</font>
  282. <font color="#c80000">// Example:</font>
  283. <font color="#c80000">// milliseconds ms(3); // ok, ms.count() == 3, which is 0.003 seconds</font>
  284. <font color="#c80000">// microseconds us = ms; // ok, us.count() == 3000 which is 0.003000 seconds</font>
  285. <font color="#c80000">// ++us; // ok, us.count() == 3001 which is 0.003001 seconds</font>
  286. <font color="#c80000">// ms = us; // won't compile, might truncate</font>
  287. <font color="#c80000">// ms = duration_cast&lt;milliseconds&gt;(us); // ok, ms.count() = 3, truncated a microsecond</font>
  288. <font color="#c80000">// </font>
  289. <font color="#c80000">// A duration has a single observer: rep count() const; which returns the stored</font>
  290. <font color="#c80000">// representation which holds the number of elapsed "ticks".</font>
  291. <font color="#c80000">// </font>
  292. <font color="#c80000">// A duration supports the following member arithmetic:</font>
  293. <font color="#c80000">// </font>
  294. <font color="#c80000">// duration operator+() const;</font>
  295. <font color="#c80000">// duration operator-() const;</font>
  296. <font color="#c80000">// duration&amp; operator++();</font>
  297. <font color="#c80000">// duration operator++(int);</font>
  298. <font color="#c80000">// duration&amp; operator--();</font>
  299. <font color="#c80000">// duration operator--(int);</font>
  300. <font color="#c80000">// </font>
  301. <font color="#c80000">// duration&amp; operator+=(duration d);</font>
  302. <font color="#c80000">// duration&amp; operator-=(duration d);</font>
  303. <font color="#c80000">// </font>
  304. <font color="#c80000">// duration&amp; operator*=(rep rhs);</font>
  305. <font color="#c80000">// duration&amp; operator/=(rep rhs);</font>
  306. <font color="#c80000">//</font>
  307. <font color="#c80000">// The arithmetic simply manipulates the "tick" count in the obvious way (e.g. operator++</font>
  308. <font color="#c80000">// increments the tick count by 1).</font>
  309. <font color="#c80000">// </font>
  310. <font color="#c80000">// A duration supports the following non-member arithmetic.</font>
  311. <font color="#c80000">// Let D1 represent duration&lt;Rep1, Period1&gt; and D2 represent duration&lt;Rep2, Period2&gt;.</font>
  312. <font color="#c80000">// </font>
  313. <font color="#c80000">// common_type&lt;D1, D2&gt;::type operator+( D1, D2); // returns a duration</font>
  314. <font color="#c80000">// common_type&lt;D1, D2&gt;::type operator-( D1, D2); // returns a duration</font>
  315. <font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*( D1, Rep2); // returns a duration</font>
  316. <font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*(Rep2, D1); // returns a duration</font>
  317. <font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator/( D1, Rep2); // returns a duration</font>
  318. <font color="#c80000">// common_type&lt;D1::rep, D2::rep&gt;::type operator/( D1, D2); // returns a scalar</font>
  319. <font color="#c80000">// </font>
  320. <font color="#c80000">// A duration D1 is fully equality and less-than comparable with any other duration D2, as</font>
  321. <font color="#c80000">// long as common_type&lt;D1::rep, D2::rep&gt; is well defined.</font>
  322. <font color="#c80000">// Example:</font>
  323. <font color="#c80000">// milliseconds ms(3); // ms.count() == 3, which is 0.003 seconds</font>
  324. <font color="#c80000">// microseconds us = ms; // us.count() == 3000 which is 0.003000 seconds</font>
  325. <font color="#c80000">// --us; // us.count() == 2999 which is 0.002999 seconds</font>
  326. <font color="#c80000">// assert(ms != us); // 3 milliseconds is not equal to 2999 microseconds</font>
  327. <font color="#c80000">// assert(ms &gt; us); // 3 milliseconds is greater than 2999 microseconds</font>
  328. <font color="#c80000">// ++us; // us.count() == 3000 which is 0.003000 seconds</font>
  329. <font color="#c80000">// assert(ms == us); // 3 milliseconds is equal to 3000 microseconds</font>
  330. <font color="#c80000">//</font>
  331. <font color="#c80000">// Durations based on floating point representations are subject to round off error precisely the</font>
  332. <font color="#c80000">// same way their representations are.</font>
  333. <font color="#c80000">// </font>
  334. <font color="#c80000">// Arithmetic and comparisons among integral-based durations is not subject to truncation error or</font>
  335. <font color="#c80000">// round off error. If truncation error would result from the arithmetic (say</font>
  336. <font color="#c80000">// by converting a smaller period duration to a larger one) the expression will</font>
  337. <font color="#c80000">// not compile (unless duration_cast is used). If one performs arithmetic</font>
  338. <font color="#c80000">// involving the duration's representation (such as division), then truncation</font>
  339. <font color="#c80000">// will happen implicitly.</font>
  340. <font color="#c80000">// </font>
  341. <font color="#c80000">// Overflow error may silently happen with a duration. The std-defined durations</font>
  342. <font color="#c80000">// have a minimum range of +/- 292 years.</font>
  343. <font color="#c80000">// </font>
  344. <font color="#c80000">// A duration is a thin wrapper around its representation. sizeof(duration&lt;Rep, Period&gt;) == sizeof(Rep).</font>
  345. <font color="#c80000">// </font>
  346. <font color="#c80000">// A duration can represent units as small as 10^-18 seconds (attoseconds) and as large as 10^18 seconds</font>
  347. <font color="#c80000">// (about 30 billion years). The range of a duration is based on the range of its representation</font>
  348. <font color="#c80000">// combined with its period.</font>
  349. <font color="#c80000">// The cost of not including the flexibility to represent different "tick periods" in the duration</font>
  350. <font color="#c80000">// type would be a great loss of both flexibility, convenience and safety for the client. For example</font>
  351. <font color="#c80000">// if had just one duration type which counted nanoseconds (no matter how that count was represented),</font>
  352. <font color="#c80000">// then clients could never have the ability to traffic in picoseconds. And the only hope of reaching</font>
  353. <font color="#c80000">// beyond a +/- 292 year range with nanoseconds is to increase the number of bits in the representation</font>
  354. <font color="#c80000">// (such as a long long). Furthermore, if the client wanted to traffic in units larger than a nanosecond</font>
  355. <font color="#c80000">// (e.g. seconds) for convience, they would likely need to set up their own conversion constants and</font>
  356. <font color="#c80000">// convert manually.</font>
  357. <font color="#c80000">//</font>
  358. <font color="#c80000">// If the conversion constants are specified at run time, rather than as compile time integral constants,</font>
  359. <font color="#c80000">// then the client suffers a significant performance penalty as for every conversion one will have to</font>
  360. <font color="#c80000">// perform both a multiplication and a division. In contrast, when converting among any two units of</font>
  361. <font color="#c80000">// the set (hours, minutes, seconds, milliseconds, microseconds, nanoseconds), there need be only a</font>
  362. <font color="#c80000">// single multiplication *or* division (never both). This proposal makes every unit conversion as</font>
  363. <font color="#c80000">// efficient as if it had been coded by hand (see duration_cast). Furthermore duration_cast encapsulates</font>
  364. <font color="#c80000">// all unit conversions within a single uniform-syntax function which is easily used in generic code. There</font>
  365. <font color="#c80000">// is no need (or motivation) to set up a "hub-and-spoke" conversion regimen, so that the number of conversion</font>
  366. <font color="#c80000">// functions is O(N) rather than O(N^2).</font>
  367. template &lt;class Rep, class Period = ratio&lt;1&gt;&gt;
  368. requires Rep is an arithmetic type, or a class emulating an arithmetic type,
  369. and not an instantiation of duration
  370. requires Period is an instantiation of ratio and represents a positive fraction
  371. class duration
  372. {
  373. public:
  374. typedef Rep rep;
  375. typedef Period period;
  376. private:
  377. rep rep_; <font color="#c80000">// exposition only</font>
  378. public:
  379. <font color="#c80000">// construction / destruction</font>
  380. duration() = default;
  381. template &lt;class Rep2&gt;
  382. requires is_convertible&lt;Rep2, rep&gt;::value &amp;&amp;
  383. (treat_as_floating_point&lt;rep&gt;::value ||
  384. !treat_as_floating_point&lt;rep&gt;::value &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
  385. explicit duration(const Rep2&amp; r);
  386. ~duration() = default;
  387. <font color="#c80000">// copy semantics</font>
  388. duration(const duration&amp;) = default;
  389. duration&amp; operator=(const duration&amp;) = default;
  390. <font color="#c80000">// conversions</font>
  391. template &lt;class Rep2, class Period2&gt;
  392. requires Rep2 is explicitly convertible to rep &amp;&amp;
  393. (treat_as_floating_point&lt;rep&gt;::value ||
  394. !treat_as_floating_point&lt;Rep2&gt;::value &amp;&amp; ratio_divide&lt;Period2, period&gt;::type::den == 1)
  395. duration(const duration&lt;Rep2, Period2&gt;&amp; d);
  396. <font color="#c80000">// observer</font>
  397. rep count() const;
  398. <font color="#c80000">// arithmetic</font>
  399. duration operator+() const;
  400. duration operator-() const;
  401. duration&amp; operator++();
  402. duration operator++(int);
  403. duration&amp; operator--();
  404. duration operator--(int);
  405. duration&amp; operator+=(const duration&amp; d);
  406. duration&amp; operator-=(const duration&amp; d);
  407. duration&amp; operator*=(const rep&amp; rhs);
  408. duration&amp; operator/=(const rep&amp; rhs);
  409. <font color="#c80000">// special values</font>
  410. static constexpr duration zero();
  411. static constexpr duration min();
  412. static constexpr duration max();
  413. };
  414. <font color="#c80000">// convenience typedefs</font>
  415. typedef duration&lt;int_least64_t, nano&gt; nanoseconds; <font color="#c80000">// 10^-9 seconds</font>
  416. typedef duration&lt;int_least55_t, micro&gt; microseconds; <font color="#c80000">// 10^-6 seconds</font>
  417. typedef duration&lt;int_least45_t, milli&gt; milliseconds; <font color="#c80000">// 10^-3 seconds</font>
  418. typedef duration&lt;int_least35_t &gt; seconds; <font color="#c80000">// 1 second</font>
  419. typedef duration&lt;int_least29_t, ratio&lt; 60&gt;&gt; minutes; <font color="#c80000">// 60 seconds</font>
  420. typedef duration&lt;int_least23_t, ratio&lt;3600&gt;&gt; hours; <font color="#c80000">// 3600 seconds</font>
  421. <font color="#c80000">// duration_cast can be used to force a conversion between two durations (assuming</font>
  422. <font color="#c80000">// the source representation can be explicitly converted to the target representation).</font>
  423. <font color="#c80000">// Not all integral-based durations are implicitly convertible to another (to</font>
  424. <font color="#c80000">// avoid accidental truncation error). When truncation error is desired, the client</font>
  425. <font color="#c80000">// uses duration_cast to explicitly request the non-exact conversion. When</font>
  426. <font color="#c80000">// duration_cast is used to convert between durations which have an implicit conversion,</font>
  427. <font color="#c80000">// the behavior and performance of the conversion using duration_cast is identical to</font>
  428. <font color="#c80000">// that of the implicit conversion.</font>
  429. template &lt;class ToDuration, class Rep, class Period&gt;
  430. requires ToDuration is an instantiation of duration
  431. ToDuration duration_cast(const duration&lt;Rep, Period&gt;&amp; fd);
  432. <font color="#c80000">// Examples:</font>
  433. <font color="#c80000">// microseconds us(3500); // 3500 microseconds</font>
  434. <font color="#c80000">// milliseconds ms = us; // Does not compile (implicit truncation)</font>
  435. <font color="#c80000">// milliseconds ms = duration_cast&lt;milliseconds&gt;(us); // 3 milliseconds (explicit truncation)</font>
  436. <font color="#c80000">// us = ms; // 3000 microseconds</font>
  437. <font color="#c80000">// us = duration_cast&lt;microseconds&gt;(ms); // 3000 microseconds</font>
  438. } <font color="#c80000">// datetime</font>
  439. <font color="#c80000">// Given two durations: duration&lt;Rep1, Period1&gt; and duration&lt;Rep2, Period2&gt;, the common_type</font>
  440. <font color="#c80000">// of those two durations is a duration with a representation of common_type&lt;Rep1, Rep2&gt;,</font>
  441. <font color="#c80000">// and a period which is the "greatest common period" of Period1 and Period2. The GCP</font>
  442. <font color="#c80000">// (Greatest Common Period) of Period1 and Period2 is the largest period which will divide</font>
  443. <font color="#c80000">// both Period1 and Period2 evenly (and is often equivalent to the minimum of Period1 and</font>
  444. <font color="#c80000">// Period2). This can be computed (by the implementation at compile time) by</font>
  445. <font color="#c80000">// GCD(Period1::num, Period2::num) / LCM(Period1::den, Period2::den) where GCD is</font>
  446. <font color="#c80000">// "Greatest Common Divisor" and LCM is "Least Common Multiple".</font>
  447. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  448. struct common_type&lt;datetime::duration&lt;Rep1, Period1&gt;, datetime::duration&lt;Rep2, Period2&gt; &gt;
  449. {
  450. typedef datetime::duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type,
  451. ratio&lt;GCD(Period1::num, Period2::num), LCM(Period1::den, Period2::den)&gt;&gt; type;
  452. };
  453. <font color="#c80000">// Note: For any two durations D1 and D2, they will both exactly convert to common_type&lt;D1, D2&gt;::type.</font>
  454. <font color="#c80000">// common_type&lt;D1, D2&gt;::type will have the largest possible period to make this possible, and</font>
  455. <font color="#c80000">// may be the same type as D1 or D2. Examples:</font>
  456. <font color="#c80000">// common_type&lt;minutes, microseconds&gt;::type is microseconds.</font>
  457. <font color="#c80000">// common_type&lt;milliseconds, microseconds&gt;::type is microseconds.</font>
  458. <font color="#c80000">// common_type&lt;nanoseconds, microseconds&gt;::type is nanoseconds.</font>
  459. <font color="#c80000">//</font>
  460. <font color="#c80000">// A more complex example:</font>
  461. <font color="#c80000">// common_type&lt; duration&lt;long, milli&gt;, duration&lt;int, ratio&lt;1,30&gt;&gt; &gt;::type is</font>
  462. <font color="#c80000">// duration&lt;long, ratio&lt;1,3000&gt;&gt;. And both duration&lt;long, milli&gt; and </font>
  463. <font color="#c80000">// duration&lt;int, ratio&lt;1,30&gt;&gt; will exactly convert to duration&lt;long, ratio&lt;1,3000&gt;&gt;.</font>
  464. <font color="#c80000">// The former multitplies its representation by 3L and the latter converts its</font>
  465. <font color="#c80000">// representation to long and multiplies that result by 1000L. There exists no</font>
  466. <font color="#c80000">// duration with a larger period such that both duration&lt;long, milli&gt; and</font>
  467. <font color="#c80000">// duration&lt;int, ratio&lt;1,30&gt;&gt; will exactly convert to it.</font>
  468. namespace datetime {
  469. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  470. bool operator==(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  471. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  472. bool operator!=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  473. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  474. bool operator&lt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  475. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  476. bool operator&lt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  477. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  478. bool operator&gt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  479. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  480. bool operator&gt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  481. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  482. typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
  483. operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  484. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  485. typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
  486. operator-(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  487. template &lt;class Rep1, class Period, class Rep2&gt;
  488. requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
  489. Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
  490. duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  491. operator*(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s);
  492. template &lt;class Rep1, class Period, class Rep2&gt;
  493. requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
  494. Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
  495. duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  496. operator*(const Rep2&amp; s, const duration&lt;Rep, Period&gt;&amp; d);
  497. template &lt;class Rep1, class Period, class Rep2&gt;
  498. requires Rep2 is not a duration &amp;&amp;
  499. Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
  500. Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
  501. duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  502. operator/(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s);
  503. <font color="#c80000">// Note: the above 3 signatures can be approximated with is_convertible if concepts do not</font>
  504. <font color="#c80000">// make it into the language. Requiring only *explicit* convertibility between the Rep</font>
  505. <font color="#c80000">// types is strongly desired. One way or another, Rep2 must be constrained. Otherwise</font>
  506. <font color="#c80000">// the operators are overly generic.</font>
  507. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  508. typename common_type&lt;Rep1, Rep2&gt;::type
  509. operator/(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  510. <font color="#c80000">// time_point</font>
  511. <font color="#c80000">// A time_point represents an epoch plus or minus a duration. The relationship between a time_point</font>
  512. <font color="#c80000">// which represents "now" and the time_point's epoch is obtained via a clock. Each time_point is</font>
  513. <font color="#c80000">// tied to a specific clock. Thus, for any time_point, one can find the duration between that</font>
  514. <font color="#c80000">// point in time and now, and between that point in time, and its epoch.</font>
  515. <font color="#c80000">// </font>
  516. <font color="#c80000">// A time_point may be default constructed. This time_point represents the epoch. time_point has</font>
  517. <font color="#c80000">// default copy semantics.</font>
  518. <font color="#c80000">// </font>
  519. <font color="#c80000">// time_point may be explicitly constructed by a duration having the same representation and period as</font>
  520. <font color="#c80000">// the time_point. Any other duration which is implicitly convertible to the time_point's "native" duration can</font>
  521. <font color="#c80000">// also be used to explicitly construct the time_point. The meaning of this construction is identical to</font>
  522. <font color="#c80000">// time_point() + d.</font>
  523. <font color="#c80000">//</font>
  524. <font color="#c80000">// A time_point is implicitly constructible from another time_point if they share the same clock,</font>
  525. <font color="#c80000">// and the duration of this time_point is implicitly constructible from the duration of the other</font>
  526. <font color="#c80000">// time_point. A time_point constructed in this fashion will compare equal to the source time_point</font>
  527. <font color="#c80000">// after the construction.</font>
  528. <font color="#c80000">// </font>
  529. <font color="#c80000">// A time_point supports the following member arithmetic:</font>
  530. <font color="#c80000">// </font>
  531. <font color="#c80000">// time_point&amp; operator+=(duration d);</font>
  532. <font color="#c80000">// time_point&amp; operator-=(duration d);</font>
  533. <font color="#c80000">// </font>
  534. <font color="#c80000">// A time_point supports the following non-member arithmetic.</font>
  535. <font color="#c80000">// Let T1 represent time_point&lt;Clock, Duration1&gt;,</font>
  536. <font color="#c80000">// T2 represent time_point&lt;Clock, Duration2&gt;,</font>
  537. <font color="#c80000">// and D represent duration&lt;Rep3, Period3&gt;. Note that T1 and T2 must have the same Clock.</font>
  538. <font color="#c80000">// Attempts to interoperate times having different clocks results in a compile time failure.</font>
  539. <font color="#c80000">// </font>
  540. <font color="#c80000">// T2 operator+(T1, D); // return type is a time_point</font>
  541. <font color="#c80000">// T2 operator+( D, T1); // return type is a time_point</font>
  542. <font color="#c80000">// T2 operator-(T1, D); // return type is a time_point</font>
  543. <font color="#c80000">// D operator-(T1, T2); // return type is a duration</font>
  544. <font color="#c80000">// </font>
  545. <font color="#c80000">// A time_point T1 is fully equality and less-than comparable with any other time_point T2 which</font>
  546. <font color="#c80000">// has the same clock, and for which their durations are comparable.</font>
  547. <font color="#c80000">// </font>
  548. <font color="#c80000">// Times based on floating point representations are subject to round off error precisely the</font>
  549. <font color="#c80000">// same way their representations are.</font>
  550. <font color="#c80000">// </font>
  551. <font color="#c80000">// Times based on integral representations are not subject to truncation error or round off</font>
  552. <font color="#c80000">// error. A compile time error will result if truncation error is possible. Truncation error</font>
  553. <font color="#c80000">// is only possible with construction or the member arithmetic (and won't compile). Non-member</font>
  554. <font color="#c80000">// arithmetic and comparison is always exact. Overflow error with integral based times remains a</font>
  555. <font color="#c80000">// possibility.</font>
  556. <font color="#c80000">// </font>
  557. <font color="#c80000">// A time_point is a thin wrapper around its representation.</font>
  558. <font color="#c80000">// sizeof(time_point&lt;Clock, Duration&gt;) == sizeof(Duration) == sizeof(Duration::rep).</font>
  559. <font color="#c80000">// </font>
  560. <font color="#c80000">// A time_point can represent units as small as 10^-18 seconds and as large as 10^18 seconds. The range</font>
  561. <font color="#c80000">// of a time_point is based on the range of its representation combined with its period.</font>
  562. <font color="#c80000">//</font>
  563. <font color="#c80000">// Because no two clocks report the exact same time, even clocks which nominally have the same</font>
  564. <font color="#c80000">// epoch, are considered by this framework to have different epochs, if only by a few nanoseconds.</font>
  565. <font color="#c80000">// Converting time_points from one clock to another will involve synchronization of the clocks,</font>
  566. <font color="#c80000">// which can be viewed as a synchronization of their epochs. Such synchronization is clock specific</font>
  567. <font color="#c80000">// and beyond the scope of this API. A future API, or a platform specific API, can easily</font>
  568. <font color="#c80000">// write such a synchronization API, basing it on this API.</font>
  569. <font color="#c80000">// The cost of not including a time_point class is the lack of the ability to safely interact with</font>
  570. <font color="#c80000">// the concept of "epoch + duration". Without a separate type, the client is in danger of accidently</font>
  571. <font color="#c80000">// writing code that boils down to "epoch1 + duration1" + "epoch2 + duration2". Algebraically this</font>
  572. <font color="#c80000">// results in epoch1+epoch2 as a subexpression which is likely to be completely without meaning. What</font>
  573. <font color="#c80000">// would it mean to add New Years 1970 to the point in time at which your computer booted up? Or for</font>
  574. <font color="#c80000">// that matter, what is the meaning of "New Years 1970" + "New Years 1970"?</font>
  575. <font color="#c80000">//</font>
  576. <font color="#c80000">// Additionally this would force the duration type to play double duty as a time_point leading to</font>
  577. <font color="#c80000">// client confusion. For example POSIX has timespec represent a duration in nanosleep, and yet the</font>
  578. <font color="#c80000">// same type is used as a time_point in pthread_cond_timedwait and pthread_mutex_timedlock. The</font>
  579. <font color="#c80000">// confusion seems even more likely with a function such as clock_nanosleep where timespec can mean</font>
  580. <font color="#c80000">// either a duration or a time_point depending upon another argument to the function.</font>
  581. <font color="#c80000">//</font>
  582. <font color="#c80000">// In C++ we can easily mitigate such errors by detecting them at compile time. This is done through</font>
  583. <font color="#c80000">// the use of distinct types for these distinct concepts (even though both types have identical layout!).</font>
  584. template &lt;class Clock, class Duration = typename Clock::duration&gt;
  585. requires Duration is an instantiation of duration
  586. class time_point
  587. {
  588. public:
  589. typedef Clock clock;
  590. typedef Duration duration;
  591. typedef typename duration::rep rep;
  592. typedef typename duration::period period;
  593. private:
  594. duration d_; <font color="#c80000">// exposition only</font>
  595. public:
  596. time_point(); <font color="#c80000">// has value "epoch"</font>
  597. explicit time_point(const duration&amp; d); <font color="#c80000">// same as time_point() + d</font>
  598. <font color="#c80000">// conversions</font>
  599. template &lt;class Duration2&gt;
  600. requires Convertible&lt;Duration2, duration&gt;
  601. time_point(const time_point&lt;clock, Duration2&gt;&amp; t);
  602. <font color="#c80000">// observer</font>
  603. duration time_since_epoch() const;
  604. <font color="#c80000">// arithmetic</font>
  605. time_point&amp; operator+=(const duration&amp; d);
  606. time_point&amp; operator-=(const duration&amp; d);
  607. <font color="#c80000">// special values</font>
  608. static time_point min();
  609. static time_point max();
  610. };
  611. } <font color="#c80000">// datetime</font>
  612. template &lt;class Clock, class Duration1, class Duration2&gt;
  613. struct common_type&lt;datetime::time_point&lt;Clock, Duration1&gt;, datetime::time_point&lt;Clock, Duration2&gt; &gt;
  614. {
  615. typedef datetime::time_point&lt;Clock, typename common_type&lt;Duration1, Duration2&gt;::type&gt; type;
  616. };
  617. namespace datetime {
  618. template &lt;class ToDuration, class Clock, class Duration&gt;
  619. time_point&lt;Clock, ToDuration&gt; time_point_cast(const time_point&lt;Clock, Duration&gt;&amp; t);
  620. template &lt;class Clock, class Duration1, class Duration2&gt;
  621. bool operator==(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  622. template &lt;class Clock, class Duration1, class Duration2&gt;
  623. bool operator!=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  624. template &lt;class Clock, class Duration1, class Duration2&gt;
  625. bool operator&lt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  626. template &lt;class Clock, class Duration1, class Duration2&gt;
  627. bool operator&lt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  628. template &lt;class Clock, class Duration1, class Duration2&gt;
  629. bool operator&gt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  630. template &lt;class Clock, class Duration1, class Duration2&gt;
  631. bool operator&gt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  632. template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
  633. time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
  634. operator+(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  635. template &lt;class Rep1, class Period1, class Clock, class Duration2&gt;
  636. time_point&lt;Clock, typename common_type&lt;duration&lt;Rep1, Period1&gt;, Duration2&gt;::type&gt;
  637. operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  638. template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
  639. time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
  640. operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
  641. template &lt;class Clock, class Duration1, class Duration2&gt;
  642. typename common_type&lt;Duration1, Duration2&gt;::type
  643. operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
  644. <font color="#c80000">// clocks</font>
  645. <font color="#c80000">// A clock specifies a representation, and a period. These specifications are used to</font>
  646. <font color="#c80000">// to define a clock's native duration and time_point types. A clock also has a function to get the current</font>
  647. <font color="#c80000">// time_point. A clock need not have any state.</font>
  648. <font color="#c80000">// The cost of not including separate types for clocks is that there is no better place to</font>
  649. <font color="#c80000">// bundle the "native" duration and time_point types for a clock with the functionality to</font>
  650. <font color="#c80000">// get the current time_point (what time is it now?). By bundling this information into a</font>
  651. <font color="#c80000">// type, the extension to support multiple clocks is both easy and obvious. The ability to</font>
  652. <font color="#c80000">// easily support multiple clocks in such a flexible yet simple and efficient manner is</font>
  653. <font color="#c80000">// very important. A client might (for example) write code with the clock as a generic</font>
  654. <font color="#c80000">// template parameter, and then easily experiment with different timers.</font>
  655. class system_clock
  656. {
  657. public:
  658. typedef &lt;unspecified&gt; rep;
  659. typedef ratio&lt;unspecified, unspecified&gt; period;
  660. typedef datetime::duration&lt;rep, period&gt; duration;
  661. typedef datetime::time_point&lt;system_clock&gt; time_point;
  662. static const bool is_mononontic = &lt;unspecified&gt;;
  663. static time_point now();
  664. <font color="#c80000">// Map to C API</font>
  665. static time_t to_time_t (const time_point&amp; t);
  666. static time_point from_time_t(time_t t);
  667. };
  668. class monotonic_clock <font color="#c80000">// optional</font>
  669. {
  670. public:
  671. typedef &lt;unspecified&gt; rep;
  672. typedef ratio&lt;unspecified, unspecified&gt; period;
  673. typedef datetime::duration&lt;rep, period&gt; duration;
  674. typedef datetime::time_point&lt;monotonic_clock&gt; time_point;
  675. static const bool is_mononontic = true;
  676. static time_point now();
  677. };
  678. class high_resolution_clock <font color="#c80000">// optional</font>
  679. {
  680. public:
  681. typedef &lt;unspecified&gt; rep;
  682. typedef ratio&lt;unspecified, unspecified&gt; period;
  683. typedef datetime::duration&lt;rep, period&gt; duration;
  684. typedef datetime::time_point&lt;high_resolution_clock&gt; time_point;
  685. static const bool is_mononontic = &lt;unspecified&gt;;
  686. static time_point now();
  687. };
  688. <font color="#c80000">// Note: These clocks may be three separate types, or typedefs to one or two common types.</font>
  689. } <font color="#c80000">// datetime</font>
  690. <font color="#c80000">//////////////////////////</font>
  691. <font color="#c80000">// Threading interface //</font>
  692. <font color="#c80000">//////////////////////////</font>
  693. <font color="#c80000">// timed_mutex</font>
  694. struct timed_mutex
  695. {
  696. public:
  697. timed_mutex();
  698. ~timed_mutex();
  699. timed_mutex(const timed_mutex&amp;) = delete;
  700. timed_mutex&amp; operator=(const timed_mutex&amp;) = delete;
  701. void lock();
  702. bool try_lock();
  703. template &lt;class Rep, class Period&gt;
  704. bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
  705. template &lt;class Clock, class Duration&gt;
  706. bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
  707. void unlock();
  708. typedef unspecified native_handle_type; <font color="#c80000">// optional. example: pthread_mutex_t*</font>
  709. native_handle_type native_handle(); <font color="#c80000">// optional</font>
  710. };
  711. <font color="#c80000">// recursive_timed_mutex</font>
  712. struct recursive_timed_mutex
  713. {
  714. public:
  715. recursive_timed_mutex();
  716. ~recursive_timed_mutex();
  717. recursive_timed_mutex(const recursive_timed_mutex&amp;) = delete;
  718. recursive_timed_mutex&amp; operator=(const recursive_timed_mutex&amp;) = delete;
  719. void lock();
  720. bool try_lock();
  721. template &lt;class Rep, class Period&gt;
  722. bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
  723. template &lt;class Clock, class Duration&gt;
  724. bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
  725. void unlock();
  726. typedef unspecified native_handle_type; <font color="#c80000">// optional. example: pthread_mutex_t*</font>
  727. native_handle_type native_handle(); <font color="#c80000">// optional</font>
  728. };
  729. <font color="#c80000">// unique_lock</font>
  730. template &lt;class Mutex&gt;
  731. class unique_lock
  732. {
  733. public:
  734. typedef Mutex mutex_type;
  735. unique_lock();
  736. explicit unique_lock(mutex_type&amp; m);
  737. unique_lock(mutex_type&amp; m, defer_lock_t);
  738. unique_lock(mutex_type&amp; m, try_to_lock_t);
  739. unique_lock(mutex_type&amp; m, adopt_lock_t);
  740. template &lt;class Rep, class Period&gt;
  741. unique_lock(mutex_type&amp; m, const datetime::duration&lt;Rep, Period&gt;&amp; rel_t);
  742. template &lt;class Clock, class Duration&gt;
  743. unique_lock(mutex_type&amp; m, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
  744. ~unique_lock();
  745. unique_lock(unique_lock const&amp;) = delete;
  746. unique_lock&amp; operator=(unique_lock const&amp;) = delete;
  747. unique_lock(unique_lock&amp;&amp; u);
  748. unique_lock&amp; operator=(unique_lock&amp;&amp; u);
  749. void lock();
  750. bool try_lock();
  751. template &lt;class Rep, class Period&gt;
  752. bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_t);
  753. template &lt;class Clock, class Duration&gt;
  754. bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
  755. void unlock();
  756. bool owns_lock() const;
  757. operator unspecified-bool-type () const;
  758. mutex_type* mutex() const;
  759. void swap(unique_lock&amp;&amp; u);
  760. mutex_type* release();
  761. };
  762. <font color="#c80000">// condition_variable</font>
  763. class condition_variable
  764. {
  765. public:
  766. condition_variable();
  767. ~condition_variable();
  768. condition_variable(const condition_variable&amp;) = delete;
  769. condition_variable&amp; operator=(const condition_variable&amp;) = delete;
  770. void notify_one();
  771. void notify_all();
  772. void wait(unique_lock&lt;mutex&gt;&amp; lock);
  773. template &lt;class Predicate&gt;
  774. void wait(unique_lock&lt;mutex&gt;&amp; lock, Predicate pred);
  775. template &lt;class Clock, class Duration&gt;
  776. bool wait_until(unique_lock&lt;mutex&gt;&amp; lock,
  777. const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
  778. template &lt;class Clock, class Duration, class Predicate&gt;
  779. bool wait_until(unique_lock&lt;mutex&gt;&amp; lock,
  780. const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time,
  781. Predicate pred);
  782. template &lt;class Rep, class Period&gt;
  783. bool wait_for(unique_lock&lt;mutex&gt;&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
  784. template &lt;class Rep, class Period, class Predicate&gt;
  785. bool wait_for(unique_lock&lt;mutex&gt;&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time,
  786. Predicate pred);
  787. typedef pthread_cond_t* native_handle_type;
  788. native_handle_type native_handle();
  789. };
  790. <font color="#c80000">// condition_variable_any</font>
  791. class condition_variable_any
  792. {
  793. public:
  794. condition_variable_any();
  795. ~condition_variable_any();
  796. condition_variable_any(const condition_variable_any&amp;) = delete;
  797. condition_variable_any&amp; operator=(const condition_variable_any&amp;) = delete;
  798. void notify_one();
  799. void notify_all();
  800. template &lt;class Lock&gt;
  801. void wait(Lock&amp; lock);
  802. template &lt;class Lock, class Predicate&gt;
  803. void wait(Lock&amp; lock, Predicate pred);
  804. template &lt;class Lock, class Clock, class Duration&gt;
  805. bool wait_until(Lock&amp; lock, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
  806. template &lt;class Lock, class Clock, class Duration, class Predicate&gt;
  807. bool wait_until(Lock&amp; lock, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time,
  808. Predicate pred);
  809. template &lt;class Lock, class Rep, class Period&gt;
  810. bool wait_for(Lock&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
  811. template &lt;class Lock, class Rep, class Period, class Predicate&gt;
  812. bool wait_for(Lock&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time, Predicate pred);
  813. };
  814. <font color="#c80000">// sleep</font>
  815. namespace this_thread
  816. {
  817. template &lt;class Rep, class Period&gt;
  818. void sleep_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
  819. template &lt;class Clock, class Duration&gt;
  820. void sleep_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
  821. } <font color="#c80000">// this_thread</font>
  822. } <font color="#c80000">// std</font>
  823. */</font>
  824. #include &lt;ctime&gt;
  825. #include &lt;climits&gt;
  826. #include &lt;inttypes.h&gt;
  827. #include &lt;limits&gt;
  828. #include "type_traits"
  829. #define decltype __typeof__
  830. namespace std
  831. {
  832. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  833. <font color="#c80000">////////////////////// common_type ///////////////////////</font>
  834. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  835. #define VARIADIC_COMMON_TYPE 0
  836. #if VARIADIC_COMMON_TYPE == 0
  837. template &lt;class T, class U&gt;
  838. struct common_type
  839. {
  840. private:
  841. static T t();
  842. static U u();
  843. public:
  844. typedef decltype(true ? t() : u()) type;
  845. };
  846. #else
  847. template &lt;class ...T&gt; struct common_type;
  848. template &lt;class T&gt;
  849. struct common_type&lt;T&gt;
  850. {
  851. typedef T type;
  852. };
  853. template &lt;class T, class U&gt;
  854. struct common_type&lt;T, U&gt;
  855. {
  856. private:
  857. static T t();
  858. static U u();
  859. public:
  860. typedef decltype(true ? t() : u()) type;
  861. };
  862. template &lt;class T, class U, class ...V&gt;
  863. struct common_type&lt;T, U, V...&gt;
  864. {
  865. typedef typename common_type&lt;typename common_type&lt;T, U&gt;::type, V...&gt;::type type;
  866. };
  867. #endif
  868. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  869. <font color="#c80000">/////////////////////// ratio ////////////////////////////</font>
  870. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  871. <font color="#c80000">// __static_gcd</font>
  872. template &lt;intmax_t X, intmax_t Y&gt;
  873. struct __static_gcd
  874. {
  875. static const intmax_t value = __static_gcd&lt;Y, X % Y&gt;::value;
  876. };
  877. template &lt;intmax_t X&gt;
  878. struct __static_gcd&lt;X, 0&gt;
  879. {
  880. static const intmax_t value = X;
  881. };
  882. <font color="#c80000">// __static_lcm</font>
  883. template &lt;intmax_t X, intmax_t Y&gt;
  884. struct __static_lcm
  885. {
  886. static const intmax_t value = X / __static_gcd&lt;X, Y&gt;::value * Y;
  887. };
  888. template &lt;intmax_t X&gt;
  889. struct __static_abs
  890. {
  891. static const intmax_t value = X &lt; 0 ? -X : X;
  892. };
  893. template &lt;intmax_t X&gt;
  894. struct __static_sign
  895. {
  896. static const intmax_t value = X == 0 ? 0 : (X &lt; 0 ? -1 : 1);
  897. };
  898. template &lt;intmax_t X, intmax_t Y, intmax_t = __static_sign&lt;Y&gt;::value&gt;
  899. class __ll_add;
  900. template &lt;intmax_t X, intmax_t Y&gt;
  901. class __ll_add&lt;X, Y, 1&gt;
  902. {
  903. static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
  904. static const intmax_t max = -min;
  905. static char test[X &lt;= max - Y];
  906. <font color="#c80000">// static_assert(X &lt;= max - Y, "overflow in __ll_add");</font>
  907. public:
  908. static const intmax_t value = X + Y;
  909. };
  910. template &lt;intmax_t X, intmax_t Y&gt;
  911. class __ll_add&lt;X, Y, 0&gt;
  912. {
  913. public:
  914. static const intmax_t value = X;
  915. };
  916. template &lt;intmax_t X, intmax_t Y&gt;
  917. class __ll_add&lt;X, Y, -1&gt;
  918. {
  919. static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
  920. static const intmax_t max = -min;
  921. static char test[min - Y &lt;= X];
  922. <font color="#c80000">// static_assert(min - Y &lt;= X, "overflow in __ll_add");</font>
  923. public:
  924. static const intmax_t value = X + Y;
  925. };
  926. template &lt;intmax_t X, intmax_t Y, intmax_t = __static_sign&lt;Y&gt;::value&gt;
  927. class __ll_sub;
  928. template &lt;intmax_t X, intmax_t Y&gt;
  929. class __ll_sub&lt;X, Y, 1&gt;
  930. {
  931. static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
  932. static const intmax_t max = -min;
  933. static char test[min + Y &lt;= X];
  934. <font color="#c80000">// static_assert(min + Y &lt;= X, "overflow in __ll_sub");</font>
  935. public:
  936. static const intmax_t value = X - Y;
  937. };
  938. template &lt;intmax_t X, intmax_t Y&gt;
  939. class __ll_sub&lt;X, Y, 0&gt;
  940. {
  941. public:
  942. static const intmax_t value = X;
  943. };
  944. template &lt;intmax_t X, intmax_t Y&gt;
  945. class __ll_sub&lt;X, Y, -1&gt;
  946. {
  947. static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
  948. static const intmax_t max = -min;
  949. static char test[X &lt;= max + Y];
  950. <font color="#c80000">// static_assert(X &lt;= max + Y, "overflow in __ll_sub");</font>
  951. public:
  952. static const intmax_t value = X - Y;
  953. };
  954. template &lt;intmax_t X, intmax_t Y&gt;
  955. class __ll_mul
  956. {
  957. static const intmax_t nan = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1));
  958. static const intmax_t min = nan + 1;
  959. static const intmax_t max = -min;
  960. static const intmax_t __a_x = __static_abs&lt;X&gt;::value;
  961. static const intmax_t __a_y = __static_abs&lt;Y&gt;::value;
  962. static char test1[X != nan];
  963. static char test2[Y != nan];
  964. static char test[__a_x &lt;= max / __a_y];
  965. <font color="#c80000">// static_assert(X != nan &amp;&amp; Y != nan &amp;&amp; __a_x &lt;= max / __a_y, "overflow in __ll_mul");</font>
  966. public:
  967. static const intmax_t value = X * Y;
  968. };
  969. template &lt;intmax_t Y&gt;
  970. class __ll_mul&lt;0, Y&gt;
  971. {
  972. public:
  973. static const intmax_t value = 0;
  974. };
  975. template &lt;intmax_t X&gt;
  976. class __ll_mul&lt;X, 0&gt;
  977. {
  978. public:
  979. static const intmax_t value = 0;
  980. };
  981. template &lt;&gt;
  982. class __ll_mul&lt;0, 0&gt;
  983. {
  984. public:
  985. static const intmax_t value = 0;
  986. };
  987. <font color="#c80000">// Not actually used but left here in case needed in future maintenance</font>
  988. template &lt;intmax_t X, intmax_t Y&gt;
  989. class __ll_div
  990. {
  991. static const intmax_t nan = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1));
  992. static const intmax_t min = nan + 1;
  993. static const intmax_t max = -min;
  994. static char test1[X != nan];
  995. static char test2[Y != nan];
  996. static char test3[Y != 0];
  997. <font color="#c80000">// static_assert(X != nan &amp;&amp; Y != nan &amp;&amp; Y != 0, "overflow in __ll_div");</font>
  998. public:
  999. static const intmax_t value = X / Y;
  1000. };
  1001. template &lt;intmax_t N, intmax_t D = 1&gt;
  1002. class ratio
  1003. {
  1004. static char test1[__static_abs&lt;N&gt;::value &gt;= 0];
  1005. static char test2[__static_abs&lt;D&gt;::value &gt; 0];
  1006. <font color="#c80000">// static_assert(__static_abs&lt;N&gt;::value &gt;= 0, "ratio numerator is out of range");</font>
  1007. <font color="#c80000">// static_assert(D != 0, "ratio divide by 0");</font>
  1008. <font color="#c80000">// static_assert(__static_abs&lt;D&gt;::value &gt; 0, "ratio denominator is out of range");</font>
  1009. static const intmax_t __na = __static_abs&lt;N&gt;::value;
  1010. static const intmax_t __da = __static_abs&lt;D&gt;::value;
  1011. static const intmax_t __s = __static_sign&lt;N&gt;::value * __static_sign&lt;D&gt;::value;
  1012. static const intmax_t __gcd = __static_gcd&lt;__na, __da&gt;::value;
  1013. public:
  1014. static const intmax_t num = __s * __na / __gcd;
  1015. static const intmax_t den = __da / __gcd;
  1016. };
  1017. template &lt;class T&gt; struct ___is_ratio : tmp::false_type {};
  1018. template &lt;intmax_t N, intmax_t D&gt; struct ___is_ratio&lt;ratio&lt;N, D&gt; &gt; : tmp::true_type {};
  1019. template &lt;class T&gt; struct __is_ratio : ___is_ratio&lt;typename tmp::remove_cv&lt;T&gt;::type&gt; {};
  1020. typedef ratio&lt;1LL, 1000000000000000000LL&gt; atto;
  1021. typedef ratio&lt;1LL, 1000000000000000LL&gt; femto;
  1022. typedef ratio&lt;1LL, 1000000000000LL&gt; pico;
  1023. typedef ratio&lt;1LL, 1000000000LL&gt; nano;
  1024. typedef ratio&lt;1LL, 1000000LL&gt; micro;
  1025. typedef ratio&lt;1LL, 1000LL&gt; milli;
  1026. typedef ratio&lt;1LL, 100LL&gt; centi;
  1027. typedef ratio&lt;1LL, 10LL&gt; deci;
  1028. typedef ratio&lt; 10LL, 1LL&gt; deca;
  1029. typedef ratio&lt; 100LL, 1LL&gt; hecto;
  1030. typedef ratio&lt; 1000LL, 1LL&gt; kilo;
  1031. typedef ratio&lt; 1000000LL, 1LL&gt; mega;
  1032. typedef ratio&lt; 1000000000LL, 1LL&gt; giga;
  1033. typedef ratio&lt; 1000000000000LL, 1LL&gt; tera;
  1034. typedef ratio&lt; 1000000000000000LL, 1LL&gt; peta;
  1035. typedef ratio&lt;1000000000000000000LL, 1LL&gt; exa;
  1036. template &lt;class R1, class R2&gt;
  1037. struct ratio_add
  1038. {
  1039. typedef ratio&lt;__ll_add&lt;__ll_mul&lt;R1::num, R2::den&gt;::value,
  1040. __ll_mul&lt;R1::den, R2::num&gt;::value&gt;::value,
  1041. __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
  1042. };
  1043. template &lt;class R1, class R2&gt;
  1044. struct ratio_subtract
  1045. {
  1046. typedef ratio&lt;__ll_sub&lt;__ll_mul&lt;R1::num, R2::den&gt;::value,
  1047. __ll_mul&lt;R1::den, R2::num&gt;::value&gt;::value,
  1048. __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
  1049. };
  1050. template &lt;class R1, class R2&gt;
  1051. struct ratio_multiply
  1052. {
  1053. typedef ratio&lt;__ll_mul&lt;R1::num, R2::num&gt;::value, __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
  1054. };
  1055. template &lt;class R1, class R2&gt;
  1056. struct ratio_divide
  1057. {
  1058. typedef ratio&lt;__ll_mul&lt;R1::num, R2::den&gt;::value, __ll_mul&lt;R1::den, R2::num&gt;::value&gt; type;
  1059. };
  1060. <font color="#c80000">// ratio_equal</font>
  1061. template &lt;class R1, class R2&gt;
  1062. struct ratio_equal
  1063. : public tmp::integral_constant&lt;bool, R1::num == R2::num &amp;&amp; R1::den == R2::den&gt; {};
  1064. template &lt;class R1, class R2&gt;
  1065. struct ratio_not_equal
  1066. : public tmp::integral_constant&lt;bool, !ratio_equal&lt;R1, R2&gt;::value&gt; {};
  1067. <font color="#c80000">// ratio_less</font>
  1068. <font color="#c80000">// Protect against overflow, and still get the right answer as much as possible.</font>
  1069. <font color="#c80000">// This just demonstrates for fun how far you can push things without hitting</font>
  1070. <font color="#c80000">// overflow. The obvious and simple implementation is conforming.</font>
  1071. template &lt;class R1, class R2, bool ok1, bool ok2&gt;
  1072. struct __ratio_less3 <font color="#c80000">// true, true and false, false</font>
  1073. {
  1074. static const bool value = __ll_mul&lt;R1::num, R2::den&gt;::value &lt; __ll_mul&lt;R2::num, R1::den&gt;::value;
  1075. };
  1076. template &lt;class R1, class R2&gt;
  1077. struct __ratio_less3&lt;R1, R2, true, false&gt;
  1078. {
  1079. static const bool value = true;
  1080. };
  1081. template &lt;class R1, class R2&gt;
  1082. struct __ratio_less3&lt;R1, R2, false, true&gt;
  1083. {
  1084. static const bool value = false;
  1085. };
  1086. template &lt;class R1, class R2, bool = R1::num &lt; R1::den == R2::num &lt; R2::den&gt;
  1087. struct __ratio_less2 <font color="#c80000">// N1 &lt; D1 == N2 &lt; D2</font>
  1088. {
  1089. static const intmax_t max = -((1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
  1090. static const bool ok1 = R1::num &lt;= max / R2::den;
  1091. static const bool ok2 = R2::num &lt;= max / R1::den;
  1092. static const bool value = __ratio_less3&lt;R1, R2, ok1, ok2&gt;::value;
  1093. };
  1094. template &lt;class R1, class R2&gt;
  1095. struct __ratio_less2&lt;R1, R2, false&gt; <font color="#c80000">// N1 &lt; D1 != N2 &lt; D2</font>
  1096. {
  1097. static const bool value = R1::num &lt; R1::den;
  1098. };
  1099. template &lt;class R1, class R2, bool = R1::num &lt; R1::den == R2::num &lt; R2::den&gt;
  1100. struct __ratio_less1 <font color="#c80000">// N1 &lt; D1 == N2 &lt; D2</font>
  1101. {
  1102. static const bool value = __ratio_less2&lt;ratio&lt;R1::num, R2::num&gt;, ratio&lt;R1::den, R2::den&gt; &gt;::value;
  1103. };
  1104. template &lt;class R1, class R2&gt;
  1105. struct __ratio_less1&lt;R1, R2, false&gt; <font color="#c80000">// N1 &lt; D1 != N2 &lt; D2</font>
  1106. {
  1107. static const bool value = R1::num &lt; R1::den;
  1108. };
  1109. template &lt;class R1, class R2, intmax_t S1 = __static_sign&lt;R1::num&gt;::value,
  1110. intmax_t S2 = __static_sign&lt;R2::num&gt;::value&gt;
  1111. struct __ratio_less
  1112. {
  1113. static const bool value = S1 &lt; S2;
  1114. };
  1115. template &lt;class R1, class R2&gt;
  1116. struct __ratio_less&lt;R1, R2, 1LL, 1LL&gt;
  1117. {
  1118. static const bool value = __ratio_less1&lt;R1, R2&gt;::value;
  1119. };
  1120. template &lt;class R1, class R2&gt;
  1121. struct __ratio_less&lt;R1, R2, -1LL, -1LL&gt;
  1122. {
  1123. static const bool value = __ratio_less1&lt;ratio&lt;-R2::num, R2::den&gt;, ratio&lt;-R1::num, R1::den&gt; &gt;::value;
  1124. };
  1125. template &lt;class R1, class R2&gt;
  1126. struct ratio_less
  1127. : public tmp::integral_constant&lt;bool, __ratio_less&lt;R1, R2&gt;::value&gt; {};
  1128. template &lt;class R1, class R2&gt;
  1129. struct ratio_less_equal
  1130. : public tmp::integral_constant&lt;bool, !ratio_less&lt;R2, R1&gt;::value&gt; {};
  1131. template &lt;class R1, class R2&gt;
  1132. struct ratio_greater
  1133. : public tmp::integral_constant&lt;bool, ratio_less&lt;R2, R1&gt;::value&gt; {};
  1134. template &lt;class R1, class R2&gt;
  1135. struct ratio_greater_equal
  1136. : public tmp::integral_constant&lt;bool, !ratio_less&lt;R1, R2&gt;::value&gt; {};
  1137. template &lt;class R1, class R2&gt;
  1138. struct __ratio_gcd
  1139. {
  1140. typedef ratio&lt;__static_gcd&lt;R1::num, R2::num&gt;::value,
  1141. __static_lcm&lt;R1::den, R2::den&gt;::value&gt; type;
  1142. };
  1143. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1144. <font color="#c80000">////////////////////// duration //////////////////////////</font>
  1145. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1146. namespace datetime
  1147. {
  1148. template &lt;class RepType, class Period = ratio&lt;1&gt; &gt; class duration;
  1149. template &lt;class T&gt; struct ___is_duration : tmp::false_type {};
  1150. template &lt;class Rep, class Period&gt; struct ___is_duration&lt;duration&lt;Rep, Period&gt; &gt; : tmp::true_type {};
  1151. template &lt;class T&gt; struct __is_duration : ___is_duration&lt;typename tmp::remove_cv&lt;T&gt;::type&gt; {};
  1152. <font color="#c80000">// duration_cast</font>
  1153. <font color="#c80000">// duration_cast is the heart of this whole prototype. It can convert any</font>
  1154. <font color="#c80000">// duration to any other. It is also (implicitly) used in converting</font>
  1155. <font color="#c80000">// time_points. The conversion is always exact if possible. And it is</font>
  1156. <font color="#c80000">// always as efficient as hand written code. If different representations</font>
  1157. <font color="#c80000">// are involved, care is taken to never require implicit conversions.</font>
  1158. <font color="#c80000">// Instead static_cast is used explicitly for every required conversion.</font>
  1159. <font color="#c80000">// If there are a mixture of integral and floating point representations,</font>
  1160. <font color="#c80000">// the use of common_type ensures that the most logical "intermediate"</font>
  1161. <font color="#c80000">// representation is used.</font>
  1162. template &lt;class FromDuration, class ToDuration,
  1163. class Period = typename ratio_divide&lt;typename FromDuration::period, typename ToDuration::period&gt;::type,
  1164. bool = Period::num == 1,
  1165. bool = Period::den == 1&gt;
  1166. struct __duration_cast;
  1167. <font color="#c80000">// When the two periods are the same, all that is left to do is static_cast from</font>
  1168. <font color="#c80000">// the source representation to the target representation (which may be a no-op).</font>
  1169. <font color="#c80000">// This conversion is always exact as long as the static_cast from the source</font>
  1170. <font color="#c80000">// representation to the destination representation is exact.</font>
  1171. template &lt;class FromDuration, class ToDuration, class Period&gt;
  1172. struct __duration_cast&lt;FromDuration, ToDuration, Period, true, true&gt;
  1173. {
  1174. ToDuration operator()(const FromDuration&amp; fd) const
  1175. {
  1176. return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(fd.count()));
  1177. }
  1178. };
  1179. <font color="#c80000">// When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
  1180. <font color="#c80000">// divide by the denominator of FromPeriod / ToPeriod. The common_type of</font>
  1181. <font color="#c80000">// the two representations is used for the intermediate computation before</font>
  1182. <font color="#c80000">// static_cast'ing to the destination.</font>
  1183. <font color="#c80000">// This conversion is generally not exact because of the division (but could be</font>
  1184. <font color="#c80000">// if you get lucky on the run time value of fd.count()).</font>
  1185. template &lt;class FromDuration, class ToDuration, class Period&gt;
  1186. struct __duration_cast&lt;FromDuration, ToDuration, Period, true, false&gt;
  1187. {
  1188. ToDuration operator()(const FromDuration&amp; fd) const
  1189. {
  1190. #if VARIADIC_COMMON_TYPE == 0
  1191. typedef typename common_type&lt;
  1192. typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
  1193. intmax_t&gt;::type C;
  1194. #else
  1195. typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
  1196. #endif
  1197. return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
  1198. static_cast&lt;C&gt;(fd.count()) / static_cast&lt;C&gt;(Period::den)));
  1199. }
  1200. };
  1201. <font color="#c80000">// When the denomenator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
  1202. <font color="#c80000">// multiply by the numerator of FromPeriod / ToPeriod. The common_type of</font>
  1203. <font color="#c80000">// the two representations is used for the intermediate computation before</font>
  1204. <font color="#c80000">// static_cast'ing to the destination.</font>
  1205. <font color="#c80000">// This conversion is always exact as long as the static_cast's involved are exact.</font>
  1206. template &lt;class FromDuration, class ToDuration, class Period&gt;
  1207. struct __duration_cast&lt;FromDuration, ToDuration, Period, false, true&gt;
  1208. {
  1209. ToDuration operator()(const FromDuration&amp; fd) const
  1210. {
  1211. #if VARIADIC_COMMON_TYPE == 0
  1212. typedef typename common_type&lt;
  1213. typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
  1214. intmax_t&gt;::type C;
  1215. #else
  1216. typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
  1217. #endif
  1218. return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
  1219. static_cast&lt;C&gt;(fd.count()) * static_cast&lt;C&gt;(Period::num)));
  1220. }
  1221. };
  1222. <font color="#c80000">// When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to</font>
  1223. <font color="#c80000">// multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The</font>
  1224. <font color="#c80000">// common_type of the two representations is used for the intermediate computation before</font>
  1225. <font color="#c80000">// static_cast'ing to the destination.</font>
  1226. <font color="#c80000">// This conversion is generally not exact because of the division (but could be</font>
  1227. <font color="#c80000">// if you get lucky on the run time value of fd.count()).</font>
  1228. template &lt;class FromDuration, class ToDuration, class Period&gt;
  1229. struct __duration_cast&lt;FromDuration, ToDuration, Period, false, false&gt;
  1230. {
  1231. ToDuration operator()(const FromDuration&amp; fd) const
  1232. {
  1233. #if VARIADIC_COMMON_TYPE == 0
  1234. typedef typename common_type&lt;
  1235. typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
  1236. intmax_t&gt;::type C;
  1237. #else
  1238. typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
  1239. #endif
  1240. return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
  1241. static_cast&lt;C&gt;(fd.count()) * static_cast&lt;C&gt;(Period::num) / static_cast&lt;C&gt;(Period::den)));
  1242. }
  1243. };
  1244. <font color="#c80000">// Compile-time select the most efficient algorithm for the conversion...</font>
  1245. template &lt;class ToDuration, class Rep, class Period&gt;
  1246. inline
  1247. typename tmp::enable_if
  1248. &lt;
  1249. __is_duration&lt;ToDuration&gt;::value,
  1250. ToDuration
  1251. &gt;::type
  1252. duration_cast(const duration&lt;Rep, Period&gt;&amp; fd)
  1253. {
  1254. return __duration_cast&lt;duration&lt;Rep, Period&gt;, ToDuration&gt;()(fd);
  1255. }
  1256. <font color="#c80000">// Support bidirectional (non-exact) conversions for floating point rep types</font>
  1257. <font color="#c80000">// (or user defined rep types which specialize treat_as_floating_point).</font>
  1258. template &lt;class Rep&gt; struct treat_as_floating_point : tmp::is_floating_point&lt;Rep&gt; {};
  1259. template &lt;class Rep&gt;
  1260. struct duration_values
  1261. {
  1262. static Rep __min_imp(tmp::false_type) {return -max();}
  1263. static Rep __min_imp(tmp::true_type) {return zero();}
  1264. public:
  1265. static Rep zero() {return Rep(0);}
  1266. static Rep max() {return numeric_limits&lt;Rep&gt;::max();}
  1267. static Rep min() {return __min_imp(tmp::is_unsigned&lt;Rep&gt;());}
  1268. };
  1269. <font color="#c80000">// duration</font>
  1270. template &lt;class Rep, class Period&gt;
  1271. class duration
  1272. {
  1273. static char test0[!__is_duration&lt;Rep&gt;::value];
  1274. <font color="#c80000">// static_assert(!__is_duration&lt;Rep&gt;::value, "A duration representation can not be a duration");</font>
  1275. static char test1[__is_ratio&lt;Period&gt;::value];
  1276. <font color="#c80000">// static_assert(__is_ratio&lt;Period&gt;::value, "Second template parameter of duration must be a std::ratio");</font>
  1277. static char test2[Period::num &gt; 0];
  1278. <font color="#c80000">// static_assert(Period::num &gt; 0, "duration period must be positive");</font>
  1279. public:
  1280. typedef Rep rep;
  1281. typedef Period period;
  1282. private:
  1283. rep rep_;
  1284. public:
  1285. duration() {} <font color="#c80000">// = default;</font>
  1286. template &lt;class Rep2&gt;
  1287. explicit duration(const Rep2&amp; r,
  1288. typename tmp::enable_if
  1289. &lt;
  1290. tmp::is_convertible&lt;Rep2, rep&gt;::value &amp;&amp;
  1291. (treat_as_floating_point&lt;rep&gt;::value ||
  1292. !treat_as_floating_point&lt;rep&gt;::value &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
  1293. &gt;::type* = 0)
  1294. : rep_(r) {}
  1295. <font color="#c80000">// conversions</font>
  1296. template &lt;class Rep2, class Period2&gt;
  1297. duration(const duration&lt;Rep2, Period2&gt;&amp; d,
  1298. typename tmp::enable_if
  1299. &lt;
  1300. treat_as_floating_point&lt;rep&gt;::value ||
  1301. (ratio_divide&lt;Period2, period&gt;::type::den == 1 &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
  1302. &gt;::type* = 0)
  1303. : rep_(duration_cast&lt;duration&gt;(d).count()) {}
  1304. <font color="#c80000">// observer</font>
  1305. rep count() const {return rep_;}
  1306. <font color="#c80000">// arithmetic</font>
  1307. duration operator+() const {return *this;}
  1308. duration operator-() const {return duration(-rep_);}
  1309. duration&amp; operator++() {++rep_; return *this;}
  1310. duration operator++(int) {return duration(rep_++);}
  1311. duration&amp; operator--() {--rep_; return *this;}
  1312. duration operator--(int) {return duration(rep_--);}
  1313. duration&amp; operator+=(const duration&amp; d) {rep_ += d.count(); return *this;}
  1314. duration&amp; operator-=(const duration&amp; d) {rep_ -= d.count(); return *this;}
  1315. duration&amp; operator*=(const rep&amp; rhs) {rep_ *= rhs; return *this;}
  1316. duration&amp; operator/=(const rep&amp; rhs) {rep_ /= rhs; return *this;}
  1317. <font color="#c80000">// special values</font>
  1318. static duration zero() {return duration(duration_values&lt;rep&gt;::zero());}
  1319. static duration min() {return duration(duration_values&lt;rep&gt;::min());}
  1320. static duration max() {return duration(duration_values&lt;rep&gt;::max());}
  1321. };
  1322. typedef duration&lt;long long, nano&gt; nanoseconds;
  1323. typedef duration&lt;long long, micro&gt; microseconds;
  1324. typedef duration&lt;long long, milli&gt; milliseconds;
  1325. typedef duration&lt;long long &gt; seconds;
  1326. typedef duration&lt; long, ratio&lt; 60&gt; &gt; minutes;
  1327. typedef duration&lt; long, ratio&lt;3600&gt; &gt; hours;
  1328. } <font color="#c80000">// datetime</font>
  1329. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1330. struct common_type&lt;datetime::duration&lt;Rep1, Period1&gt;, datetime::duration&lt;Rep2, Period2&gt; &gt;
  1331. {
  1332. typedef datetime::duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type,
  1333. typename __ratio_gcd&lt;Period1, Period2&gt;::type&gt; type;
  1334. };
  1335. namespace datetime {
  1336. <font color="#c80000">// Duration ==</font>
  1337. template &lt;class LhsDuration, class RhsDuration&gt;
  1338. struct __duration_eq
  1339. {
  1340. bool operator()(const LhsDuration&amp; lhs, const RhsDuration&amp; rhs)
  1341. {
  1342. typedef typename common_type&lt;LhsDuration, RhsDuration&gt;::type CD;
  1343. return CD(lhs).count() == CD(rhs).count();
  1344. }
  1345. };
  1346. template &lt;class LhsDuration&gt;
  1347. struct __duration_eq&lt;LhsDuration, LhsDuration&gt;
  1348. {
  1349. bool operator()(const LhsDuration&amp; lhs, const LhsDuration&amp; rhs)
  1350. {return lhs.count() == rhs.count();}
  1351. };
  1352. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1353. inline
  1354. bool
  1355. operator==(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1356. {
  1357. return __duration_eq&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;()(lhs, rhs);
  1358. }
  1359. <font color="#c80000">// Duration !=</font>
  1360. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1361. inline
  1362. bool
  1363. operator!=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1364. {
  1365. return !(lhs == rhs);
  1366. }
  1367. <font color="#c80000">// Duration &lt;</font>
  1368. template &lt;class LhsDuration, class RhsDuration&gt;
  1369. struct __duration_lt
  1370. {
  1371. bool operator()(const LhsDuration&amp; lhs, const RhsDuration&amp; rhs)
  1372. {
  1373. typedef typename common_type&lt;LhsDuration, RhsDuration&gt;::type CD;
  1374. return CD(lhs).count() &lt; CD(rhs).count();
  1375. }
  1376. };
  1377. template &lt;class LhsDuration&gt;
  1378. struct __duration_lt&lt;LhsDuration, LhsDuration&gt;
  1379. {
  1380. bool operator()(const LhsDuration&amp; lhs, const LhsDuration&amp; rhs)
  1381. {return lhs.count() &lt; rhs.count();}
  1382. };
  1383. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1384. inline
  1385. bool
  1386. operator&lt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1387. {
  1388. return __duration_lt&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;()(lhs, rhs);
  1389. }
  1390. <font color="#c80000">// Duration &gt;</font>
  1391. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1392. inline
  1393. bool
  1394. operator&gt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1395. {
  1396. return rhs &lt; lhs;
  1397. }
  1398. <font color="#c80000">// Duration &lt;=</font>
  1399. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1400. inline
  1401. bool
  1402. operator&lt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1403. {
  1404. return !(rhs &lt; lhs);
  1405. }
  1406. <font color="#c80000">// Duration &gt;=</font>
  1407. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1408. inline
  1409. bool
  1410. operator&gt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1411. {
  1412. return !(lhs &lt; rhs);
  1413. }
  1414. <font color="#c80000">// Duration +</font>
  1415. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1416. inline
  1417. typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
  1418. operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1419. {
  1420. typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type result = lhs;
  1421. result += rhs;
  1422. return result;
  1423. }
  1424. <font color="#c80000">// Duration -</font>
  1425. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1426. inline
  1427. typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
  1428. operator-(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1429. {
  1430. typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type result = lhs;
  1431. result -= rhs;
  1432. return result;
  1433. }
  1434. <font color="#c80000">// Duration *</font>
  1435. template &lt;class Rep1, class Period, class Rep2&gt;
  1436. inline
  1437. typename tmp::enable_if
  1438. &lt;
  1439. tmp::is_convertible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value &amp;&amp;
  1440. tmp::is_convertible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value,
  1441. duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  1442. &gt;::type
  1443. operator*(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s)
  1444. {
  1445. typedef typename common_type&lt;Rep1, Rep2&gt;::type CR;
  1446. duration&lt;CR, Period&gt; r = d;
  1447. r *= static_cast&lt;CR&gt;(s);
  1448. return r;
  1449. }
  1450. template &lt;class Rep1, class Period, class Rep2&gt;
  1451. inline
  1452. typename tmp::enable_if
  1453. &lt;
  1454. tmp::is_convertible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value &amp;&amp;
  1455. tmp::is_convertible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value,
  1456. duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
  1457. &gt;::type
  1458. operator*(const Rep1&amp; s, const duration&lt;Rep2, Period&gt;&amp; d)
  1459. {
  1460. return d * s;
  1461. }
  1462. <font color="#c80000">// Duration /</font>
  1463. template &lt;class Duration, class Rep, bool = __is_duration&lt;Rep&gt;::value&gt;
  1464. struct __duration_divide_result
  1465. {
  1466. };
  1467. template &lt;class Duration, class Rep2,
  1468. bool = tmp::is_convertible&lt;typename Duration::rep,
  1469. typename common_type&lt;typename Duration::rep, Rep2&gt;::type&gt;::value &amp;&amp;
  1470. tmp::is_convertible&lt;Rep2,
  1471. typename common_type&lt;typename Duration::rep, Rep2&gt;::type&gt;::value&gt;
  1472. struct __duration_divide_imp
  1473. {
  1474. };
  1475. template &lt;class Rep1, class Period, class Rep2&gt;
  1476. struct __duration_divide_imp&lt;duration&lt;Rep1, Period&gt;, Rep2, true&gt;
  1477. {
  1478. typedef duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt; type;
  1479. };
  1480. template &lt;class Rep1, class Period, class Rep2&gt;
  1481. struct __duration_divide_result&lt;duration&lt;Rep1, Period&gt;, Rep2, false&gt;
  1482. : __duration_divide_imp&lt;duration&lt;Rep1, Period&gt;, Rep2&gt;
  1483. {
  1484. };
  1485. template &lt;class Rep1, class Period, class Rep2&gt;
  1486. inline
  1487. typename __duration_divide_result&lt;duration&lt;Rep1, Period&gt;, Rep2&gt;::type
  1488. operator/(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s)
  1489. {
  1490. typedef typename common_type&lt;Rep1, Rep2&gt;::type CR;
  1491. duration&lt;CR, Period&gt; r = d;
  1492. r /= static_cast&lt;CR&gt;(s);
  1493. return r;
  1494. }
  1495. template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
  1496. inline
  1497. typename common_type&lt;Rep1, Rep2&gt;::type
  1498. operator/(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1499. {
  1500. typedef typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type CD;
  1501. return CD(lhs).count() / CD(rhs).count();
  1502. }
  1503. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1504. <font color="#c80000">///////////////////// time_point /////////////////////////</font>
  1505. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1506. template &lt;class Clock, class Duration = typename Clock::duration&gt;
  1507. class time_point
  1508. {
  1509. static char test1[__is_duration&lt;Duration&gt;::value];
  1510. <font color="#c80000">// static_assert(__is_duration&lt;Duration&gt;::value,</font>
  1511. <font color="#c80000">// "Second template parameter of time_point must be a std::datetime::duration");</font>
  1512. public:
  1513. typedef Clock clock;
  1514. typedef Duration duration;
  1515. typedef typename duration::rep rep;
  1516. typedef typename duration::period period;
  1517. private:
  1518. duration d_;
  1519. public:
  1520. time_point() : d_(duration::zero()) {}
  1521. explicit time_point(const duration&amp; d) : d_(d) {}
  1522. <font color="#c80000">// conversions</font>
  1523. template &lt;class Duration2&gt;
  1524. time_point(const time_point&lt;clock, Duration2&gt;&amp; t,
  1525. typename tmp::enable_if
  1526. &lt;
  1527. tmp::is_convertible&lt;Duration2, duration&gt;::value
  1528. &gt;::type* = 0)
  1529. : d_(t.time_since_epoch()) {}
  1530. <font color="#c80000">// observer</font>
  1531. duration time_since_epoch() const {return d_;}
  1532. <font color="#c80000">// arithmetic</font>
  1533. time_point&amp; operator+=(const duration&amp; d) {d_ += d; return *this;}
  1534. time_point&amp; operator-=(const duration&amp; d) {d_ -= d; return *this;}
  1535. <font color="#c80000">// special values</font>
  1536. static time_point min() {return time_point(duration::min());}
  1537. static time_point max() {return time_point(duration::max());}
  1538. };
  1539. } <font color="#c80000">// datetime</font>
  1540. template &lt;class Clock, class Duration1, class Duration2&gt;
  1541. struct common_type&lt;datetime::time_point&lt;Clock, Duration1&gt;, datetime::time_point&lt;Clock, Duration2&gt; &gt;
  1542. {
  1543. typedef datetime::time_point&lt;Clock, typename common_type&lt;Duration1, Duration2&gt;::type&gt; type;
  1544. };
  1545. namespace datetime {
  1546. template &lt;class ToDuration, class Clock, class Duration&gt;
  1547. inline
  1548. time_point&lt;Clock, ToDuration&gt;
  1549. time_point_cast(const time_point&lt;Clock, Duration&gt;&amp; t)
  1550. {
  1551. return time_point&lt;Clock, ToDuration&gt;(duration_cast&lt;ToDuration&gt;(t.time_since_epoch()));
  1552. }
  1553. <font color="#c80000">// time_point ==</font>
  1554. template &lt;class Clock, class Duration1, class Duration2&gt;
  1555. inline
  1556. bool
  1557. operator==(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1558. {
  1559. return lhs.time_since_epoch() == rhs.time_since_epoch();
  1560. }
  1561. <font color="#c80000">// time_point !=</font>
  1562. template &lt;class Clock, class Duration1, class Duration2&gt;
  1563. inline
  1564. bool
  1565. operator!=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1566. {
  1567. return !(lhs == rhs);
  1568. }
  1569. <font color="#c80000">// time_point &lt;</font>
  1570. template &lt;class Clock, class Duration1, class Duration2&gt;
  1571. inline
  1572. bool
  1573. operator&lt;(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1574. {
  1575. return lhs.time_since_epoch() &lt; rhs.time_since_epoch();
  1576. }
  1577. <font color="#c80000">// time_point &gt;</font>
  1578. template &lt;class Clock, class Duration1, class Duration2&gt;
  1579. inline
  1580. bool
  1581. operator&gt;(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1582. {
  1583. return rhs &lt; lhs;
  1584. }
  1585. <font color="#c80000">// time_point &lt;=</font>
  1586. template &lt;class Clock, class Duration1, class Duration2&gt;
  1587. inline
  1588. bool
  1589. operator&lt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1590. {
  1591. return !(rhs &lt; lhs);
  1592. }
  1593. <font color="#c80000">// time_point &gt;=</font>
  1594. template &lt;class Clock, class Duration1, class Duration2&gt;
  1595. inline
  1596. bool
  1597. operator&gt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1598. {
  1599. return !(lhs &lt; rhs);
  1600. }
  1601. <font color="#c80000">// time_point operator+(time_point x, duration y);</font>
  1602. template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
  1603. inline
  1604. time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
  1605. operator+(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1606. {
  1607. typedef time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt; TimeResult;
  1608. TimeResult r(lhs);
  1609. r += rhs;
  1610. return r;
  1611. }
  1612. <font color="#c80000">// time_point operator+(duration x, time_point y);</font>
  1613. template &lt;class Rep1, class Period1, class Clock, class Duration2&gt;
  1614. inline
  1615. time_point&lt;Clock, typename common_type&lt;duration&lt;Rep1, Period1&gt;, Duration2&gt;::type&gt;
  1616. operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1617. {
  1618. return rhs + lhs;
  1619. }
  1620. <font color="#c80000">// time_point operator-(time_point x, duration y);</font>
  1621. template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
  1622. inline
  1623. time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
  1624. operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
  1625. {
  1626. return lhs + (-rhs);
  1627. }
  1628. <font color="#c80000">// duration operator-(time_point x, time_point y);</font>
  1629. template &lt;class Clock, class Duration1, class Duration2&gt;
  1630. inline
  1631. typename common_type&lt;Duration1, Duration2&gt;::type
  1632. operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
  1633. {
  1634. return lhs.time_since_epoch() - rhs.time_since_epoch();
  1635. }
  1636. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1637. <font color="#c80000">/////////////////////// clocks ///////////////////////////</font>
  1638. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1639. <font color="#c80000">// If you're porting, clocks are the system-specific (non-portable) part.</font>
  1640. <font color="#c80000">// You'll need to know how to get the current time and implement that under now().</font>
  1641. <font color="#c80000">// You'll need to know what units (tick period) and representation makes the most</font>
  1642. <font color="#c80000">// sense for your clock and set those accordingly.</font>
  1643. <font color="#c80000">// If you know how to map this clock to time_t (perhaps your clock is std::time, which</font>
  1644. <font color="#c80000">// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t().</font>
  1645. class system_clock
  1646. {
  1647. public:
  1648. typedef microseconds duration;
  1649. typedef duration::rep rep;
  1650. typedef duration::period period;
  1651. typedef datetime::time_point&lt;system_clock&gt; time_point;
  1652. static const bool is_monotonic = false;
  1653. static time_point now();
  1654. static time_t to_time_t (const time_point&amp; t);
  1655. static time_point from_time_t(time_t t);
  1656. };
  1657. class monotonic_clock
  1658. {
  1659. public:
  1660. typedef nanoseconds duration;
  1661. typedef duration::rep rep;
  1662. typedef duration::period period;
  1663. typedef datetime::time_point&lt;monotonic_clock&gt; time_point;
  1664. static const bool is_monotonic = true;
  1665. static time_point now();
  1666. };
  1667. typedef monotonic_clock high_resolution_clock;
  1668. } <font color="#c80000">// datetime</font>
  1669. } <font color="#c80000">// std</font>
  1670. <font color="#c80000">// clocks.cpp</font>
  1671. #include &lt;sys/time.h&gt; <font color="#c80000">//for gettimeofday and timeval</font>
  1672. #include &lt;mach/mach_time.h&gt; <font color="#c80000">// mach_absolute_time, mach_timebase_info_data_t</font>
  1673. namespace std {
  1674. namespace datetime {
  1675. <font color="#c80000">// system_clock</font>
  1676. <font color="#c80000">// gettimeofday is the most precise "system time" available on this platform.</font>
  1677. <font color="#c80000">// It returns the number of microseconds since New Years 1970 in a struct called timeval</font>
  1678. <font color="#c80000">// which has a field for seconds and a field for microseconds.</font>
  1679. <font color="#c80000">// Fill in the timeval and then convert that to the time_point</font>
  1680. system_clock::time_point
  1681. system_clock::now()
  1682. {
  1683. timeval tv;
  1684. gettimeofday(&amp;tv, 0);
  1685. return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
  1686. }
  1687. <font color="#c80000">// Take advantage of the fact that on this platform time_t is nothing but</font>
  1688. <font color="#c80000">// an integral count of seconds since New Years 1970 (same epoch as timeval).</font>
  1689. <font color="#c80000">// Just get the duration out of the time_point and truncate it to seconds.</font>
  1690. time_t
  1691. system_clock::to_time_t(const time_point&amp; t)
  1692. {
  1693. return time_t(duration_cast&lt;seconds&gt;(t.time_since_epoch()).count());
  1694. }
  1695. <font color="#c80000">// Just turn the time_t into a count of seconds and construct a time_point with it.</font>
  1696. system_clock::time_point
  1697. system_clock::from_time_t(time_t t)
  1698. {
  1699. return system_clock::time_point(seconds(t));
  1700. }
  1701. <font color="#c80000">// monotonic_clock</font>
  1702. <font color="#c80000">// Note, in this implementation monotonic_clock and high_resolution_clock</font>
  1703. <font color="#c80000">// are the same clock. They are both based on mach_absolute_time().</font>
  1704. <font color="#c80000">// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of</font>
  1705. <font color="#c80000">// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom</font>
  1706. <font color="#c80000">// are run time constants supplied by the OS. This clock has no relationship</font>
  1707. <font color="#c80000">// to the Gregorian calendar. It's main use is as a high resolution timer.</font>
  1708. <font color="#c80000">// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize</font>
  1709. <font color="#c80000">// for that case as an optimization.</font>
  1710. static
  1711. monotonic_clock::rep
  1712. monotonic_simplified()
  1713. {
  1714. return mach_absolute_time();
  1715. }
  1716. static
  1717. double
  1718. compute_monotonic_factor()
  1719. {
  1720. mach_timebase_info_data_t MachInfo;
  1721. mach_timebase_info(&amp;MachInfo);
  1722. return static_cast&lt;double&gt;(MachInfo.numer) / MachInfo.denom;
  1723. }
  1724. static
  1725. monotonic_clock::rep
  1726. monotonic_full()
  1727. {
  1728. static const double factor = compute_monotonic_factor();
  1729. return static_cast&lt;monotonic_clock::rep&gt;(mach_absolute_time() * factor);
  1730. }
  1731. typedef monotonic_clock::rep (*FP)();
  1732. static
  1733. FP
  1734. init_monotonic_clock()
  1735. {
  1736. mach_timebase_info_data_t MachInfo;
  1737. mach_timebase_info(&amp;MachInfo);
  1738. if (MachInfo.numer == MachInfo.denom)
  1739. return &amp;monotonic_simplified;
  1740. return &amp;monotonic_full;
  1741. }
  1742. monotonic_clock::time_point
  1743. monotonic_clock::now()
  1744. {
  1745. static FP fp = init_monotonic_clock();
  1746. return time_point(duration(fp()));
  1747. }
  1748. <font color="#c80000">// clocks.cpp end</font>
  1749. } } <font color="#c80000">// std::datetime</font>
  1750. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1751. <font color="#c80000">///////////// simulated thread interface /////////////////</font>
  1752. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1753. #include &lt;iostream&gt;
  1754. namespace std {
  1755. void __print_time(datetime::system_clock::time_point t)
  1756. {
  1757. using namespace datetime;
  1758. time_t c_time = system_clock::to_time_t(t);
  1759. std::tm* tmptr = std::localtime(&amp;c_time);
  1760. system_clock::duration d = t.time_since_epoch();
  1761. std::cout &lt;&lt; tmptr-&gt;tm_hour &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_min &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_sec
  1762. &lt;&lt; '.' &lt;&lt; (d - duration_cast&lt;seconds&gt;(d)).count();
  1763. }
  1764. namespace this_thread {
  1765. template &lt;class Rep, class Period&gt;
  1766. void sleep_for(const datetime::duration&lt;Rep, Period&gt;&amp; d)
  1767. {
  1768. datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
  1769. if (t &lt; d)
  1770. ++t;
  1771. if (t &gt; datetime::microseconds(0))
  1772. std::cout &lt;&lt; "sleep_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
  1773. }
  1774. template &lt;class Clock, class Duration&gt;
  1775. void sleep_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
  1776. {
  1777. using namespace datetime;
  1778. typedef time_point&lt;Clock, Duration&gt; Time;
  1779. typedef system_clock::time_point SysTime;
  1780. if (t &gt; Clock::now())
  1781. {
  1782. typedef typename common_type&lt;typename Time::duration, typename SysTime::duration&gt;::type D;
  1783. <font color="#c80000">/* auto */</font> D d = t - Clock::now();
  1784. microseconds us = duration_cast&lt;microseconds&gt;(d);
  1785. if (us &lt; d)
  1786. ++us;
  1787. SysTime st = system_clock::now() + us;
  1788. std::cout &lt;&lt; "sleep_until ";
  1789. __print_time(st);
  1790. std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
  1791. }
  1792. }
  1793. } <font color="#c80000">// this_thread</font>
  1794. struct mutex {};
  1795. struct timed_mutex
  1796. {
  1797. bool try_lock() {std::cout &lt;&lt; "timed_mutex::try_lock()\n";}
  1798. template &lt;class Rep, class Period&gt;
  1799. bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; d)
  1800. {
  1801. datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
  1802. if (t &lt;= datetime::microseconds(0))
  1803. return try_lock();
  1804. std::cout &lt;&lt; "try_lock_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
  1805. return true;
  1806. }
  1807. template &lt;class Clock, class Duration&gt;
  1808. bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
  1809. {
  1810. using namespace datetime;
  1811. typedef time_point&lt;Clock, Duration&gt; Time;
  1812. typedef system_clock::time_point SysTime;
  1813. if (t &lt;= Clock::now())
  1814. return try_lock();
  1815. typedef typename common_type&lt;typename Time::duration, typename Clock::duration&gt;::type D;
  1816. <font color="#c80000">/* auto */</font> D d = t - Clock::now();
  1817. microseconds us = duration_cast&lt;microseconds&gt;(d);
  1818. SysTime st = system_clock::now() + us;
  1819. std::cout &lt;&lt; "try_lock_until ";
  1820. __print_time(st);
  1821. std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
  1822. }
  1823. };
  1824. struct condition_variable
  1825. {
  1826. template &lt;class Rep, class Period&gt;
  1827. bool wait_for(mutex&amp;, const datetime::duration&lt;Rep, Period&gt;&amp; d)
  1828. {
  1829. datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
  1830. std::cout &lt;&lt; "wait_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
  1831. return true;
  1832. }
  1833. template &lt;class Clock, class Duration&gt;
  1834. bool wait_until(mutex&amp;, const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
  1835. {
  1836. using namespace datetime;
  1837. typedef time_point&lt;Clock, Duration&gt; Time;
  1838. typedef system_clock::time_point SysTime;
  1839. if (t &lt;= Clock::now())
  1840. return false;
  1841. typedef typename common_type&lt;typename Time::duration, typename Clock::duration&gt;::type D;
  1842. <font color="#c80000">/* auto */</font> D d = t - Clock::now();
  1843. microseconds us = duration_cast&lt;microseconds&gt;(d);
  1844. SysTime st = system_clock::now() + us;
  1845. std::cout &lt;&lt; "wait_until ";
  1846. __print_time(st);
  1847. std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
  1848. }
  1849. };
  1850. } <font color="#c80000">// std</font>
  1851. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1852. <font color="#c80000">/////////////////// End of implemetation ////////////////</font>
  1853. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1854. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1855. <font color="#c80000">//////////// Simple sleep and wait examples //////////////</font>
  1856. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1857. std::mutex m;
  1858. std::timed_mutex mut;
  1859. std::condition_variable cv;
  1860. void basic_examples()
  1861. {
  1862. std::cout &lt;&lt; "Running basic examples\n";
  1863. using namespace std;
  1864. using namespace std::datetime;
  1865. system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
  1866. this_thread::sleep_for(seconds(3));
  1867. this_thread::sleep_for(nanoseconds(300));
  1868. this_thread::sleep_until(time_limit);
  1869. <font color="#c80000">// this_thread::sleep_for(time_limit); // desired compile-time error</font>
  1870. <font color="#c80000">// this_thread::sleep_until(seconds(3)); // desired compile-time error</font>
  1871. mut.try_lock_for(milliseconds(30));
  1872. mut.try_lock_until(time_limit);
  1873. <font color="#c80000">// mut.try_lock_for(time_limit); // desired compile-time error</font>
  1874. <font color="#c80000">// mut.try_lock_until(milliseconds(30)); // desired compile-time error</font>
  1875. cv.wait_for(m, minutes(1)); <font color="#c80000">// real code would put this in a loop</font>
  1876. cv.wait_until(m, time_limit); <font color="#c80000">// real code would put this in a loop</font>
  1877. <font color="#c80000">// For those who prefer floating point</font>
  1878. this_thread::sleep_for(duration&lt;double&gt;(0.25));
  1879. this_thread::sleep_until(system_clock::now() + duration&lt;double&gt;(1.5));
  1880. }
  1881. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1882. <font color="#c80000">//////////////////// User1 Example ///////////////////////</font>
  1883. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  1884. namespace User1
  1885. {
  1886. <font color="#c80000">// Example type-safe "physics" code interoperating with std::datetime::duration types</font>
  1887. <font color="#c80000">// and taking advantage of the std::ratio infrastructure and design philosophy.</font>
  1888. <font color="#c80000">// length - mimics std::datetime::duration except restricts representation to double.</font>
  1889. <font color="#c80000">// Uses std::ratio facilities for length units conversions.</font>
  1890. template &lt;class Ratio&gt;
  1891. class length
  1892. {
  1893. public:
  1894. typedef Ratio ratio;
  1895. private:
  1896. double len_;
  1897. public:
  1898. length() : len_(1) {}
  1899. length(const double&amp; len) : len_(len) {}
  1900. <font color="#c80000">// conversions</font>
  1901. template &lt;class R&gt;
  1902. length(const length&lt;R&gt;&amp; d)
  1903. : len_(d.count() * std::ratio_divide&lt;Ratio, R&gt;::type::den /
  1904. std::ratio_divide&lt;Ratio, R&gt;::type::num) {}
  1905. <font color="#c80000">// observer</font>
  1906. double count() const {return len_;}
  1907. <font color="#c80000">// arithmetic</font>
  1908. length&amp; operator+=(const length&amp; d) {len_ += d.count(); return *this;}
  1909. length&amp; operator-=(const length&amp; d) {len_ -= d.count(); return *this;}
  1910. length operator+() const {return *this;}
  1911. length operator-() const {return length(-len_);}
  1912. length&amp; operator*=(double rhs) {len_ *= rhs; return *this;}
  1913. length&amp; operator/=(double rhs) {len_ /= rhs; return *this;}
  1914. };
  1915. <font color="#c80000">// Sparse sampling of length units</font>
  1916. typedef length&lt;std::ratio&lt;1&gt; &gt; meter; <font color="#c80000">// set meter as "unity"</font>
  1917. typedef length&lt;std::centi&gt; centimeter; <font color="#c80000">// 1/100 meter</font>
  1918. typedef length&lt;std::kilo&gt; kilometer; <font color="#c80000">// 1000 meters</font>
  1919. typedef length&lt;std::ratio&lt;254, 10000&gt; &gt; inch; <font color="#c80000">// 254/10000 meters</font>
  1920. <font color="#c80000">// length takes ratio instead of two integral types so that definitions can be made like so:</font>
  1921. typedef length&lt;std::ratio_multiply&lt;std::ratio&lt;12&gt;, inch::ratio&gt;::type&gt; foot; <font color="#c80000">// 12 inchs</font>
  1922. typedef length&lt;std::ratio_multiply&lt;std::ratio&lt;5280&gt;, foot::ratio&gt;::type&gt; mile; <font color="#c80000">// 5280 feet</font>
  1923. <font color="#c80000">// Need a floating point definition of seconds</font>
  1924. typedef std::datetime::duration&lt;double&gt; seconds; <font color="#c80000">// unity</font>
  1925. <font color="#c80000">// Demo of (scientific) support for sub-nanosecond resolutions</font>
  1926. typedef std::datetime::duration&lt;double, std::pico&gt; picosecond; <font color="#c80000">// 10^-12 seconds</font>
  1927. typedef std::datetime::duration&lt;double, std::femto&gt; femtosecond; <font color="#c80000">// 10^-15 seconds</font>
  1928. typedef std::datetime::duration&lt;double, std::atto&gt; attosecond; <font color="#c80000">// 10^-18 seconds</font>
  1929. <font color="#c80000">// A very brief proof-of-concept for SIUnits-like library</font>
  1930. <font color="#c80000">// Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())</font>
  1931. template &lt;class R1, class R2&gt;
  1932. class quantity
  1933. {
  1934. double q_;
  1935. public:
  1936. quantity() : q_(1) {}
  1937. double get() const {return q_;}
  1938. void set(double q) {q_ = q;}
  1939. };
  1940. template &lt;&gt;
  1941. class quantity&lt;std::ratio&lt;1&gt;, std::ratio&lt;0&gt; &gt;
  1942. {
  1943. double q_;
  1944. public:
  1945. quantity() : q_(1) {}
  1946. quantity(seconds d) : q_(d.count()) {} <font color="#c80000">// note: only User1::seconds needed here</font>
  1947. double get() const {return q_;}
  1948. void set(double q) {q_ = q;}
  1949. };
  1950. template &lt;&gt;
  1951. class quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;1&gt; &gt;
  1952. {
  1953. double q_;
  1954. public:
  1955. quantity() : q_(1) {}
  1956. quantity(meter d) : q_(d.count()) {} <font color="#c80000">// note: only User1::meter needed here</font>
  1957. double get() const {return q_;}
  1958. void set(double q) {q_ = q;}
  1959. };
  1960. template &lt;&gt;
  1961. class quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;0&gt; &gt;
  1962. {
  1963. double q_;
  1964. public:
  1965. quantity() : q_(1) {}
  1966. quantity(double d) : q_(d) {}
  1967. double get() const {return q_;}
  1968. void set(double q) {q_ = q;}
  1969. };
  1970. <font color="#c80000">// Example SI-Units</font>
  1971. typedef quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;0&gt; &gt; Scalar;
  1972. typedef quantity&lt;std::ratio&lt;1&gt;, std::ratio&lt;0&gt; &gt; Time; <font color="#c80000">// second</font>
  1973. typedef quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;1&gt; &gt; Distance; <font color="#c80000">// meter</font>
  1974. typedef quantity&lt;std::ratio&lt;-1&gt;, std::ratio&lt;1&gt; &gt; Speed; <font color="#c80000">// meter/second</font>
  1975. typedef quantity&lt;std::ratio&lt;-2&gt;, std::ratio&lt;1&gt; &gt; Acceleration; <font color="#c80000">// meter/second^2</font>
  1976. template &lt;class R1, class R2, class R3, class R4&gt;
  1977. quantity&lt;typename std::ratio_subtract&lt;R1, R3&gt;::type, typename std::ratio_subtract&lt;R2, R4&gt;::type&gt;
  1978. operator/(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R3, R4&gt;&amp; y)
  1979. {
  1980. typedef quantity&lt;typename std::ratio_subtract&lt;R1, R3&gt;::type, typename std::ratio_subtract&lt;R2, R4&gt;::type&gt; R;
  1981. R r;
  1982. r.set(x.get() / y.get());
  1983. return r;
  1984. }
  1985. template &lt;class R1, class R2, class R3, class R4&gt;
  1986. quantity&lt;typename std::ratio_add&lt;R1, R3&gt;::type, typename std::ratio_add&lt;R2, R4&gt;::type&gt;
  1987. operator*(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R3, R4&gt;&amp; y)
  1988. {
  1989. typedef quantity&lt;typename std::ratio_add&lt;R1, R3&gt;::type, typename std::ratio_add&lt;R2, R4&gt;::type&gt; R;
  1990. R r;
  1991. r.set(x.get() * y.get());
  1992. return r;
  1993. }
  1994. template &lt;class R1, class R2&gt;
  1995. quantity&lt;R1, R2&gt;
  1996. operator+(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R1, R2&gt;&amp; y)
  1997. {
  1998. typedef quantity&lt;R1, R2&gt; R;
  1999. R r;
  2000. r.set(x.get() + y.get());
  2001. return r;
  2002. }
  2003. template &lt;class R1, class R2&gt;
  2004. quantity&lt;R1, R2&gt;
  2005. operator-(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R1, R2&gt;&amp; y)
  2006. {
  2007. typedef quantity&lt;R1, R2&gt; R;
  2008. R r;
  2009. r.set(x.get() - y.get());
  2010. return r;
  2011. }
  2012. <font color="#c80000">// Example type-safe physics function</font>
  2013. Distance
  2014. compute_distance(Speed v0, Time t, Acceleration a)
  2015. {
  2016. return v0 * t + Scalar(.5) * a * t * t; <font color="#c80000">// if a units mistake is made here it won't compile</font>
  2017. }
  2018. } <font color="#c80000">// User1</font>
  2019. #include &lt;iostream&gt;
  2020. <font color="#c80000">// Exercise example type-safe physics function and show interoperation</font>
  2021. <font color="#c80000">// of custom time durations (User1::seconds) and standard time durations (std::hours).</font>
  2022. <font color="#c80000">// Though input can be arbitrary (but type-safe) units, output is always in SI-units</font>
  2023. <font color="#c80000">// (a limitation of the simplified Units lib demoed here).</font>
  2024. void testUser1()
  2025. {
  2026. std::cout &lt;&lt; "*************\n";
  2027. std::cout &lt;&lt; "* testUser1 *\n";
  2028. std::cout &lt;&lt; "*************\n";
  2029. User1::Distance d( User1::mile(110) );
  2030. User1::Time t( std::datetime::hours(2) );
  2031. User1::Speed s = d / t;
  2032. std::cout &lt;&lt; "Speed = " &lt;&lt; s.get() &lt;&lt; " meters/sec\n";
  2033. User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
  2034. std::cout &lt;&lt; "Acceleration = " &lt;&lt; a.get() &lt;&lt; " meters/sec^2\n";
  2035. User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
  2036. std::cout &lt;&lt; "Distance = " &lt;&lt; df.get() &lt;&lt; " meters\n";
  2037. std::cout &lt;&lt; "There are " &lt;&lt; User1::mile::ratio::den &lt;&lt; '/' &lt;&lt; User1::mile::ratio::num &lt;&lt; " miles/meter";
  2038. User1::meter mt = 1;
  2039. User1::mile mi = mt;
  2040. std::cout &lt;&lt; " which is approximately " &lt;&lt; mi.count() &lt;&lt; '\n';
  2041. std::cout &lt;&lt; "There are " &lt;&lt; User1::mile::ratio::num &lt;&lt; '/' &lt;&lt; User1::mile::ratio::den &lt;&lt; " meters/mile";
  2042. mi = 1;
  2043. mt = mi;
  2044. std::cout &lt;&lt; " which is approximately " &lt;&lt; mt.count() &lt;&lt; '\n';
  2045. User1::attosecond as(1);
  2046. User1::seconds sec = as;
  2047. std::cout &lt;&lt; "1 attosecond is " &lt;&lt; sec.count() &lt;&lt; " seconds\n";
  2048. std::cout &lt;&lt; "sec = as; <font color="#c80000">// compiles\n";</font>
  2049. sec = User1::seconds(1);
  2050. as = sec;
  2051. std::cout &lt;&lt; "1 second is " &lt;&lt; as.count() &lt;&lt; " attoseconds\n";
  2052. std::cout &lt;&lt; "as = sec; <font color="#c80000">// compiles\n";</font>
  2053. std::cout &lt;&lt; "\n";
  2054. }
  2055. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  2056. <font color="#c80000">//////////////////// User2 Example ///////////////////////</font>
  2057. <font color="#c80000">//////////////////////////////////////////////////////////</font>
  2058. <font color="#c80000">// Demonstrate User2:</font>
  2059. <font color="#c80000">// A "saturating" signed integral type is developed. This type has +/- infinity and a nan</font>
  2060. <font color="#c80000">// (like IEEE floating point) but otherwise obeys signed integral arithmetic.</font>
  2061. <font color="#c80000">// This class is subsequently used as the rep in std::datetime::duration to demonstrate a</font>
  2062. <font color="#c80000">// duration class that does not silently ignore overflow.</font>
  2063. #include &lt;ostream&gt;
  2064. #include &lt;stdexcept&gt;
  2065. #include &lt;climits&gt;
  2066. namespace User2
  2067. {
  2068. template &lt;class I&gt;
  2069. class saturate
  2070. {
  2071. public:
  2072. typedef I int_type;
  2073. static const int_type nan = int_type(int_type(1) &lt;&lt; (sizeof(int_type) * CHAR_BIT - 1));
  2074. static const int_type neg_inf = nan + 1;
  2075. static const int_type pos_inf = -neg_inf;
  2076. private:
  2077. int_type i_;
  2078. <font color="#c80000">// static_assert(std::is_integral&lt;int_type&gt;::value &amp;&amp; std::is_signed&lt;int_type&gt;::value,</font>
  2079. <font color="#c80000">// "saturate only accepts signed integral types");</font>
  2080. <font color="#c80000">// static_assert(nan == -nan &amp;&amp; neg_inf &lt; pos_inf,</font>
  2081. <font color="#c80000">// "saturate assumes two's complement hardware for signed integrals");</font>
  2082. public:
  2083. saturate() : i_(nan) {}
  2084. explicit saturate(int_type i) : i_(i) {}
  2085. <font color="#c80000">// explicit</font>
  2086. operator int_type() const;
  2087. saturate&amp; operator+=(saturate x);
  2088. saturate&amp; operator-=(saturate x) {return *this += -x;}
  2089. saturate&amp; operator*=(saturate x);
  2090. saturate&amp; operator/=(saturate x);
  2091. saturate&amp; operator%=(saturate x);
  2092. saturate operator- () const {return saturate(-i_);}
  2093. saturate&amp; operator++() {*this += saturate(int_type(1)); return *this;}
  2094. saturate operator++(int) {saturate tmp(*this); ++(*this); return tmp;}
  2095. saturate&amp; operator--() {*this -= saturate(int_type(1)); return *this;}
  2096. saturate operator--(int) {saturate tmp(*this); --(*this); return tmp;}
  2097. friend saturate operator+(saturate x, saturate y) {return x += y;}
  2098. friend saturate operator-(saturate x, saturate y) {return x -= y;}
  2099. friend saturate operator*(saturate x, saturate y) {return x *= y;}
  2100. friend saturate operator/(saturate x, saturate y) {return x /= y;}
  2101. friend saturate operator%(saturate x, saturate y) {return x %= y;}
  2102. friend bool operator==(saturate x, saturate y)
  2103. {
  2104. if (x.i_ == nan || y.i_ == nan)
  2105. return false;
  2106. return x.i_ == y.i_;
  2107. }
  2108. friend bool operator!=(saturate x, saturate y) {return !(x == y);}
  2109. friend bool operator&lt;(saturate x, saturate y)
  2110. {
  2111. if (x.i_ == nan || y.i_ == nan)
  2112. return false;
  2113. return x.i_ &lt; y.i_;
  2114. }
  2115. friend bool operator&lt;=(saturate x, saturate y)
  2116. {
  2117. if (x.i_ == nan || y.i_ == nan)
  2118. return false;
  2119. return x.i_ &lt;= y.i_;
  2120. }
  2121. friend bool operator&gt;(saturate x, saturate y)
  2122. {
  2123. if (x.i_ == nan || y.i_ == nan)
  2124. return false;
  2125. return x.i_ &gt; y.i_;
  2126. }
  2127. friend bool operator&gt;=(saturate x, saturate y)
  2128. {
  2129. if (x.i_ == nan || y.i_ == nan)
  2130. return false;
  2131. return x.i_ &gt;= y.i_;
  2132. }
  2133. friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, saturate s)
  2134. {
  2135. switch (s.i_)
  2136. {
  2137. case pos_inf:
  2138. return os &lt;&lt; "inf";
  2139. case nan:
  2140. return os &lt;&lt; "nan";
  2141. case neg_inf:
  2142. return os &lt;&lt; "-inf";
  2143. };
  2144. return os &lt;&lt; s.i_;
  2145. }
  2146. };
  2147. template &lt;class I&gt;
  2148. saturate&lt;I&gt;::operator int_type() const
  2149. {
  2150. switch (i_)
  2151. {
  2152. case nan:
  2153. case neg_inf:
  2154. case pos_inf:
  2155. throw std::out_of_range("saturate special value can not convert to int_type");
  2156. }
  2157. return i_;
  2158. }
  2159. template &lt;class I&gt;
  2160. saturate&lt;I&gt;&amp;
  2161. saturate&lt;I&gt;::operator+=(saturate x)
  2162. {
  2163. switch (i_)
  2164. {
  2165. case pos_inf:
  2166. switch (x.i_)
  2167. {
  2168. case neg_inf:
  2169. case nan:
  2170. i_ = nan;
  2171. }
  2172. return *this;
  2173. case nan:
  2174. return *this;
  2175. case neg_inf:
  2176. switch (x.i_)
  2177. {
  2178. case pos_inf:
  2179. case nan:
  2180. i_ = nan;
  2181. }
  2182. return *this;
  2183. }
  2184. switch (x.i_)
  2185. {
  2186. case pos_inf:
  2187. case neg_inf:
  2188. case nan:
  2189. i_ = x.i_;
  2190. return *this;
  2191. }
  2192. if (x.i_ &gt;= 0)
  2193. {
  2194. if (i_ &lt; pos_inf - x.i_)
  2195. i_ += x.i_;
  2196. else
  2197. i_ = pos_inf;
  2198. return *this;
  2199. }
  2200. if (i_ &gt; neg_inf - x.i_)
  2201. i_ += x.i_;
  2202. else
  2203. i_ = neg_inf;
  2204. return *this;
  2205. }
  2206. template &lt;class I&gt;
  2207. saturate&lt;I&gt;&amp;
  2208. saturate&lt;I&gt;::operator*=(saturate x)
  2209. {
  2210. switch (i_)
  2211. {
  2212. case 0:
  2213. switch (x.i_)
  2214. {
  2215. case pos_inf:
  2216. case neg_inf:
  2217. case nan:
  2218. i_ = nan;
  2219. }
  2220. return *this;
  2221. case pos_inf:
  2222. switch (x.i_)
  2223. {
  2224. case nan:
  2225. case 0:
  2226. i_ = nan;
  2227. return *this;
  2228. }
  2229. if (x.i_ &lt; 0)
  2230. i_ = neg_inf;
  2231. return *this;
  2232. case nan:
  2233. return *this;
  2234. case neg_inf:
  2235. switch (x.i_)
  2236. {
  2237. case nan:
  2238. case 0:
  2239. i_ = nan;
  2240. return *this;
  2241. }
  2242. if (x.i_ &lt; 0)
  2243. i_ = pos_inf;
  2244. return *this;
  2245. }
  2246. switch (x.i_)
  2247. {
  2248. case 0:
  2249. i_ = 0;
  2250. return *this;
  2251. case nan:
  2252. i_ = nan;
  2253. return *this;
  2254. case pos_inf:
  2255. if (i_ &lt; 0)
  2256. i_ = neg_inf;
  2257. else
  2258. i_ = pos_inf;
  2259. return *this;
  2260. case neg_inf:
  2261. if (i_ &lt; 0)
  2262. i_ = pos_inf;
  2263. else
  2264. i_ = neg_inf;
  2265. return *this;
  2266. }
  2267. int s = (i_ &lt; 0 ? -1 : 1) * (x.i_ &lt; 0 ? -1 : 1);
  2268. i_ = i_ &lt; 0 ? -i_ : i_;
  2269. int_type x_i_ = x.i_ &lt; 0 ? -x.i_ : x.i_;
  2270. if (i_ &lt;= pos_inf / x_i_)
  2271. i_ *= x_i_;
  2272. else
  2273. i_ = pos_inf;
  2274. i_ *= s;
  2275. return *this;
  2276. }
  2277. template &lt;class I&gt;
  2278. saturate&lt;I&gt;&amp;
  2279. saturate&lt;I&gt;::operator/=(saturate x)
  2280. {
  2281. switch (x.i_)
  2282. {
  2283. case pos_inf:
  2284. case neg_inf:
  2285. switch (i_)
  2286. {
  2287. case pos_inf:
  2288. case neg_inf:
  2289. case nan:
  2290. i_ = nan;
  2291. break;
  2292. default:
  2293. i_ = 0;
  2294. break;
  2295. }
  2296. return *this;
  2297. case nan:
  2298. i_ = nan;
  2299. return *this;
  2300. case 0:
  2301. switch (i_)
  2302. {
  2303. case pos_inf:
  2304. case neg_inf:
  2305. case nan:
  2306. return *this;
  2307. case 0:
  2308. i_ = nan;
  2309. return *this;
  2310. }
  2311. if (i_ &gt; 0)
  2312. i_ = pos_inf;
  2313. else
  2314. i_ = neg_inf;
  2315. return *this;
  2316. }
  2317. switch (i_)
  2318. {
  2319. case 0:
  2320. case nan:
  2321. return *this;
  2322. case pos_inf:
  2323. case neg_inf:
  2324. if (x.i_ &lt; 0)
  2325. i_ = -i_;
  2326. return *this;
  2327. }
  2328. i_ /= x.i_;
  2329. return *this;
  2330. }
  2331. template &lt;class I&gt;
  2332. saturate&lt;I&gt;&amp;
  2333. saturate&lt;I&gt;::operator%=(saturate x)
  2334. {
  2335. <font color="#c80000">// *this -= *this / x * x; // definition</font>
  2336. switch (x.i_)
  2337. {
  2338. case nan:
  2339. case neg_inf:
  2340. case 0:
  2341. case pos_inf:
  2342. i_ = nan;
  2343. return *this;
  2344. }
  2345. switch (i_)
  2346. {
  2347. case neg_inf:
  2348. case pos_inf:
  2349. i_ = nan;
  2350. case nan:
  2351. return *this;
  2352. }
  2353. i_ %= x.i_;
  2354. return *this;
  2355. }
  2356. <font color="#c80000">// Demo overflow-safe integral durations ranging from picoseconds resolution to millennium resolution</font>
  2357. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::pico &gt; picoseconds;
  2358. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::nano &gt; nanoseconds;
  2359. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::micro &gt; microseconds;
  2360. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::milli &gt; milliseconds;
  2361. typedef std::datetime::duration&lt;saturate&lt;long long&gt; &gt; seconds;
  2362. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 60LL&gt; &gt; minutes;
  2363. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 3600LL&gt; &gt; hours;
  2364. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 86400LL&gt; &gt; days;
  2365. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt; 31556952LL&gt; &gt; years;
  2366. typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt;31556952000LL&gt; &gt; millennium;
  2367. } <font color="#c80000">// User2</font>
  2368. <font color="#c80000">// Demonstrate custom promotion rules (needed only if there are no implicit conversions)</font>
  2369. namespace User2 { namespace detail {
  2370. template &lt;class T1, class T2, bool = tmp::is_integral&lt;T1&gt;::value&gt;
  2371. struct promote_helper;
  2372. template &lt;class T1, class T2&gt;
  2373. struct promote_helper&lt;T1, saturate&lt;T2&gt;, true&gt; <font color="#c80000">// integral</font>
  2374. {
  2375. typedef typename std::common_type&lt;T1, T2&gt;::type rep;
  2376. typedef User2::saturate&lt;rep&gt; type;
  2377. };
  2378. template &lt;class T1, class T2&gt;
  2379. struct promote_helper&lt;T1, saturate&lt;T2&gt;, false&gt; <font color="#c80000">// floating</font>
  2380. {
  2381. typedef T1 type;
  2382. };
  2383. } }
  2384. namespace std
  2385. {
  2386. template &lt;class T1, class T2&gt;
  2387. struct common_type&lt;User2::saturate&lt;T1&gt;, User2::saturate&lt;T2&gt; &gt;
  2388. {
  2389. typedef typename common_type&lt;T1, T2&gt;::type rep;
  2390. typedef User2::saturate&lt;rep&gt; type;
  2391. };
  2392. template &lt;class T1, class T2&gt;
  2393. struct common_type&lt;T1, User2::saturate&lt;T2&gt; &gt;
  2394. : User2::detail::promote_helper&lt;T1, User2::saturate&lt;T2&gt; &gt; {};
  2395. template &lt;class T1, class T2&gt;
  2396. struct common_type&lt;User2::saturate&lt;T1&gt;, T2&gt;
  2397. : User2::detail::promote_helper&lt;T2, User2::saturate&lt;T1&gt; &gt; {};
  2398. <font color="#c80000">// Demonstrate specialization of duration_values:</font>
  2399. namespace datetime {
  2400. template &lt;class I&gt;
  2401. struct duration_values&lt;User2::saturate&lt;I&gt; &gt;
  2402. {
  2403. typedef User2::saturate&lt;I&gt; Rep;
  2404. public:
  2405. static Rep zero() {return Rep(0);}
  2406. static Rep max() {return Rep(Rep::pos_inf-1);}
  2407. static Rep min() {return -max();}
  2408. };
  2409. }
  2410. }
  2411. #include &lt;iostream&gt;
  2412. void testUser2()
  2413. {
  2414. std::cout &lt;&lt; "*************\n";
  2415. std::cout &lt;&lt; "* testUser2 *\n";
  2416. std::cout &lt;&lt; "*************\n";
  2417. using namespace User2;
  2418. typedef seconds::rep sat;
  2419. years yr(sat(100));
  2420. std::cout &lt;&lt; "100 years expressed as years = " &lt;&lt; yr.count() &lt;&lt; '\n';
  2421. nanoseconds ns = yr;
  2422. std::cout &lt;&lt; "100 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
  2423. ns += yr;
  2424. std::cout &lt;&lt; "200 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
  2425. ns += yr;
  2426. std::cout &lt;&lt; "300 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
  2427. <font color="#c80000">// yr = ns; // does not compile</font>
  2428. std::cout &lt;&lt; "yr = ns; <font color="#c80000">// does not compile\n";</font>
  2429. <font color="#c80000">// picoseconds ps1 = yr; // does not compile, compile-time overflow in ratio arithmetic</font>
  2430. std::cout &lt;&lt; "ps = yr; <font color="#c80000">// does not compile\n";</font>
  2431. ns = yr;
  2432. picoseconds ps = ns;
  2433. std::cout &lt;&lt; "100 years expressed as picoseconds = " &lt;&lt; ps.count() &lt;&lt; '\n';
  2434. ps = ns / sat(1000);
  2435. std::cout &lt;&lt; "0.1 years expressed as picoseconds = " &lt;&lt; ps.count() &lt;&lt; '\n';
  2436. yr = years(sat(-200000000));
  2437. std::cout &lt;&lt; "200 million years ago encoded in years: " &lt;&lt; yr.count() &lt;&lt; '\n';
  2438. days d = std::datetime::duration_cast&lt;days&gt;(yr);
  2439. std::cout &lt;&lt; "200 million years ago encoded in days: " &lt;&lt; d.count() &lt;&lt; '\n';
  2440. millennium c = std::datetime::duration_cast&lt;millennium&gt;(yr);
  2441. std::cout &lt;&lt; "200 million years ago encoded in millennium: " &lt;&lt; c.count() &lt;&lt; '\n';
  2442. std::cout &lt;&lt; "Demonstrate \"uninitialized protection\" behavior:\n";
  2443. seconds sec;
  2444. for (++sec; sec &lt; seconds(sat(10)); ++sec)
  2445. ;
  2446. std::cout &lt;&lt; sec.count() &lt;&lt; '\n';
  2447. std::cout &lt;&lt; "\n";
  2448. }
  2449. void testStdUser()
  2450. {
  2451. std::cout &lt;&lt; "***************\n";
  2452. std::cout &lt;&lt; "* testStdUser *\n";
  2453. std::cout &lt;&lt; "***************\n";
  2454. using namespace std::datetime;
  2455. hours hr = hours(100);
  2456. std::cout &lt;&lt; "100 hours expressed as hours = " &lt;&lt; hr.count() &lt;&lt; '\n';
  2457. nanoseconds ns = hr;
  2458. std::cout &lt;&lt; "100 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
  2459. ns += hr;
  2460. std::cout &lt;&lt; "200 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
  2461. ns += hr;
  2462. std::cout &lt;&lt; "300 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
  2463. <font color="#c80000">// hr = ns; // does not compile</font>
  2464. std::cout &lt;&lt; "hr = ns; <font color="#c80000">// does not compile\n";</font>
  2465. <font color="#c80000">// hr * ns; // does not compile</font>
  2466. std::cout &lt;&lt; "hr * ns; <font color="#c80000">// does not compile\n";</font>
  2467. duration&lt;double&gt; fs(2.5);
  2468. std::cout &lt;&lt; "duration&lt;double&gt; has count() = " &lt;&lt; fs.count() &lt;&lt; '\n';
  2469. <font color="#c80000">// seconds sec = fs; // does not compile</font>
  2470. std::cout &lt;&lt; "seconds sec = duration&lt;double&gt; won't compile\n";
  2471. seconds sec = duration_cast&lt;seconds&gt;(fs);
  2472. std::cout &lt;&lt; "seconds has count() = " &lt;&lt; sec.count() &lt;&lt; '\n';
  2473. std::cout &lt;&lt; "\n";
  2474. }
  2475. <font color="#c80000">// timeval clock demo</font>
  2476. <font color="#c80000">// Demonstrate the use of a timeval-like struct to be used as the representation</font>
  2477. <font color="#c80000">// type for both duraiton and time_point.</font>
  2478. namespace timeval_demo
  2479. {
  2480. class xtime {
  2481. private:
  2482. long tv_sec;
  2483. long tv_usec;
  2484. void fixup() {
  2485. if (tv_usec &lt; 0) {
  2486. tv_usec += 1000000;
  2487. --tv_sec;
  2488. }
  2489. }
  2490. public:
  2491. explicit xtime(long sec, long usec) {
  2492. tv_sec = sec;
  2493. tv_usec = usec;
  2494. if (tv_usec &lt; 0 || tv_usec &gt;= 1000000) {
  2495. tv_sec += tv_usec / 1000000;
  2496. tv_usec %= 1000000;
  2497. fixup();
  2498. }
  2499. }
  2500. explicit xtime(long long usec)
  2501. {
  2502. tv_usec = static_cast&lt;long&gt;(usec % 1000000);
  2503. tv_sec = static_cast&lt;long&gt;(usec / 1000000);
  2504. fixup();
  2505. }
  2506. <font color="#c80000">// explicit</font>
  2507. operator long long() const {return static_cast&lt;long long&gt;(tv_sec) * 1000000 + tv_usec;}
  2508. xtime&amp; operator += (xtime rhs) {
  2509. tv_sec += rhs.tv_sec;
  2510. tv_usec += rhs.tv_usec;
  2511. if (tv_usec &gt;= 1000000) {
  2512. tv_usec -= 1000000;
  2513. ++tv_sec;
  2514. }
  2515. return *this;
  2516. }
  2517. xtime&amp; operator -= (xtime rhs) {
  2518. tv_sec -= rhs.tv_sec;
  2519. tv_usec -= rhs.tv_usec;
  2520. fixup();
  2521. return *this;
  2522. }
  2523. xtime&amp; operator %= (xtime rhs) {
  2524. long long t = tv_sec * 1000000 + tv_usec;
  2525. long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
  2526. t %= r;
  2527. tv_sec = t / 1000000;
  2528. tv_usec = t % 1000000;
  2529. fixup();
  2530. return *this;
  2531. }
  2532. friend xtime operator+(xtime x, xtime y) {return x += y;}
  2533. friend xtime operator-(xtime x, xtime y) {return x -= y;}
  2534. friend xtime operator%(xtime x, xtime y) {return x %= y;}
  2535. friend bool operator==(xtime x, xtime y)
  2536. { return (x.tv_sec == y.tv_sec &amp;&amp; x.tv_usec == y.tv_usec); }
  2537. friend bool operator&lt;(xtime x, xtime y) {
  2538. if (x.tv_sec == y.tv_sec)
  2539. return (x.tv_usec &lt; y.tv_usec);
  2540. return (x.tv_sec &lt; y.tv_sec);
  2541. }
  2542. friend bool operator!=(xtime x, xtime y) { return !(x == y); }
  2543. friend bool operator&gt; (xtime x, xtime y) { return y &lt; x; }
  2544. friend bool operator&lt;=(xtime x, xtime y) { return !(y &lt; x); }
  2545. friend bool operator&gt;=(xtime x, xtime y) { return !(x &lt; y); }
  2546. friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, xtime x)
  2547. {return os &lt;&lt; '{' &lt;&lt; x.tv_sec &lt;&lt; ',' &lt;&lt; x.tv_usec &lt;&lt; '}';}
  2548. };
  2549. class xtime_clock
  2550. {
  2551. public:
  2552. typedef xtime rep;
  2553. typedef std::micro period;
  2554. typedef std::datetime::duration&lt;rep, period&gt; duration;
  2555. typedef std::datetime::time_point&lt;xtime_clock&gt; time_point;
  2556. static time_point now();
  2557. };
  2558. xtime_clock::time_point
  2559. xtime_clock::now()
  2560. {
  2561. time_point t(duration(xtime(0)));
  2562. gettimeofday((timeval*)&amp;t, 0);
  2563. return t;
  2564. }
  2565. void test_xtime_clock()
  2566. {
  2567. using namespace std::datetime;
  2568. std::cout &lt;&lt; "timeval_demo system clock test\n";
  2569. std::cout &lt;&lt; "sizeof xtime_clock::time_point = " &lt;&lt; sizeof(xtime_clock::time_point) &lt;&lt; '\n';
  2570. std::cout &lt;&lt; "sizeof xtime_clock::duration = " &lt;&lt; sizeof(xtime_clock::duration) &lt;&lt; '\n';
  2571. std::cout &lt;&lt; "sizeof xtime_clock::rep = " &lt;&lt; sizeof(xtime_clock::rep) &lt;&lt; '\n';
  2572. xtime_clock::duration delay(milliseconds(5));
  2573. xtime_clock::time_point start = xtime_clock::now();
  2574. while (xtime_clock::now() - start &lt;= delay)
  2575. ;
  2576. xtime_clock::time_point stop = xtime_clock::now();
  2577. xtime_clock::duration elapsed = stop - start;
  2578. std::cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
  2579. }
  2580. } <font color="#c80000">// timeval_demo</font>
  2581. <font color="#c80000">// Handle duration with resolution not known until run time</font>
  2582. namespace runtime_resolution
  2583. {
  2584. class duration
  2585. {
  2586. public:
  2587. typedef long long rep;
  2588. private:
  2589. rep rep_;
  2590. static const double ticks_per_nanosecond;
  2591. public:
  2592. typedef std::datetime::duration&lt;double, std::nano&gt; tonanosec;
  2593. duration() {} <font color="#c80000">// = default;</font>
  2594. explicit duration(const rep&amp; r) : rep_(r) {}
  2595. <font color="#c80000">// conversions</font>
  2596. explicit duration(const tonanosec&amp; d)
  2597. : rep_(static_cast&lt;rep&gt;(d.count() * ticks_per_nanosecond)) {}
  2598. <font color="#c80000">// explicit</font>
  2599. operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
  2600. <font color="#c80000">// observer</font>
  2601. rep count() const {return rep_;}
  2602. <font color="#c80000">// arithmetic</font>
  2603. duration&amp; operator+=(const duration&amp; d) {rep_ += d.rep_; return *this;}
  2604. duration&amp; operator-=(const duration&amp; d) {rep_ += d.rep_; return *this;}
  2605. duration&amp; operator*=(rep rhs) {rep_ *= rhs; return *this;}
  2606. duration&amp; operator/=(rep rhs) {rep_ /= rhs; return *this;}
  2607. duration operator+() const {return *this;}
  2608. duration operator-() const {return duration(-rep_);}
  2609. duration&amp; operator++() {++rep_; return *this;}
  2610. duration operator++(int) {return duration(rep_++);}
  2611. duration&amp; operator--() {--rep_; return *this;}
  2612. duration operator--(int) {return duration(rep_--);}
  2613. friend duration operator+(duration x, duration y) {return x += y;}
  2614. friend duration operator-(duration x, duration y) {return x -= y;}
  2615. friend duration operator*(duration x, rep y) {return x *= y;}
  2616. friend duration operator*(rep x, duration y) {return y *= x;}
  2617. friend duration operator/(duration x, rep y) {return x /= y;}
  2618. friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
  2619. friend bool operator!=(duration x, duration y) {return !(x == y);}
  2620. friend bool operator&lt; (duration x, duration y) {return x.rep_ &lt; y.rep_;}
  2621. friend bool operator&lt;=(duration x, duration y) {return !(y &lt; x);}
  2622. friend bool operator&gt; (duration x, duration y) {return y &lt; x;}
  2623. friend bool operator&gt;=(duration x, duration y) {return !(x &lt; y);}
  2624. };
  2625. static
  2626. double
  2627. init_duration()
  2628. {
  2629. mach_timebase_info_data_t MachInfo;
  2630. mach_timebase_info(&amp;MachInfo);
  2631. return static_cast&lt;double&gt;(MachInfo.denom) / MachInfo.numer;
  2632. }
  2633. const double duration::ticks_per_nanosecond = init_duration();
  2634. class clock;
  2635. class time_point
  2636. {
  2637. public:
  2638. typedef runtime_resolution::clock clock;
  2639. typedef long long rep;
  2640. private:
  2641. rep rep_;
  2642. rep count() const {return rep_;}
  2643. public:
  2644. time_point() : rep_(0) {}
  2645. explicit time_point(const duration&amp; d)
  2646. : rep_(d.count()) {}
  2647. <font color="#c80000">// arithmetic</font>
  2648. time_point&amp; operator+=(const duration&amp; d) {rep_ += d.count(); return *this;}
  2649. time_point&amp; operator-=(const duration&amp; d) {rep_ -= d.count(); return *this;}
  2650. friend time_point operator+(time_point x, duration y) {return x += y;}
  2651. friend time_point operator+(duration x, time_point y) {return y += x;}
  2652. friend time_point operator-(time_point x, duration y) {return x -= y;}
  2653. friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
  2654. };
  2655. class clock
  2656. {
  2657. public:
  2658. typedef duration::rep rep;
  2659. typedef runtime_resolution::duration duration;
  2660. typedef runtime_resolution::time_point time_point;
  2661. static time_point now() {return time_point(duration(mach_absolute_time()));}
  2662. };
  2663. void test()
  2664. {
  2665. using namespace std::datetime;
  2666. std::cout &lt;&lt; "runtime_resolution test\n";
  2667. clock::duration delay(std::datetime::milliseconds(5));
  2668. clock::time_point start = clock::now();
  2669. while (clock::now() - start &lt;= delay)
  2670. ;
  2671. clock::time_point stop = clock::now();
  2672. clock::duration elapsed = stop - start;
  2673. std::cout &lt;&lt; "paused " &lt;&lt; nanoseconds(duration_cast&lt;nanoseconds&gt;(duration::tonanosec(elapsed))).count()
  2674. &lt;&lt; " nanoseconds\n";
  2675. }
  2676. } <font color="#c80000">// runtime_resolution</font>
  2677. <font color="#c80000">// miscellaneous tests and demos:</font>
  2678. #include &lt;cassert&gt;
  2679. #include &lt;iostream&gt;
  2680. using namespace std::datetime;
  2681. void physics_function(duration&lt;double&gt; d)
  2682. {
  2683. std::cout &lt;&lt; "d = " &lt;&lt; d.count() &lt;&lt; '\n';
  2684. }
  2685. void drive_physics_function()
  2686. {
  2687. physics_function(nanoseconds(3));
  2688. physics_function(hours(3));
  2689. physics_function(duration&lt;double&gt;(2./3));
  2690. std::cout.precision(16);
  2691. physics_function( hours(3) + nanoseconds(-3) );
  2692. }
  2693. void test_range()
  2694. {
  2695. using namespace std::datetime;
  2696. hours h1 = hours(24 * ( 365 * 292 + 292/4));
  2697. nanoseconds n1 = h1 + nanoseconds(1);
  2698. nanoseconds delta = n1 - h1;
  2699. std::cout &lt;&lt; "292 years of hours = " &lt;&lt; h1.count() &lt;&lt; "hr\n";
  2700. std::cout &lt;&lt; "Add a nanosecond = " &lt;&lt; n1.count() &lt;&lt; "ns\n";
  2701. std::cout &lt;&lt; "Find the difference = " &lt;&lt; delta.count() &lt;&lt; "ns\n";
  2702. }
  2703. void test_extended_range()
  2704. {
  2705. using namespace std::datetime;
  2706. hours h1 = hours(24 * ( 365 * 244000 + 244000/4));
  2707. <font color="#c80000">/*auto*/</font> microseconds u1 = h1 + microseconds(1);
  2708. <font color="#c80000">/*auto*/</font> microseconds delta = u1 - h1;
  2709. std::cout &lt;&lt; "244,000 years of hours = " &lt;&lt; h1.count() &lt;&lt; "hr\n";
  2710. std::cout &lt;&lt; "Add a microsecond = " &lt;&lt; u1.count() &lt;&lt; "us\n";
  2711. std::cout &lt;&lt; "Find the difference = " &lt;&lt; delta.count() &lt;&lt; "us\n";
  2712. }
  2713. template &lt;class Rep, class Period&gt;
  2714. void inspect_duration(std::datetime::duration&lt;Rep, Period&gt; d, const std::string&amp; name)
  2715. {
  2716. typedef std::datetime::duration&lt;Rep, Period&gt; Duration;
  2717. std::cout &lt;&lt; "********* " &lt;&lt; name &lt;&lt; " *********\n";
  2718. std::cout &lt;&lt; "The period of " &lt;&lt; name &lt;&lt; " is " &lt;&lt; (double)Period::num/Period::den &lt;&lt; " seconds.\n";
  2719. std::cout &lt;&lt; "The frequency of " &lt;&lt; name &lt;&lt; " is " &lt;&lt; (double)Period::den/Period::num &lt;&lt; " Hz.\n";
  2720. std::cout &lt;&lt; "The representation is ";
  2721. if (tmp::is_floating_point&lt;Rep&gt;::value)
  2722. {
  2723. std::cout &lt;&lt; "floating point\n";
  2724. std::cout &lt;&lt; "The precision is the most significant ";
  2725. std::cout &lt;&lt; std::numeric_limits&lt;Rep&gt;::digits10 &lt;&lt; " decimal digits.\n";
  2726. }
  2727. else if (tmp::is_integral&lt;Rep&gt;::value)
  2728. {
  2729. std::cout &lt;&lt; "integral\n";
  2730. d = Duration(Rep(1));
  2731. std::datetime::duration&lt;double&gt; dsec = d;
  2732. std::cout &lt;&lt; "The precision is " &lt;&lt; dsec.count() &lt;&lt; " seconds.\n";
  2733. }
  2734. else
  2735. {
  2736. std::cout &lt;&lt; "a class type\n";
  2737. d = Duration(Rep(1));
  2738. std::datetime::duration&lt;double&gt; dsec = d;
  2739. std::cout &lt;&lt; "The precision is " &lt;&lt; dsec.count() &lt;&lt; " seconds.\n";
  2740. }
  2741. d = Duration(std::numeric_limits&lt;Rep&gt;::max());
  2742. using namespace std::datetime;
  2743. using namespace std;
  2744. typedef duration&lt;double, ratio_multiply&lt;ratio&lt;24*3652425,10000&gt;, hours::period&gt;::type&gt; Years;
  2745. Years years = d;
  2746. std::cout &lt;&lt; "The range is +/- " &lt;&lt; years.count() &lt;&lt; " years.\n";
  2747. std::cout &lt;&lt; "sizeof(" &lt;&lt; name &lt;&lt; ") = " &lt;&lt; sizeof(d) &lt;&lt; '\n';
  2748. }
  2749. void inspect_all()
  2750. {
  2751. using namespace std::datetime;
  2752. std::cout.precision(6);
  2753. inspect_duration(nanoseconds(), "nanoseconds");
  2754. inspect_duration(microseconds(), "microseconds");
  2755. inspect_duration(milliseconds(), "milliseconds");
  2756. inspect_duration(seconds(), "seconds");
  2757. inspect_duration(minutes(), "minutes");
  2758. inspect_duration(hours(), "hours");
  2759. inspect_duration(duration&lt;double&gt;(), "duration&lt;double&gt;");
  2760. }
  2761. void test_milliseconds()
  2762. {
  2763. using namespace std::datetime;
  2764. milliseconds ms(250);
  2765. ms += milliseconds(1);
  2766. milliseconds ms2(150);
  2767. milliseconds msdiff = ms - ms2;
  2768. if (msdiff == milliseconds(101))
  2769. std::cout &lt;&lt; "success\n";
  2770. else
  2771. std::cout &lt;&lt; "failure: " &lt;&lt; msdiff.count() &lt;&lt; '\n';
  2772. }
  2773. using namespace std;
  2774. using namespace std::datetime;
  2775. <font color="#c80000">// Example round_up utility: converts d to To, rounding up for inexact conversions</font>
  2776. <font color="#c80000">// Being able to *easily* write this function is a major feature!</font>
  2777. template &lt;class To, class Rep, class Period&gt;
  2778. To
  2779. round_up(duration&lt;Rep, Period&gt; d)
  2780. {
  2781. To result = duration_cast&lt;To&gt;(d);
  2782. if (result &lt; d)
  2783. ++result;
  2784. return result;
  2785. }
  2786. <font color="#c80000">// demonstrate interaction with xtime-like facility:</font>
  2787. using namespace std::datetime;
  2788. struct xtime
  2789. {
  2790. long sec;
  2791. unsigned long usec;
  2792. };
  2793. template &lt;class Rep, class Period&gt;
  2794. xtime
  2795. to_xtime_truncate(duration&lt;Rep, Period&gt; d)
  2796. {
  2797. xtime xt;
  2798. xt.sec = duration_cast&lt;seconds&gt;(d).count();
  2799. xt.usec = duration_cast&lt;microseconds&gt;(d - seconds(xt.sec)).count();
  2800. return xt;
  2801. }
  2802. template &lt;class Rep, class Period&gt;
  2803. xtime
  2804. to_xtime_round_up(duration&lt;Rep, Period&gt; d)
  2805. {
  2806. xtime xt;
  2807. xt.sec = duration_cast&lt;seconds&gt;(d).count();
  2808. xt.usec = round_up&lt;microseconds&gt;(d - seconds(xt.sec)).count();
  2809. return xt;
  2810. }
  2811. microseconds
  2812. from_xtime(xtime xt)
  2813. {
  2814. return seconds(xt.sec) + microseconds(xt.usec);
  2815. }
  2816. void print(xtime xt)
  2817. {
  2818. cout &lt;&lt; '{' &lt;&lt; xt.sec &lt;&lt; ',' &lt;&lt; xt.usec &lt;&lt; "}\n";
  2819. }
  2820. void test_with_xtime()
  2821. {
  2822. cout &lt;&lt; "test_with_xtime\n";
  2823. xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251));
  2824. print(xt);
  2825. milliseconds ms = duration_cast&lt;milliseconds&gt;(from_xtime(xt));
  2826. cout &lt;&lt; ms.count() &lt;&lt; " milliseconds\n";
  2827. xt = to_xtime_round_up(ms);
  2828. print(xt);
  2829. xt = to_xtime_truncate(seconds(3) + nanoseconds(999));
  2830. print(xt);
  2831. xt = to_xtime_round_up(seconds(3) + nanoseconds(999));
  2832. print(xt);
  2833. }
  2834. void test_system_clock()
  2835. {
  2836. cout &lt;&lt; "system_clock test" &lt;&lt; endl;
  2837. system_clock::duration delay = milliseconds(5);
  2838. system_clock::time_point start = system_clock::now();
  2839. while (system_clock::now() - start &lt;= delay)
  2840. ;
  2841. system_clock::time_point stop = system_clock::now();
  2842. system_clock::duration elapsed = stop - start;
  2843. cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
  2844. start = system_clock::now();
  2845. stop = system_clock::now();
  2846. cout &lt;&lt; "system_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
  2847. }
  2848. void test_monotonic_clock()
  2849. {
  2850. cout &lt;&lt; "monotonic_clock test" &lt;&lt; endl;
  2851. monotonic_clock::duration delay = milliseconds(5);
  2852. monotonic_clock::time_point start = monotonic_clock::now();
  2853. while (monotonic_clock::now() - start &lt;= delay)
  2854. ;
  2855. monotonic_clock::time_point stop = monotonic_clock::now();
  2856. monotonic_clock::duration elapsed = stop - start;
  2857. cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
  2858. start = monotonic_clock::now();
  2859. stop = monotonic_clock::now();
  2860. cout &lt;&lt; "monotonic_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
  2861. }
  2862. void test_hi_resolution_clock()
  2863. {
  2864. cout &lt;&lt; "high_resolution_clock test" &lt;&lt; endl;
  2865. high_resolution_clock::duration delay = milliseconds(5);
  2866. high_resolution_clock::time_point start = high_resolution_clock::now();
  2867. while (high_resolution_clock::now() - start &lt;= delay)
  2868. ;
  2869. high_resolution_clock::time_point stop = high_resolution_clock::now();
  2870. high_resolution_clock::duration elapsed = stop - start;
  2871. cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
  2872. start = high_resolution_clock::now();
  2873. stop = high_resolution_clock::now();
  2874. cout &lt;&lt; "high_resolution_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
  2875. }
  2876. void test_mixed_clock()
  2877. {
  2878. cout &lt;&lt; "mixed clock test" &lt;&lt; endl;
  2879. high_resolution_clock::time_point hstart = high_resolution_clock::now();
  2880. cout &lt;&lt; "Add 5 milliseconds to a high_resolution_clock::time_point\n";
  2881. monotonic_clock::time_point mend = hstart + milliseconds(5);
  2882. bool b = hstart == mend;
  2883. system_clock::time_point sstart = system_clock::now();
  2884. std::cout &lt;&lt; "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
  2885. <font color="#c80000">// mend - sstart; // doesn't compile</font>
  2886. cout &lt;&lt; "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
  2887. " and add that to a system_clock::time_point\n";
  2888. system_clock::time_point send = sstart + duration_cast&lt;system_clock::duration&gt;(mend - hstart);
  2889. cout &lt;&lt; "subtract two system_clock::time_point's and output that in microseconds:\n";
  2890. microseconds ms = send - sstart;
  2891. cout &lt;&lt; ms.count() &lt;&lt; " microseconds\n";
  2892. }
  2893. void test_c_mapping()
  2894. {
  2895. cout &lt;&lt; "C map test\n";
  2896. using namespace std::datetime;
  2897. system_clock::time_point t1 = system_clock::now();
  2898. std::time_t c_time = system_clock::to_time_t(t1);
  2899. std::tm* tmptr = std::localtime(&amp;c_time);
  2900. std::cout &lt;&lt; "It is now " &lt;&lt; tmptr-&gt;tm_hour &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_min &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_sec &lt;&lt; ' '
  2901. &lt;&lt; tmptr-&gt;tm_year + 1900 &lt;&lt; '-' &lt;&lt; tmptr-&gt;tm_mon + 1 &lt;&lt; '-' &lt;&lt; tmptr-&gt;tm_mday &lt;&lt; '\n';
  2902. c_time = std::mktime(tmptr);
  2903. system_clock::time_point t2 = system_clock::from_time_t(c_time);
  2904. microseconds ms = t1 - t2;
  2905. std::cout &lt;&lt; "Round-tripping through the C interface truncated the precision by " &lt;&lt; ms.count() &lt;&lt; " microseconds\n";
  2906. }
  2907. void test_duration_division()
  2908. {
  2909. cout &lt;&lt; hours(3) / milliseconds(5) &lt;&lt; '\n';
  2910. cout &lt;&lt; milliseconds(5) / hours(3) &lt;&lt; '\n';
  2911. cout &lt;&lt; hours(1) / milliseconds(1) &lt;&lt; '\n';
  2912. }
  2913. namespace I_dont_like_the_default_duration_behavior
  2914. {
  2915. <font color="#c80000">// Here's how you override the duration's default constructor to do anything you want (in this case zero)</font>
  2916. template &lt;class R&gt;
  2917. class zero_default
  2918. {
  2919. public:
  2920. typedef R rep;
  2921. private:
  2922. rep rep_;
  2923. public:
  2924. zero_default(rep i = 0) : rep_(i) {}
  2925. operator rep() const {return rep_;}
  2926. zero_default&amp; operator+=(zero_default x) {rep_ += x.rep_; return *this;}
  2927. zero_default&amp; operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
  2928. zero_default&amp; operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
  2929. zero_default&amp; operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
  2930. zero_default operator+ () const {return *this;}
  2931. zero_default operator- () const {return zero_default(-rep_);}
  2932. zero_default&amp; operator++() {++rep_; return *this;}
  2933. zero_default operator++(int) {return zero_default(rep_++);}
  2934. zero_default&amp; operator--() {--rep_; return *this;}
  2935. zero_default operator--(int) {return zero_default(rep_--);}
  2936. friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
  2937. friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
  2938. friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
  2939. friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
  2940. friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
  2941. friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
  2942. friend bool operator&lt; (zero_default x, zero_default y) {return x.rep_ &lt; y.rep_;}
  2943. friend bool operator&lt;=(zero_default x, zero_default y) {return !(y &lt; x);}
  2944. friend bool operator&gt; (zero_default x, zero_default y) {return y &lt; x;}
  2945. friend bool operator&gt;=(zero_default x, zero_default y) {return !(x &lt; y);}
  2946. };
  2947. typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::nano &gt; nanoseconds;
  2948. typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::micro &gt; microseconds;
  2949. typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::milli &gt; milliseconds;
  2950. typedef std::datetime::duration&lt;zero_default&lt;long long&gt; &gt; seconds;
  2951. typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::ratio&lt;60&gt; &gt; minutes;
  2952. typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::ratio&lt;3600&gt; &gt; hours;
  2953. void test()
  2954. {
  2955. milliseconds ms;
  2956. cout &lt;&lt; ms.count() &lt;&lt; '\n';
  2957. }
  2958. } <font color="#c80000">// I_dont_like_the_default_duration_behavior</font>
  2959. <font color="#c80000">// Build a min for two time_points</font>
  2960. template &lt;class Rep, class Period&gt;
  2961. void
  2962. print_duration(ostream&amp; os, duration&lt;Rep, Period&gt; d)
  2963. {
  2964. os &lt;&lt; d.count() &lt;&lt; " * " &lt;&lt; Period::num &lt;&lt; '/' &lt;&lt; Period::den &lt;&lt; " seconds\n";
  2965. }
  2966. <font color="#c80000">// Example min utility: returns the earliest time_point</font>
  2967. <font color="#c80000">// Being able to *easily* write this function is a major feature!</font>
  2968. template &lt;class Clock, class Duration1, class Duration2&gt;
  2969. inline
  2970. typename common_type&lt;time_point&lt;Clock, Duration1&gt;, time_point&lt;Clock, Duration2&gt; &gt;::type
  2971. min(time_point&lt;Clock, Duration1&gt; t1, time_point&lt;Clock, Duration2&gt; t2)
  2972. {
  2973. return t2 &lt; t1 ? t2 : t1;
  2974. }
  2975. void test_min()
  2976. {
  2977. typedef time_point&lt;system_clock, common_type&lt;system_clock::duration, seconds&gt;::type&gt; T1;
  2978. typedef time_point&lt;system_clock, common_type&lt;system_clock::duration, nanoseconds&gt;::type&gt; T2;
  2979. typedef common_type&lt;T1, T2&gt;::type T3;
  2980. <font color="#c80000">/*auto*/</font> T1 t1 = system_clock::now() + seconds(3);
  2981. <font color="#c80000">/*auto*/</font> T2 t2 = system_clock::now() + nanoseconds(3);
  2982. <font color="#c80000">/*auto*/</font> T3 t3 = min(t1, t2);
  2983. print_duration(cout, t1 - t3);
  2984. print_duration(cout, t2 - t3);
  2985. }
  2986. void explore_limits()
  2987. {
  2988. typedef duration&lt;long long, ratio_multiply&lt;ratio&lt;24*3652425,10000&gt;, hours::period&gt;::type&gt; Years;
  2989. monotonic_clock::time_point t1( Years(250));
  2990. monotonic_clock::time_point t2(-Years(250));
  2991. <font color="#c80000">// nanosecond resolution is likely to overflow. "up cast" to microseconds.</font>
  2992. <font color="#c80000">// The "up cast" trades precision for range.</font>
  2993. microseconds d = time_point_cast&lt;microseconds&gt;(t1) - time_point_cast&lt;microseconds&gt;(t2);
  2994. cout &lt;&lt; d.count() &lt;&lt; " microseconds\n";
  2995. }
  2996. void manipulate_clock_object(system_clock clock)
  2997. {
  2998. system_clock::duration delay = milliseconds(5);
  2999. system_clock::time_point start = clock.now();
  3000. while (clock.now() - start &lt;= delay)
  3001. ;
  3002. system_clock::time_point stop = clock.now();
  3003. system_clock::duration elapsed = stop - start;
  3004. cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
  3005. };
  3006. template &lt;long long speed&gt;
  3007. struct cycle_count
  3008. {
  3009. typedef typename ratio_multiply&lt;ratio&lt;speed&gt;, mega&gt;::type frequency; <font color="#c80000">// Mhz</font>
  3010. typedef typename ratio_divide&lt;ratio&lt;1&gt;, frequency&gt;::type period;
  3011. typedef long long rep;
  3012. typedef std::datetime::duration&lt;rep, period&gt; duration;
  3013. typedef std::datetime::time_point&lt;cycle_count&gt; time_point;
  3014. static time_point now()
  3015. {
  3016. static long long tick = 0;
  3017. <font color="#c80000">// return exact cycle count</font>
  3018. return time_point(duration(++tick)); <font color="#c80000">// fake access to clock cycle count</font>
  3019. }
  3020. };
  3021. template &lt;long long speed&gt;
  3022. struct approx_cycle_count
  3023. {
  3024. static const long long frequency = speed * 1000000; <font color="#c80000">// MHz</font>
  3025. typedef nanoseconds duration;
  3026. typedef duration::rep rep;
  3027. typedef duration::period period;
  3028. static const long long nanosec_per_sec = period::den;
  3029. typedef std::datetime::time_point&lt;approx_cycle_count&gt; time_point;
  3030. static time_point now()
  3031. {
  3032. static long long tick = 0;
  3033. <font color="#c80000">// return cycle count as an approximate number of nanoseconds</font>
  3034. <font color="#c80000">// compute as if nanoseconds is only duration in the std::lib</font>
  3035. return time_point(duration(++tick * nanosec_per_sec / frequency));
  3036. }
  3037. };
  3038. void cycle_count_delay()
  3039. {
  3040. {
  3041. typedef cycle_count&lt;400&gt; clock;
  3042. cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency::num / mega::num &lt;&lt; "MHz clock which has a tick period of "
  3043. &lt;&lt; duration&lt;double, nano&gt;(clock::duration(1)).count() &lt;&lt; " nanoseconds\n";
  3044. nanoseconds delayns(500);
  3045. clock::duration delay = duration_cast&lt;clock::duration&gt;(delayns);
  3046. cout &lt;&lt; "delay = " &lt;&lt; delayns.count() &lt;&lt; " nanoseconds which is " &lt;&lt; delay.count() &lt;&lt; " cycles\n";
  3047. clock::time_point start = clock::now();
  3048. clock::time_point stop = start + delay;
  3049. while (clock::now() &lt; stop) <font color="#c80000">// no multiplies or divides in this loop</font>
  3050. ;
  3051. clock::time_point end = clock::now();
  3052. clock::duration elapsed = end - start;
  3053. cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " cycles ";
  3054. cout &lt;&lt; "which is " &lt;&lt; duration_cast&lt;nanoseconds&gt;(elapsed).count() &lt;&lt; " nanoseconds\n";
  3055. }
  3056. {
  3057. typedef approx_cycle_count&lt;400&gt; clock;
  3058. cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency / 1000000 &lt;&lt; "MHz clock modeled with nanoseconds\n";
  3059. clock::duration delay = nanoseconds(500);
  3060. cout &lt;&lt; "delay = " &lt;&lt; delay.count() &lt;&lt; " nanoseconds\n";
  3061. clock::time_point start = clock::now();
  3062. clock::time_point stop = start + delay;
  3063. while (clock::now() &lt; stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
  3064. ;
  3065. clock::time_point end = clock::now();
  3066. clock::duration elapsed = end - start;
  3067. cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " nanoseconds\n";
  3068. }
  3069. {
  3070. typedef cycle_count&lt;1500&gt; clock;
  3071. cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency::num / mega::num &lt;&lt; "MHz clock which has a tick period of "
  3072. &lt;&lt; duration&lt;double, nano&gt;(clock::duration(1)).count() &lt;&lt; " nanoseconds\n";
  3073. nanoseconds delayns(500);
  3074. clock::duration delay = duration_cast&lt;clock::duration&gt;(delayns);
  3075. cout &lt;&lt; "delay = " &lt;&lt; delayns.count() &lt;&lt; " nanoseconds which is " &lt;&lt; delay.count() &lt;&lt; " cycles\n";
  3076. clock::time_point start = clock::now();
  3077. clock::time_point stop = start + delay;
  3078. while (clock::now() &lt; stop) <font color="#c80000">// no multiplies or divides in this loop</font>
  3079. ;
  3080. clock::time_point end = clock::now();
  3081. clock::duration elapsed = end - start;
  3082. cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " cycles ";
  3083. cout &lt;&lt; "which is " &lt;&lt; duration_cast&lt;nanoseconds&gt;(elapsed).count() &lt;&lt; " nanoseconds\n";
  3084. }
  3085. {
  3086. typedef approx_cycle_count&lt;1500&gt; clock;
  3087. cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency / 1000000 &lt;&lt; "MHz clock modeled with nanoseconds\n";
  3088. clock::duration delay = nanoseconds(500);
  3089. cout &lt;&lt; "delay = " &lt;&lt; delay.count() &lt;&lt; " nanoseconds\n";
  3090. clock::time_point start = clock::now();
  3091. clock::time_point stop = start + delay;
  3092. while (clock::now() &lt; stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
  3093. ;
  3094. clock::time_point end = clock::now();
  3095. clock::duration elapsed = end - start;
  3096. cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " nanoseconds\n";
  3097. }
  3098. }
  3099. void test_special_values()
  3100. {
  3101. std::cout &lt;&lt; "duration&lt;unsigned&gt;::min().count() = " &lt;&lt; duration&lt;unsigned&gt;::min().count() &lt;&lt; '\n';
  3102. std::cout &lt;&lt; "duration&lt;unsigned&gt;::zero().count() = " &lt;&lt; duration&lt;unsigned&gt;::zero().count() &lt;&lt; '\n';
  3103. std::cout &lt;&lt; "duration&lt;unsigned&gt;::max().count() = " &lt;&lt; duration&lt;unsigned&gt;::max().count() &lt;&lt; '\n';
  3104. std::cout &lt;&lt; "duration&lt;int&gt;::min().count() = " &lt;&lt; duration&lt;int&gt;::min().count() &lt;&lt; '\n';
  3105. std::cout &lt;&lt; "duration&lt;int&gt;::zero().count() = " &lt;&lt; duration&lt;int&gt;::zero().count() &lt;&lt; '\n';
  3106. std::cout &lt;&lt; "duration&lt;int&gt;::max().count() = " &lt;&lt; duration&lt;int&gt;::max().count() &lt;&lt; '\n';
  3107. }
  3108. int main()
  3109. {
  3110. basic_examples();
  3111. testStdUser();
  3112. testUser1();
  3113. testUser2();
  3114. drive_physics_function();
  3115. test_range();
  3116. test_extended_range();
  3117. inspect_all();
  3118. test_milliseconds();
  3119. test_with_xtime();
  3120. test_system_clock();
  3121. test_monotonic_clock();
  3122. test_hi_resolution_clock();
  3123. test_mixed_clock();
  3124. timeval_demo::test_xtime_clock();
  3125. runtime_resolution::test();
  3126. test_c_mapping();
  3127. test_duration_division();
  3128. I_dont_like_the_default_duration_behavior::test();
  3129. test_min();
  3130. #if VARIADIC_COMMON_TYPE
  3131. inspect_duration(common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type(),
  3132. "common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type");
  3133. #endif
  3134. explore_limits();
  3135. manipulate_clock_object(system_clock());
  3136. duration&lt;double, milli&gt; d = milliseconds(3) * 2.5;
  3137. inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
  3138. cout &lt;&lt; d.count() &lt;&lt; '\n';
  3139. <font color="#c80000">// milliseconds ms(3.5); // doesn't compile</font>
  3140. cout &lt;&lt; "milliseconds ms(3.5) doesn't compile\n";
  3141. cycle_count_delay();
  3142. test_special_values();
  3143. }
  3144. <font color="#c80000">/*
  3145. Output
  3146. Running basic examples
  3147. sleep_for 3000000 microseconds
  3148. sleep_for 1 microseconds
  3149. sleep_until 10:47:17.728293 which is 4499340 microseconds away
  3150. try_lock_for 30000 microseconds
  3151. try_lock_until 10:47:17.728285 which is 4499303 microseconds away
  3152. wait_for 60000000 microseconds
  3153. wait_until 10:47:17.728285 which is 4499264 microseconds away
  3154. sleep_for 250000 microseconds
  3155. sleep_until 10:47:14.729077 which is 1499979 microseconds away
  3156. ***************
  3157. * testStdUser *
  3158. ***************
  3159. 100 hours expressed as hours = 100
  3160. 100 hours expressed as nanoseconds = 360000000000000
  3161. 200 hours expressed as nanoseconds = 720000000000000
  3162. 300 hours expressed as nanoseconds = 1080000000000000
  3163. hr = ns; <font color="#c80000">// does not compile</font>
  3164. hr * ns; <font color="#c80000">// does not compile</font>
  3165. duration&lt;double&gt; has count() = 2.5
  3166. seconds sec = duration&lt;double&gt; won't compile
  3167. seconds has count() = 2
  3168. *************
  3169. * testUser1 *
  3170. *************
  3171. Speed = 24.5872 meters/sec
  3172. Acceleration = 9.81456 meters/sec^2
  3173. Distance = 13.5204 meters
  3174. There are 125/201168 miles/meter which is approximately 0.000621371
  3175. There are 201168/125 meters/mile which is approximately 1609.34
  3176. 1 attosecond is 1e-18 seconds
  3177. sec = as; <font color="#c80000">// compiles</font>
  3178. 1 second is 1e+18 attoseconds
  3179. as = sec; <font color="#c80000">// compiles</font>
  3180. *************
  3181. * testUser2 *
  3182. *************
  3183. 100 years expressed as years = 100
  3184. 100 years expressed as nanoseconds = 3155695200000000000
  3185. 200 years expressed as nanoseconds = 6311390400000000000
  3186. 300 years expressed as nanoseconds = inf
  3187. yr = ns; <font color="#c80000">// does not compile</font>
  3188. ps = yr; <font color="#c80000">// does not compile</font>
  3189. 100 years expressed as picoseconds = inf
  3190. 0.1 years expressed as picoseconds = 3155695200000000000
  3191. 200 million years ago encoded in years: -200000000
  3192. 200 million years ago encoded in days: -73048500000
  3193. 200 million years ago encoded in millennium: -200000
  3194. Demonstrate "uninitialized protection" behavior:
  3195. nan
  3196. d = 3e-09
  3197. d = 10800
  3198. d = 0.666667
  3199. d = 10799.999999997
  3200. 292 years of hours = 2559672hr
  3201. Add a nanosecond = 9214819200000000001ns
  3202. Find the difference = 1ns
  3203. 244,000 years of hours = 2138904000hr
  3204. Add a microsecond = 7700054400000000001us
  3205. Find the difference = 1us
  3206. ********* nanoseconds *********
  3207. The period of nanoseconds is 1e-09 seconds.
  3208. The frequency of nanoseconds is 1e+09 Hz.
  3209. The representation is integral
  3210. The precision is 1e-09 seconds.
  3211. The range is +/- 292.277 years.
  3212. sizeof(nanoseconds) = 8
  3213. ********* microseconds *********
  3214. The period of microseconds is 1e-06 seconds.
  3215. The frequency of microseconds is 1e+06 Hz.
  3216. The representation is integral
  3217. The precision is 1e-06 seconds.
  3218. The range is +/- 292277 years.
  3219. sizeof(microseconds) = 8
  3220. ********* milliseconds *********
  3221. The period of milliseconds is 0.001 seconds.
  3222. The frequency of milliseconds is 1000 Hz.
  3223. The representation is integral
  3224. The precision is 0.001 seconds.
  3225. The range is +/- 2.92277e+08 years.
  3226. sizeof(milliseconds) = 8
  3227. ********* seconds *********
  3228. The period of seconds is 1 seconds.
  3229. The frequency of seconds is 1 Hz.
  3230. The representation is integral
  3231. The precision is 1 seconds.
  3232. The range is +/- 2.92277e+11 years.
  3233. sizeof(seconds) = 8
  3234. ********* minutes *********
  3235. The period of minutes is 60 seconds.
  3236. The frequency of minutes is 0.0166667 Hz.
  3237. The representation is integral
  3238. The precision is 60 seconds.
  3239. The range is +/- 4083.06 years.
  3240. sizeof(minutes) = 4
  3241. ********* hours *********
  3242. The period of hours is 3600 seconds.
  3243. The frequency of hours is 0.000277778 Hz.
  3244. The representation is integral
  3245. The precision is 3600 seconds.
  3246. The range is +/- 244984 years.
  3247. sizeof(hours) = 4
  3248. ********* duration&lt;double&gt; *********
  3249. The period of duration&lt;double&gt; is 1 seconds.
  3250. The frequency of duration&lt;double&gt; is 1 Hz.
  3251. The representation is floating point
  3252. The precision is the most significant 15 decimal digits.
  3253. The range is +/- 5.69666e+300 years.
  3254. sizeof(duration&lt;double&gt;) = 8
  3255. success
  3256. test_with_xtime
  3257. {3,251000}
  3258. 3251 milliseconds
  3259. {3,251000}
  3260. {3,0}
  3261. {3,1}
  3262. system_clock test
  3263. paused 5001000 nanoseconds
  3264. system_clock resolution estimate: 0 nanoseconds
  3265. monotonic_clock test
  3266. paused 5000181 nanoseconds
  3267. monotonic_clock resolution estimate: 97 nanoseconds
  3268. high_resolution_clock test
  3269. paused 5000277 nanoseconds
  3270. high_resolution_clock resolution estimate: 96 nanoseconds
  3271. mixed clock test
  3272. Add 5 milliseconds to a high_resolution_clock::time_point
  3273. Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile
  3274. subtract high_resolution_clock::time_point from monotonic_clock::time_point and add that to a system_clock::time_point
  3275. subtract two system_clock::time_point's and output that in microseconds:
  3276. 5000 microseconds
  3277. timeval_demo system clock test
  3278. sizeof xtime_clock::time_point = 8
  3279. sizeof xtime_clock::duration = 8
  3280. sizeof xtime_clock::rep = 8
  3281. paused 5001000 nanoseconds
  3282. runtime_resolution test
  3283. paused 5000205 nanoseconds
  3284. C map test
  3285. It is now 10:47:13 2008-4-22
  3286. Round-tripping through the C interface truncated the precision by 255445 microseconds
  3287. 2160000
  3288. 0
  3289. 3600000
  3290. 0
  3291. 2999998997 * 1/1000000000 seconds
  3292. 0 * 1/1000000000 seconds
  3293. 15778476000000000 microseconds
  3294. paused 5001000 nanoseconds
  3295. ********* milliseconds(3) * 2.5 *********
  3296. The period of milliseconds(3) * 2.5 is 0.001 seconds.
  3297. The frequency of milliseconds(3) * 2.5 is 1000 Hz.
  3298. The representation is floating point
  3299. The precision is the most significant 15 decimal digits.
  3300. The range is +/- 5.69666e+297 years.
  3301. sizeof(milliseconds(3) * 2.5) = 8
  3302. 7.5
  3303. milliseconds ms(3.5) doesn't compile
  3304. Simulated 400MHz clock which has a tick period of 2.5 nanoseconds
  3305. delay = 500 nanoseconds which is 200 cycles
  3306. paused 201 cycles which is 502 nanoseconds
  3307. Simulated 400MHz clock modeled with nanoseconds
  3308. delay = 500 nanoseconds
  3309. paused 503 nanoseconds
  3310. Simulated 1500MHz clock which has a tick period of 0.666667 nanoseconds
  3311. delay = 500 nanoseconds which is 750 cycles
  3312. paused 751 cycles which is 500 nanoseconds
  3313. Simulated 1500MHz clock modeled with nanoseconds
  3314. delay = 500 nanoseconds
  3315. paused 500 nanoseconds
  3316. duration&lt;unsigned&gt;::min().count() = 0
  3317. duration&lt;unsigned&gt;::zero().count() = 0
  3318. duration&lt;unsigned&gt;::max().count() = 4294967295
  3319. duration&lt;int&gt;::min().count() = -2147483647
  3320. duration&lt;int&gt;::zero().count() = 0
  3321. duration&lt;int&gt;::max().count() = 2147483647
  3322. */</font>
  3323. <font color="#c80000">/*
  3324. Example disassemblies (to show efficiency).
  3325. Disclaimer: I don't pretend to understand the optimizations made.
  3326. Compiled with
  3327. g++ -O3 -arch x86_64 -S test2.cpp
  3328. x86 64-bit architecture
  3329. ********************
  3330. system_clock::duration
  3331. time_subtraction(system_clock::time_point x, system_clock::time_point y)
  3332. {
  3333. return x - y;
  3334. }
  3335. pushq %rbp
  3336. LCFI25:
  3337. subq %rsi, %rdi
  3338. movq %rdi, %rax
  3339. movq %rsp, %rbp
  3340. LCFI26:
  3341. leave
  3342. ret
  3343. ********************
  3344. seconds
  3345. time_subtract_to_seconds(system_clock::time_point x, system_clock::time_point y)
  3346. {
  3347. return duration_cast&lt;seconds&gt;(x - y);
  3348. }
  3349. subq %rsi, %rdi
  3350. movabsq $4835703278458516699, %rdx
  3351. pushq %rbp
  3352. LCFI25:
  3353. movq %rdi, %rax
  3354. sarq $63, %rdi
  3355. imulq %rdx
  3356. movq %rsp, %rbp
  3357. LCFI26:
  3358. leave
  3359. sarq $18, %rdx
  3360. subq %rdi, %rdx
  3361. movq %rdx, %rax
  3362. ret
  3363. ********************
  3364. nanoseconds
  3365. time_subtract_to_nanoseconds(system_clock::time_point x, system_clock::time_point y)
  3366. {
  3367. return x - y;
  3368. }
  3369. pushq %rbp
  3370. LCFI25:
  3371. subq %rsi, %rdi
  3372. imulq $1000, %rdi, %rax
  3373. movq %rsp, %rbp
  3374. LCFI26:
  3375. leave
  3376. ret
  3377. ********************
  3378. system_clock::time_point
  3379. time_plus_duration(system_clock::time_point x, system_clock::duration y)
  3380. {
  3381. return x + y;
  3382. }
  3383. pushq %rbp
  3384. LCFI37:
  3385. movq %rsp, %rbp
  3386. LCFI38:
  3387. leaq (%rsi,%rdi), %rax
  3388. leave
  3389. ret
  3390. ********************
  3391. milliseconds
  3392. duration_plus_duration(milliseconds x, milliseconds y)
  3393. {
  3394. return x + y;
  3395. }
  3396. pushq %rbp
  3397. LCFI11:
  3398. leaq (%rdi,%rsi), %rax
  3399. movq %rsp, %rbp
  3400. LCFI12:
  3401. leave
  3402. ret
  3403. ********************
  3404. nanoseconds
  3405. milliseconds_plus_nanoseconds(milliseconds x, nanoseconds y)
  3406. {
  3407. return x + y;
  3408. }
  3409. imulq $1000000, %rdi, %rdi
  3410. pushq %rbp
  3411. LCFI20:
  3412. movq %rsp, %rbp
  3413. LCFI21:
  3414. leave
  3415. leaq (%rdi,%rsi), %rax
  3416. ret
  3417. ********************
  3418. milliseconds
  3419. nanoseconds_to_milliseconds(nanoseconds x)
  3420. {
  3421. return duration_cast&lt;milliseconds&gt;(x);
  3422. }
  3423. movq %rdi, %rax
  3424. movabsq $4835703278458516699, %rdx
  3425. pushq %rbp
  3426. LCFI13:
  3427. imulq %rdx
  3428. sarq $63, %rdi
  3429. movq %rsp, %rbp
  3430. LCFI14:
  3431. leave
  3432. sarq $18, %rdx
  3433. subq %rdi, %rdx
  3434. movq %rdx, %rax
  3435. ret
  3436. ********************
  3437. nanoseconds
  3438. milliseconds_to_nanoseconds(milliseconds x)
  3439. {
  3440. return x;
  3441. }
  3442. pushq %rbp
  3443. LCFI13:
  3444. imulq $1000000, %rdi, %rax
  3445. movq %rsp, %rbp
  3446. LCFI14:
  3447. leave
  3448. ret
  3449. ********************
  3450. hours
  3451. increment_hours(hours x)
  3452. {
  3453. return ++x;
  3454. }
  3455. pushq %rbp
  3456. LCFI11:
  3457. leaq 1(%rdi), %rax
  3458. movq %rsp, %rbp
  3459. LCFI12:
  3460. leave
  3461. ret
  3462. */</font>
  3463. </pre>
  3464. </body></html>